From b11b3b60215dc054b327800148f30b7f5bdc63f2 Mon Sep 17 00:00:00 2001 From: Yang Luo Date: Thu, 17 Jun 2021 00:49:02 +0800 Subject: [PATCH] Use signup table in Signup API. --- controllers/account.go | 114 +++++++++++++++++++++++------------------ controllers/util.go | 5 ++ object/application.go | 31 +++++++++++ object/check.go | 72 ++++++++++++++++---------- object/user.go | 14 +++++ 5 files changed, 161 insertions(+), 75 deletions(-) diff --git a/controllers/account.go b/controllers/account.go index c29422dd..d1dc3bca 100644 --- a/controllers/account.go +++ b/controllers/account.go @@ -18,6 +18,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + "strconv" "strings" "github.com/casdoor/casdoor/object" @@ -77,9 +78,7 @@ func (c *ApiController) Signup() { var resp Response if c.GetSessionUser() != "" { - resp = Response{Status: "error", Msg: "Please log out first before signing up", Data: c.GetSessionUser()} - c.Data["json"] = resp - c.ServeJSON() + c.ResponseErrorWithData("Please sign out first before signing up", c.GetSessionUser()) return } @@ -89,61 +88,78 @@ func (c *ApiController) Signup() { panic(err) } - checkResult := object.CheckVerificationCode(form.Email, form.EmailCode) - if len(checkResult) != 0 { - responseText := fmt.Sprintf("Email%s", checkResult) - c.ResponseError(responseText) - return - } - - checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Phone) - checkResult = object.CheckVerificationCode(checkPhone, form.PhoneCode) - if len(checkResult) != 0 { - responseText := fmt.Sprintf("Phone%s", checkResult) - c.ResponseError(responseText) - return - } - application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application)) if !application.EnableSignUp { - resp = Response{Status: "error", Msg: "The application does not allow to sign up new account", Data: c.GetSessionUser()} - c.Data["json"] = resp - c.ServeJSON() + c.ResponseError("The application does not allow to sign up new account") return } + if application.IsSignupItemEnabled("Email") { + checkResult := object.CheckVerificationCode(form.Email, form.EmailCode) + if len(checkResult) != 0 { + c.ResponseError(fmt.Sprintf("Email%s", checkResult)) + return + } + } + + var checkPhone string + if application.IsSignupItemEnabled("Phone") { + checkPhone = fmt.Sprintf("+%s%s", form.PhonePrefix, form.Phone) + checkResult := object.CheckVerificationCode(checkPhone, form.PhoneCode) + if len(checkResult) != 0 { + c.ResponseError(fmt.Sprintf("Phone%s", checkResult)) + return + } + } + userId := fmt.Sprintf("%s/%s", form.Organization, form.Username) - msg := object.CheckUserSignup(form.Organization, form.Username, form.Password, form.Name, form.Email, form.Phone, form.Affiliation) + + organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", form.Organization)) + msg := object.CheckUserSignup(application, organization, form.Username, form.Password, form.Name, form.Email, form.Phone, form.Affiliation) if msg != "" { - resp = Response{Status: "error", Msg: msg, Data: ""} - } else { - user := &object.User{ - Owner: form.Organization, - Name: form.Username, - CreatedTime: util.GetCurrentTime(), - Id: util.GenerateId(), - Type: "normal-user", - Password: form.Password, - DisplayName: form.Name, - Avatar: "https://casbin.org/img/casbin.svg", - Email: form.Email, - Phone: form.Phone, - Affiliation: form.Affiliation, - IsAdmin: false, - IsGlobalAdmin: false, - IsForbidden: false, - Properties: map[string]string{}, - } - object.AddUser(user) - - //c.SetSessionUser(user) - - object.DisableVerificationCode(form.Email) - object.DisableVerificationCode(checkPhone) - util.LogInfo(c.Ctx, "API: [%s] is signed up as new user", userId) - resp = Response{Status: "ok", Msg: "", Data: userId} + c.ResponseError(msg) + return } + id := util.GenerateId() + if application.GetSignupItemRule("ID") == "Incremental" { + lastUser := object.GetLastUser(form.Organization) + lastIdInt := util.ParseInt(lastUser.Id) + id = strconv.Itoa(lastIdInt + 1) + } + + username := form.Username + if !application.IsSignupItemVisible("Username") { + username = id + } + + user := &object.User{ + Owner: form.Organization, + Name: username, + CreatedTime: util.GetCurrentTime(), + Id: id, + Type: "normal-user", + Password: form.Password, + DisplayName: form.Name, + Avatar: "https://casbin.org/img/casbin.svg", + Email: form.Email, + Phone: form.Phone, + Affiliation: form.Affiliation, + IsAdmin: false, + IsGlobalAdmin: false, + IsForbidden: false, + Properties: map[string]string{}, + } + object.AddUser(user) + + //c.SetSessionUser(user) + + object.DisableVerificationCode(form.Email) + object.DisableVerificationCode(checkPhone) + + util.LogInfo(c.Ctx, "API: [%s] is signed up as new user", userId) + + resp = Response{Status: "ok", Msg: "", Data: userId} c.Data["json"] = resp c.ServeJSON() } diff --git a/controllers/util.go b/controllers/util.go index 37f4936e..5ba21ffe 100644 --- a/controllers/util.go +++ b/controllers/util.go @@ -58,6 +58,11 @@ func (c *ApiController) ResponseError(error string) { c.ServeJSON() } +func (c *ApiController) ResponseErrorWithData(error string, data interface{}) { + c.Data["json"] = Response{Status: "error", Msg: error, Data: data} + c.ServeJSON() +} + func (c *ApiController) RequireSignedIn() (string, bool) { userId := c.GetSessionUser() if userId == "" { diff --git a/object/application.go b/object/application.go index ce217025..9fd27972 100644 --- a/object/application.go +++ b/object/application.go @@ -208,3 +208,34 @@ func (application *Application) GetEmailProvider() *Provider { func (application *Application) GetSmsProvider() *Provider { return application.getProviderByCategory("SMS") } + +func (application *Application) getSignupItem(itemName string) *SignupItem { + for _, signupItem := range application.SignupItems { + if signupItem.Name == itemName { + return signupItem + } + } + return nil +} + +func (application *Application) IsSignupItemEnabled(itemName string) bool { + return application.getSignupItem(itemName) != nil +} + +func (application *Application) IsSignupItemVisible(itemName string) bool { + signupItem := application.getSignupItem(itemName) + if signupItem == nil { + return false + } + + return signupItem.Visible +} + +func (application *Application) GetSignupItemRule(itemName string) string { + signupItem := application.getSignupItem(itemName) + if signupItem == nil { + return "" + } + + return signupItem.Rule +} diff --git a/object/check.go b/object/check.go index 3449f0e2..546c8f44 100644 --- a/object/check.go +++ b/object/check.go @@ -27,34 +27,54 @@ func init() { reWhiteSpace, _ = regexp.Compile("\\s") } -func CheckUserSignup(organizationName string, username string, password string, displayName string, email string, phone string, affiliation string) string { - organization := getOrganization("admin", organizationName) - - if len(username) <= 2 { - return "username must have at least 3 characters" - } else if len(password) <= 5 { - return "password must have at least 6 characters" - } else if organization == nil { +func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, email string, phone string, affiliation string) string { + if organization == nil { return "organization does not exist" - } else if reWhiteSpace.MatchString(username) { - return "username cannot contain white spaces" - } else if HasUserByField(organizationName, "name", username) { - return "username already exists" - } else if HasUserByField(organizationName, "email", email) { - return "email already exists" - } else if HasUserByField(organizationName, "phone", phone) { - return "phone already exists" - } else if displayName == "" { - return "displayName cannot be blank" - } else if affiliation == "" { - return "affiliation cannot be blank" - } else if !util.IsEmailValid(email) { - return "email is invalid" - } else if organization.PhonePrefix == "86" && !util.IsPhoneCnValid(phone) { - return "phone number is invalid" - } else { - return "" } + + if application.IsSignupItemVisible("Username") { + if len(username) <= 1 { + return "username must have at least 2 characters" + } else if reWhiteSpace.MatchString(username) { + return "username cannot contain white spaces" + } else if HasUserByField(organization.Name, "name", username) { + return "username already exists" + } + } + + if len(password) <= 5 { + return "password must have at least 6 characters" + } + + if application.IsSignupItemVisible("Email") { + if HasUserByField(organization.Name, "email", email) { + return "email already exists" + } else if !util.IsEmailValid(email) { + return "email is invalid" + } + } + + if application.IsSignupItemVisible("Phone") { + if HasUserByField(organization.Name, "phone", phone) { + return "phone already exists" + } else if organization.PhonePrefix == "86" && !util.IsPhoneCnValid(phone) { + return "phone number is invalid" + } + } + + if application.IsSignupItemVisible("Display name") { + if displayName == "" { + return "displayName cannot be blank" + } + } + + if application.IsSignupItemVisible("Affiliation") { + if affiliation == "" { + return "affiliation cannot be blank" + } + } + + return "" } func CheckPassword(user *User, password string) string { diff --git a/object/user.go b/object/user.go index a3e25c96..b9a13af4 100644 --- a/object/user.go +++ b/object/user.go @@ -114,6 +114,20 @@ func GetMaskedUsers(users []*User) []*User { return users } +func GetLastUser(owner string) *User { + user := User{Owner: owner} + existed, err := adapter.Engine.Desc("created_time", "id").Get(&user) + if err != nil { + panic(err) + } + + if existed { + return &user + } else { + return nil + } +} + func UpdateUser(id string, user *User) bool { owner, name := util.GetOwnerAndNameFromId(id) if getUser(owner, name) == nil {