Преглед на файлове

add env for admin user restriction

Alexander Belanger преди 4 години
родител
ревизия
730f8f4973

+ 5 - 0
api/server/handlers/user/cli_login.go

@@ -41,6 +41,11 @@ func (c *CLILoginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	user, _ := r.Context().Value(types.UserScope).(*models.User)
 
+	if err := checkUserRestrictions(c.Config().ServerConf, user.Email); err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
+		return
+	}
+
 	// generate the token
 	jwt, err := token.GetTokenForUser(user.ID)
 

+ 5 - 0
api/server/handlers/user/create.go

@@ -53,6 +53,11 @@ func (u *UserCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
+	if err := checkUserRestrictions(u.Config().ServerConf, request.Email); err != nil {
+		u.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
+		return
+	}
+
 	// hash the password using bcrypt
 	hashedPw, err := bcrypt.GenerateFromPassword([]byte(user.Password), 8)
 

+ 4 - 0
api/server/handlers/user/github_callback.go

@@ -131,6 +131,10 @@ func upsertUserFromToken(config *config.Config, tok *oauth2.Token) (*models.User
 			return nil, fmt.Errorf("github user must have an email")
 		}
 
+		if err := checkUserRestrictions(config.ServerConf, primary); err != nil {
+			return nil, err
+		}
+
 		// check if a user with that email address already exists
 		_, err = config.Repo.User().ReadUserByEmail(primary)
 

+ 4 - 0
api/server/handlers/user/google_callback.go

@@ -105,6 +105,10 @@ func upsertGoogleUserFromToken(config *config.Config, tok *oauth2.Token) (*model
 		return nil, err
 	}
 
+	if err := checkUserRestrictions(config.ServerConf, gInfo.Email); err != nil {
+		return nil, err
+	}
+
 	// if the app has a restricted domain, check the `hd` query param
 	if config.ServerConf.GoogleRestrictedDomain != "" {
 		if gInfo.HD != config.ServerConf.GoogleRestrictedDomain {

+ 20 - 2
api/server/handlers/user/login.go

@@ -10,6 +10,7 @@ import (
 	"github.com/porter-dev/porter/api/server/shared"
 	"github.com/porter-dev/porter/api/server/shared/apierrors"
 	"github.com/porter-dev/porter/api/server/shared/config"
+	"github.com/porter-dev/porter/api/server/shared/config/env"
 	"github.com/porter-dev/porter/api/types"
 	"golang.org/x/crypto/bcrypt"
 	"gorm.io/gorm"
@@ -32,9 +33,12 @@ func NewUserLoginHandler(
 func (u *UserLoginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 	request := &types.LoginUserRequest{}
 
-	ok := u.DecodeAndValidate(w, r, request)
+	if ok := u.DecodeAndValidate(w, r, request); !ok {
+		return
+	}
 
-	if !ok {
+	if err := checkUserRestrictions(u.Config().ServerConf, request.Email); err != nil {
+		u.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusBadRequest))
 		return
 	}
 
@@ -66,3 +70,17 @@ func (u *UserLoginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
 	u.WriteResult(w, r, storedUser.ToUserType())
 }
+
+// checkUserRestrictions checks login restrictions specified by environment variables on the
+// Porter instance.
+func checkUserRestrictions(
+	serverConf *env.ServerConf,
+	reqEmail string,
+) error {
+	// if the admin user env var is specified, only allow admin user email
+	if adminEmail := serverConf.AdminEmail; adminEmail != "" && adminEmail != reqEmail {
+		return fmt.Errorf("email not allowed")
+	}
+
+	return nil
+}

+ 5 - 0
api/server/handlers/user/pw_reset.go

@@ -53,6 +53,11 @@ func (c *UserPasswordInitiateResetHandler) ServeHTTP(w http.ResponseWriter, r *h
 		return
 	}
 
+	if err := checkUserRestrictions(c.Config().ServerConf, user.Email); err != nil {
+		c.HandleAPIError(w, r, apierrors.NewErrForbidden(err))
+		return
+	}
+
 	// if the user is a Github user, send them a Github email
 	if user.GithubUserID != 0 {
 		err := c.Config().UserNotifier.SendGithubRelinkEmail(

+ 5 - 0
api/server/shared/config/env/envconfs.go

@@ -55,6 +55,11 @@ type ServerConf struct {
 	ProvisionerImagePullSecret string `env:"PROV_IMAGE_PULL_SECRET"`
 	SegmentClientKey           string `env:"SEGMENT_CLIENT_KEY"`
 
+	// Email for an admin user. On a self-hosted instance of Porter, the
+	// admin user is the only user that can log in and register. After the admin
+	// user has logged in, registration is turned off.
+	AdminEmail string `env:"ADMIN_EMAIL"`
+
 	SentryDSN string `env:"SENTRY_DSN"`
 	SentryEnv string `env:"SENTRY_ENV,default=dev"`