diff --git a/config.yml.example b/config.yml.example index e7b0068..80c0f4d 100644 --- a/config.yml.example +++ b/config.yml.example @@ -1,8 +1,16 @@ -LFS_BUCKET: *********** -CDN_DOMAIN: *********** -OBS_REGION: *********** -OBS_ACCESS_KEY_ID: *********** -OBS_SECRET_ACCESS_KEY: *********** -CLIENT_ID: *********** -CLIENT_SECRET: *********** -PATH_PREFIX: *********** \ No newline at end of file +{ + "LFS_BUCKET": *********** + "CDN_DOMAIN": *********** + "OBS_REGION": *********** + "OBS_ACCESS_KEY_ID": *********** + "OBS_SECRET_ACCESS_KEY": *********** + "CLIENT_ID": *********** + "CLIENT_SECRET": *********** + "PATH_PREFIX": *********** + "VALIDATE_REGEXP": { + "OWNER_REGEXP": "^[a-zA-Z]([-_.]?[a-zA-Z0-9]+)*$", + "REPONAME_REGEXP": "^[a-zA-Z0-9_.-]{1,189}[a-zA-Z0-9]$", + "USERNAME_REGEXP": "^[a-zA-Z]([-_.]?[a-zA-Z0-9]+)*$", + "PASSWORD_REGEXP": "^[a-zA-Z0-9!@_#$%^&*()\\-=+,?.,]*$" + } +} diff --git a/config/config.go b/config/config.go index 64ad6e6..63952db 100644 --- a/config/config.go +++ b/config/config.go @@ -7,14 +7,22 @@ import ( ) type Config struct { - Prefix string `json:"PATH_PREFIX"` - LfsBucket string `json:"LFS_BUCKET"` - ClientId string `json:"CLIENT_ID"` - ClientSecret string `json:"CLIENT_SECRET"` - CdnDomain string `json:"CDN_DOMAIN"` - ObsRegion string `json:"OBS_REGION"` - ObsAccessKeyId string `json:"OBS_ACCESS_KEY_ID"` - ObsSecretAccessKey string `json:"OBS_SECRET_ACCESS_KEY"` + Prefix string `json:"PATH_PREFIX"` + LfsBucket string `json:"LFS_BUCKET"` + ClientId string `json:"CLIENT_ID"` + ClientSecret string `json:"CLIENT_SECRET"` + CdnDomain string `json:"CDN_DOMAIN"` + ObsRegion string `json:"OBS_REGION"` + ObsAccessKeyId string `json:"OBS_ACCESS_KEY_ID"` + ObsSecretAccessKey string `json:"OBS_SECRET_ACCESS_KEY"` + ValidateConfig ValidateConfig `json:"VALIDATE_REGEXP"` +} + +type ValidateConfig struct { + OwnerRegexp string `json:"OWNER_REGEXP" required:"true"` + RepoNameRegexp string `json:"REPONAME_REGEXP" required:"true"` + UsernameRegexp string `json:"USERNAME_REGEXP" required:"true"` + PasswordRegexp string `json:"PASSWORD_REGEXP" required:"true"` } // LoadConfig loads the configuration file from the specified path and deletes the file if needed diff --git a/main.go b/main.go index 95eeb3f..b8570a4 100644 --- a/main.go +++ b/main.go @@ -88,6 +88,12 @@ func main() { return } + if err := server.Init(cfg.ValidateConfig); err != nil { + logrus.Errorf("load ValidateConfig, err:%s", err.Error()) + + return + } + if err := auth.Init(cfg); err != nil { logrus.Errorf("load gitee config, err:%s", err.Error()) diff --git a/server/server.go b/server/server.go index aa78bd5..4ce3b67 100644 --- a/server/server.go +++ b/server/server.go @@ -132,6 +132,15 @@ func (s *server) handleBatch(w http.ResponseWriter, r *http.Request) { userInRepo.Operation = req.Operation userInRepo.Owner = chi.URLParam(r, "owner") userInRepo.Repo = chi.URLParam(r, "repo") + + if !validatecfg.ownerRegexp.MatchString(userInRepo.Owner) || !validatecfg.reponameRegexp.MatchString(userInRepo.Repo) { + w.WriteHeader(http.StatusBadRequest) + must(json.NewEncoder(w).Encode(batch.ErrorResponse{ + Message: "invalid owner or reponame format", + })) + return + } + if err = auth.CheckRepoOwner(userInRepo); req.Operation == "upload" || err != nil { err := s.dealWithAuthError(userInRepo, w, r) if err != nil { @@ -190,6 +199,15 @@ func (s *server) dealWithAuthError(userInRepo auth.UserInRepo, w http.ResponseWr })) return err } + + if !validatecfg.usernameRegexp.MatchString(userInRepo.Username) || + !validatecfg.passwordRegexp.MatchString(userInRepo.Password) { + w.WriteHeader(http.StatusBadRequest) + must(json.NewEncoder(w).Encode(batch.ErrorResponse{ + Message: "invalid username or password format", + })) + return errors.New("invalid username or password format") + } return nil } diff --git a/server/validate.go b/server/validate.go new file mode 100644 index 0000000..f7e40fb --- /dev/null +++ b/server/validate.go @@ -0,0 +1,41 @@ +package server + +import ( + "fmt" + "github.com/metalogical/BigFiles/config" + "regexp" +) + +type validateConfig struct { + ownerRegexp *regexp.Regexp + reponameRegexp *regexp.Regexp + usernameRegexp *regexp.Regexp + passwordRegexp *regexp.Regexp +} + +var validatecfg validateConfig + +func Init(cfg config.ValidateConfig) error { + var err error + validatecfg.ownerRegexp, err = regexp.Compile(cfg.OwnerRegexp) + if err != nil { + return fmt.Errorf("failed to compile owner regexp: %w", err) + } + + validatecfg.reponameRegexp, err = regexp.Compile(cfg.RepoNameRegexp) + if err != nil { + return fmt.Errorf("failed to compile repo name regexp: %w", err) + } + + validatecfg.usernameRegexp, err = regexp.Compile(cfg.UsernameRegexp) + if err != nil { + return fmt.Errorf("failed to compile username regexp: %w", err) + } + + validatecfg.passwordRegexp, err = regexp.Compile(cfg.PasswordRegexp) + if err != nil { + return fmt.Errorf("failed to compile password regexp: %w", err) + } + + return nil +}