mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-24 08:20:31 +08:00
feat: refactor out form package and optimize verification code module (#1787)
* refactor: add forms package and optimize verification code module * chore: add license * chore: fix lint * chore: fix lint * chore: fix lint * chore: swagger
This commit is contained in:
parent
511aefb706
commit
95f4f4cb6d
@ -21,6 +21,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/form"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
)
|
)
|
||||||
@ -34,44 +35,6 @@ const (
|
|||||||
ResponseTypeCas = "cas"
|
ResponseTypeCas = "cas"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RequestForm struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
|
|
||||||
Organization string `json:"organization"`
|
|
||||||
Username string `json:"username"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
FirstName string `json:"firstName"`
|
|
||||||
LastName string `json:"lastName"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Phone string `json:"phone"`
|
|
||||||
Affiliation string `json:"affiliation"`
|
|
||||||
IdCard string `json:"idCard"`
|
|
||||||
Region string `json:"region"`
|
|
||||||
|
|
||||||
Application string `json:"application"`
|
|
||||||
ClientId string `json:"clientId"`
|
|
||||||
Provider string `json:"provider"`
|
|
||||||
Code string `json:"code"`
|
|
||||||
State string `json:"state"`
|
|
||||||
RedirectUri string `json:"redirectUri"`
|
|
||||||
Method string `json:"method"`
|
|
||||||
|
|
||||||
EmailCode string `json:"emailCode"`
|
|
||||||
PhoneCode string `json:"phoneCode"`
|
|
||||||
CountryCode string `json:"countryCode"`
|
|
||||||
|
|
||||||
AutoSignin bool `json:"autoSignin"`
|
|
||||||
|
|
||||||
RelayState string `json:"relayState"`
|
|
||||||
SamlRequest string `json:"samlRequest"`
|
|
||||||
SamlResponse string `json:"samlResponse"`
|
|
||||||
|
|
||||||
CaptchaType string `json:"captchaType"`
|
|
||||||
CaptchaToken string `json:"captchaToken"`
|
|
||||||
ClientSecret string `json:"clientSecret"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
Msg string `json:"msg"`
|
Msg string `json:"msg"`
|
||||||
@ -108,28 +71,28 @@ func (c *ApiController) Signup() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var form RequestForm
|
var authForm form.AuthForm
|
||||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &form)
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &authForm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||||
if !application.EnableSignUp {
|
if !application.EnableSignUp {
|
||||||
c.ResponseError(c.T("account:The application does not allow to sign up new account"))
|
c.ResponseError(c.T("account:The application does not allow to sign up new account"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", form.Organization))
|
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", authForm.Organization))
|
||||||
msg := object.CheckUserSignup(application, organization, form.Username, form.Password, form.Name, form.FirstName, form.LastName, form.Email, form.Phone, form.CountryCode, form.Affiliation, c.GetAcceptLanguage())
|
msg := object.CheckUserSignup(application, organization, &authForm, c.GetAcceptLanguage())
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
c.ResponseError(msg)
|
c.ResponseError(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Email") && application.GetSignupItemRule("Email") != "No verification" && form.Email != "" {
|
if application.IsSignupItemVisible("Email") && application.GetSignupItemRule("Email") != "No verification" && authForm.Email != "" {
|
||||||
checkResult := object.CheckVerificationCode(form.Email, form.EmailCode, c.GetAcceptLanguage())
|
checkResult := object.CheckVerificationCode(authForm.Email, authForm.EmailCode, c.GetAcceptLanguage())
|
||||||
if checkResult.Code != object.VerificationSuccess {
|
if checkResult.Code != object.VerificationSuccess {
|
||||||
c.ResponseError(checkResult.Msg)
|
c.ResponseError(checkResult.Msg)
|
||||||
return
|
return
|
||||||
@ -137,9 +100,9 @@ func (c *ApiController) Signup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var checkPhone string
|
var checkPhone string
|
||||||
if application.IsSignupItemVisible("Phone") && application.GetSignupItemRule("Phone") != "No verification" && form.Phone != "" {
|
if application.IsSignupItemVisible("Phone") && application.GetSignupItemRule("Phone") != "No verification" && authForm.Phone != "" {
|
||||||
checkPhone, _ = util.GetE164Number(form.Phone, form.CountryCode)
|
checkPhone, _ = util.GetE164Number(authForm.Phone, authForm.CountryCode)
|
||||||
checkResult := object.CheckVerificationCode(checkPhone, form.PhoneCode, c.GetAcceptLanguage())
|
checkResult := object.CheckVerificationCode(checkPhone, authForm.PhoneCode, c.GetAcceptLanguage())
|
||||||
if checkResult.Code != object.VerificationSuccess {
|
if checkResult.Code != object.VerificationSuccess {
|
||||||
c.ResponseError(checkResult.Msg)
|
c.ResponseError(checkResult.Msg)
|
||||||
return
|
return
|
||||||
@ -148,7 +111,7 @@ func (c *ApiController) Signup() {
|
|||||||
|
|
||||||
id := util.GenerateId()
|
id := util.GenerateId()
|
||||||
if application.GetSignupItemRule("ID") == "Incremental" {
|
if application.GetSignupItemRule("ID") == "Incremental" {
|
||||||
lastUser := object.GetLastUser(form.Organization)
|
lastUser := object.GetLastUser(authForm.Organization)
|
||||||
|
|
||||||
lastIdInt := -1
|
lastIdInt := -1
|
||||||
if lastUser != nil {
|
if lastUser != nil {
|
||||||
@ -158,7 +121,7 @@ func (c *ApiController) Signup() {
|
|||||||
id = strconv.Itoa(lastIdInt + 1)
|
id = strconv.Itoa(lastIdInt + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
username := form.Username
|
username := authForm.Username
|
||||||
if !application.IsSignupItemVisible("Username") {
|
if !application.IsSignupItemVisible("Username") {
|
||||||
username = id
|
username = id
|
||||||
}
|
}
|
||||||
@ -170,21 +133,21 @@ func (c *ApiController) Signup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user := &object.User{
|
user := &object.User{
|
||||||
Owner: form.Organization,
|
Owner: authForm.Organization,
|
||||||
Name: username,
|
Name: username,
|
||||||
CreatedTime: util.GetCurrentTime(),
|
CreatedTime: util.GetCurrentTime(),
|
||||||
Id: id,
|
Id: id,
|
||||||
Type: "normal-user",
|
Type: "normal-user",
|
||||||
Password: form.Password,
|
Password: authForm.Password,
|
||||||
DisplayName: form.Name,
|
DisplayName: authForm.Name,
|
||||||
Avatar: organization.DefaultAvatar,
|
Avatar: organization.DefaultAvatar,
|
||||||
Email: form.Email,
|
Email: authForm.Email,
|
||||||
Phone: form.Phone,
|
Phone: authForm.Phone,
|
||||||
CountryCode: form.CountryCode,
|
CountryCode: authForm.CountryCode,
|
||||||
Address: []string{},
|
Address: []string{},
|
||||||
Affiliation: form.Affiliation,
|
Affiliation: authForm.Affiliation,
|
||||||
IdCard: form.IdCard,
|
IdCard: authForm.IdCard,
|
||||||
Region: form.Region,
|
Region: authForm.Region,
|
||||||
Score: initScore,
|
Score: initScore,
|
||||||
IsAdmin: false,
|
IsAdmin: false,
|
||||||
IsGlobalAdmin: false,
|
IsGlobalAdmin: false,
|
||||||
@ -203,10 +166,10 @@ func (c *ApiController) Signup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if application.GetSignupItemRule("Display name") == "First, last" {
|
if application.GetSignupItemRule("Display name") == "First, last" {
|
||||||
if form.FirstName != "" || form.LastName != "" {
|
if authForm.FirstName != "" || authForm.LastName != "" {
|
||||||
user.DisplayName = fmt.Sprintf("%s %s", form.FirstName, form.LastName)
|
user.DisplayName = fmt.Sprintf("%s %s", authForm.FirstName, authForm.LastName)
|
||||||
user.FirstName = form.FirstName
|
user.FirstName = authForm.FirstName
|
||||||
user.LastName = form.LastName
|
user.LastName = authForm.LastName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,7 +186,7 @@ func (c *ApiController) Signup() {
|
|||||||
c.SetSessionUsername(user.GetId())
|
c.SetSessionUsername(user.GetId())
|
||||||
}
|
}
|
||||||
|
|
||||||
object.DisableVerificationCode(form.Email)
|
object.DisableVerificationCode(authForm.Email)
|
||||||
object.DisableVerificationCode(checkPhone)
|
object.DisableVerificationCode(checkPhone)
|
||||||
|
|
||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
|
@ -28,6 +28,7 @@ import (
|
|||||||
|
|
||||||
"github.com/casdoor/casdoor/captcha"
|
"github.com/casdoor/casdoor/captcha"
|
||||||
"github.com/casdoor/casdoor/conf"
|
"github.com/casdoor/casdoor/conf"
|
||||||
|
"github.com/casdoor/casdoor/form"
|
||||||
"github.com/casdoor/casdoor/idp"
|
"github.com/casdoor/casdoor/idp"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/proxy"
|
"github.com/casdoor/casdoor/proxy"
|
||||||
@ -56,7 +57,7 @@ func tokenToResponse(token *object.Token) *Response {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HandleLoggedIn ...
|
// HandleLoggedIn ...
|
||||||
func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *RequestForm) (resp *Response) {
|
func (c *ApiController) HandleLoggedIn(application *object.Application, user *object.User, form *form.AuthForm) (resp *Response) {
|
||||||
userId := user.GetId()
|
userId := user.GetId()
|
||||||
|
|
||||||
allowed, err := object.CheckAccessPermission(userId, application)
|
allowed, err := object.CheckAccessPermission(userId, application)
|
||||||
@ -221,21 +222,21 @@ func isProxyProviderType(providerType string) bool {
|
|||||||
// @Param nonce query string false nonce
|
// @Param nonce query string false nonce
|
||||||
// @Param code_challenge_method query string false code_challenge_method
|
// @Param code_challenge_method query string false code_challenge_method
|
||||||
// @Param code_challenge query string false code_challenge
|
// @Param code_challenge query string false code_challenge
|
||||||
// @Param form body controllers.RequestForm true "Login information"
|
// @Param form body controllers.AuthForm true "Login information"
|
||||||
// @Success 200 {object} Response The Response object
|
// @Success 200 {object} Response The Response object
|
||||||
// @router /login [post]
|
// @router /login [post]
|
||||||
func (c *ApiController) Login() {
|
func (c *ApiController) Login() {
|
||||||
resp := &Response{}
|
resp := &Response{}
|
||||||
|
|
||||||
var form RequestForm
|
var authForm form.AuthForm
|
||||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &form)
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &authForm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.Username != "" {
|
if authForm.Username != "" {
|
||||||
if form.Type == ResponseTypeLogin {
|
if authForm.Type == ResponseTypeLogin {
|
||||||
if c.GetSessionUsername() != "" {
|
if c.GetSessionUsername() != "" {
|
||||||
c.ResponseError(c.T("account:Please sign out first"), c.GetSessionUsername())
|
c.ResponseError(c.T("account:Please sign out first"), c.GetSessionUsername())
|
||||||
return
|
return
|
||||||
@ -245,25 +246,25 @@ func (c *ApiController) Login() {
|
|||||||
var user *object.User
|
var user *object.User
|
||||||
var msg string
|
var msg string
|
||||||
|
|
||||||
if form.Password == "" {
|
if authForm.Password == "" {
|
||||||
if user = object.GetUserByFields(form.Organization, form.Username); user == nil {
|
if user = object.GetUserByFields(authForm.Organization, authForm.Username); user == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(authForm.Organization, authForm.Username)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationCodeType := object.GetVerifyType(form.Username)
|
verificationCodeType := object.GetVerifyType(authForm.Username)
|
||||||
var checkDest string
|
var checkDest string
|
||||||
if verificationCodeType == object.VerifyTypePhone {
|
if verificationCodeType == object.VerifyTypePhone {
|
||||||
form.CountryCode = user.GetCountryCode(form.CountryCode)
|
authForm.CountryCode = user.GetCountryCode(authForm.CountryCode)
|
||||||
var ok bool
|
var ok bool
|
||||||
if checkDest, ok = util.GetE164Number(form.Username, form.CountryCode); !ok {
|
if checkDest, ok = util.GetE164Number(authForm.Username, authForm.CountryCode); !ok {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), form.CountryCode))
|
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), authForm.CountryCode))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check result through Email or Phone
|
// check result through Email or Phone
|
||||||
checkResult := object.CheckSigninCode(user, checkDest, form.Code, c.GetAcceptLanguage())
|
checkResult := object.CheckSigninCode(user, checkDest, authForm.Code, c.GetAcceptLanguage())
|
||||||
if len(checkResult) != 0 {
|
if len(checkResult) != 0 {
|
||||||
c.ResponseError(fmt.Sprintf("%s - %s", verificationCodeType, checkResult))
|
c.ResponseError(fmt.Sprintf("%s - %s", verificationCodeType, checkResult))
|
||||||
return
|
return
|
||||||
@ -272,9 +273,9 @@ func (c *ApiController) Login() {
|
|||||||
// disable the verification code
|
// disable the verification code
|
||||||
object.DisableVerificationCode(checkDest)
|
object.DisableVerificationCode(checkDest)
|
||||||
} else {
|
} else {
|
||||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !application.EnablePassword {
|
if !application.EnablePassword {
|
||||||
@ -282,8 +283,8 @@ func (c *ApiController) Login() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var enableCaptcha bool
|
var enableCaptcha bool
|
||||||
if enableCaptcha = object.CheckToEnableCaptcha(application, form.Organization, form.Username); enableCaptcha {
|
if enableCaptcha = object.CheckToEnableCaptcha(application, authForm.Organization, authForm.Username); enableCaptcha {
|
||||||
isHuman, err := captcha.VerifyCaptchaByCaptchaType(form.CaptchaType, form.CaptchaToken, form.ClientSecret)
|
isHuman, err := captcha.VerifyCaptchaByCaptchaType(authForm.CaptchaType, authForm.CaptchaToken, authForm.ClientSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -295,42 +296,42 @@ func (c *ApiController) Login() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
password := form.Password
|
password := authForm.Password
|
||||||
user, msg = object.CheckUserPassword(form.Organization, form.Username, password, c.GetAcceptLanguage(), enableCaptcha)
|
user, msg = object.CheckUserPassword(authForm.Organization, authForm.Username, password, c.GetAcceptLanguage(), enableCaptcha)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
resp = &Response{Status: "error", Msg: msg}
|
resp = &Response{Status: "error", Msg: msg}
|
||||||
} else {
|
} else {
|
||||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = c.HandleLoggedIn(application, user, &form)
|
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||||
|
|
||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
record.Organization = application.Organization
|
record.Organization = application.Organization
|
||||||
record.User = user.Name
|
record.User = user.Name
|
||||||
util.SafeGoroutine(func() { object.AddRecord(record) })
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
}
|
}
|
||||||
} else if form.Provider != "" {
|
} else if authForm.Provider != "" {
|
||||||
var application *object.Application
|
var application *object.Application
|
||||||
if form.ClientId != "" {
|
if authForm.ClientId != "" {
|
||||||
application = object.GetApplicationByClientId(form.ClientId)
|
application = object.GetApplicationByClientId(authForm.ClientId)
|
||||||
} else {
|
} else {
|
||||||
application = object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application = object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||||
}
|
}
|
||||||
|
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", application.Organization))
|
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", application.Organization))
|
||||||
provider := object.GetProvider(util.GetId("admin", form.Provider))
|
provider := object.GetProvider(util.GetId("admin", authForm.Provider))
|
||||||
providerItem := application.GetProviderItem(provider.Name)
|
providerItem := application.GetProviderItem(provider.Name)
|
||||||
if !providerItem.IsProviderVisible() {
|
if !providerItem.IsProviderVisible() {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:The provider: %s is not enabled for the application"), provider.Name))
|
c.ResponseError(fmt.Sprintf(c.T("auth:The provider: %s is not enabled for the application"), provider.Name))
|
||||||
@ -340,7 +341,7 @@ func (c *ApiController) Login() {
|
|||||||
userInfo := &idp.UserInfo{}
|
userInfo := &idp.UserInfo{}
|
||||||
if provider.Category == "SAML" {
|
if provider.Category == "SAML" {
|
||||||
// SAML
|
// SAML
|
||||||
userInfo.Id, err = object.ParseSamlResponse(form.SamlResponse, provider, c.Ctx.Request.Host)
|
userInfo.Id, err = object.ParseSamlResponse(authForm.SamlResponse, provider, c.Ctx.Request.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -355,7 +356,7 @@ func (c *ApiController) Login() {
|
|||||||
clientSecret = provider.ClientSecret2
|
clientSecret = provider.ClientSecret2
|
||||||
}
|
}
|
||||||
|
|
||||||
idProvider := idp.GetIdProvider(provider.Type, provider.SubType, clientId, clientSecret, provider.AppId, form.RedirectUri, provider.Domain, provider.CustomAuthUrl, provider.CustomTokenUrl, provider.CustomUserInfoUrl)
|
idProvider := idp.GetIdProvider(provider.Type, provider.SubType, clientId, clientSecret, provider.AppId, authForm.RedirectUri, provider.Domain, provider.CustomAuthUrl, provider.CustomTokenUrl, provider.CustomUserInfoUrl)
|
||||||
if idProvider == nil {
|
if idProvider == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("storage:The provider type: %s is not supported"), provider.Type))
|
c.ResponseError(fmt.Sprintf(c.T("storage:The provider type: %s is not supported"), provider.Type))
|
||||||
return
|
return
|
||||||
@ -363,13 +364,13 @@ func (c *ApiController) Login() {
|
|||||||
|
|
||||||
setHttpClient(idProvider, provider.Type)
|
setHttpClient(idProvider, provider.Type)
|
||||||
|
|
||||||
if form.State != conf.GetConfigString("authState") && form.State != application.Name {
|
if authForm.State != conf.GetConfigString("authState") && authForm.State != application.Name {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:State expected: %s, but got: %s"), conf.GetConfigString("authState"), form.State))
|
c.ResponseError(fmt.Sprintf(c.T("auth:State expected: %s, but got: %s"), conf.GetConfigString("authState"), authForm.State))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/golang/oauth2/issues/123#issuecomment-103715338
|
// https://github.com/golang/oauth2/issues/123#issuecomment-103715338
|
||||||
token, err := idProvider.GetToken(form.Code)
|
token, err := idProvider.GetToken(authForm.Code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
@ -387,7 +388,7 @@ func (c *ApiController) Login() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if form.Method == "signup" {
|
if authForm.Method == "signup" {
|
||||||
user := &object.User{}
|
user := &object.User{}
|
||||||
if provider.Category == "SAML" {
|
if provider.Category == "SAML" {
|
||||||
user = object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Id))
|
user = object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Id))
|
||||||
@ -402,7 +403,7 @@ func (c *ApiController) Login() {
|
|||||||
c.ResponseError(c.T("check:The user is forbidden to sign in, please contact the administrator"))
|
c.ResponseError(c.T("check:The user is forbidden to sign in, please contact the administrator"))
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = c.HandleLoggedIn(application, user, &form)
|
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||||
|
|
||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
record.Organization = application.Organization
|
record.Organization = application.Organization
|
||||||
@ -477,7 +478,7 @@ func (c *ApiController) Login() {
|
|||||||
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
|
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
|
||||||
object.LinkUserAccount(user, provider.Type, userInfo.Id)
|
object.LinkUserAccount(user, provider.Type, userInfo.Id)
|
||||||
|
|
||||||
resp = c.HandleLoggedIn(application, user, &form)
|
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||||
|
|
||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
record.Organization = application.Organization
|
record.Organization = application.Organization
|
||||||
@ -493,7 +494,7 @@ func (c *ApiController) Login() {
|
|||||||
resp = &Response{Status: "error", Msg: fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id))}
|
resp = &Response{Status: "error", Msg: fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id))}
|
||||||
}
|
}
|
||||||
// resp = &Response{Status: "ok", Msg: "", Data: res}
|
// resp = &Response{Status: "ok", Msg: "", Data: res}
|
||||||
} else { // form.Method != "signup"
|
} else { // authForm.Method != "signup"
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
if userId == "" {
|
if userId == "" {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id)), userInfo)
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id)), userInfo)
|
||||||
@ -521,21 +522,21 @@ func (c *ApiController) Login() {
|
|||||||
} else {
|
} else {
|
||||||
if c.GetSessionUsername() != "" {
|
if c.GetSessionUsername() != "" {
|
||||||
// user already signed in to Casdoor, so let the user click the avatar button to do the quick sign-in
|
// user already signed in to Casdoor, so let the user click the avatar button to do the quick sign-in
|
||||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
application := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||||
if application == nil {
|
if application == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), authForm.Application))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
user := c.getCurrentUser()
|
user := c.getCurrentUser()
|
||||||
resp = c.HandleLoggedIn(application, user, &form)
|
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||||
|
|
||||||
record := object.NewRecord(c.Ctx)
|
record := object.NewRecord(c.Ctx)
|
||||||
record.Organization = application.Organization
|
record.Organization = application.Organization
|
||||||
record.User = user.Name
|
record.User = user.Name
|
||||||
util.SafeGoroutine(func() { object.AddRecord(record) })
|
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||||
} else {
|
} else {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("auth:Unknown authentication type (not password or provider), form = %s"), util.StructToJson(form)))
|
c.ResponseError(fmt.Sprintf(c.T("auth:Unknown authentication type (not password or provider), authForm = %s"), util.StructToJson(authForm)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,18 +41,41 @@ type SessionData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ApiController) IsGlobalAdmin() bool {
|
func (c *ApiController) IsGlobalAdmin() bool {
|
||||||
|
isGlobalAdmin, _ := c.isGlobalAdmin()
|
||||||
|
|
||||||
|
return isGlobalAdmin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) IsAdmin() bool {
|
||||||
|
isGlobalAdmin, user := c.isGlobalAdmin()
|
||||||
|
|
||||||
|
return isGlobalAdmin || user.IsAdmin
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) isGlobalAdmin() (bool, *object.User) {
|
||||||
username := c.GetSessionUsername()
|
username := c.GetSessionUsername()
|
||||||
if strings.HasPrefix(username, "app/") {
|
if strings.HasPrefix(username, "app/") {
|
||||||
// e.g., "app/app-casnode"
|
// e.g., "app/app-casnode"
|
||||||
return true
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
user := object.GetUser(username)
|
user := c.getCurrentUser()
|
||||||
if user == nil {
|
if user == nil {
|
||||||
return false
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return user.Owner == "built-in" || user.IsGlobalAdmin
|
return user.Owner == "built-in" || user.IsGlobalAdmin, user
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) getCurrentUser() *object.User {
|
||||||
|
var user *object.User
|
||||||
|
userId := c.GetSessionUsername()
|
||||||
|
if userId == "" {
|
||||||
|
user = nil
|
||||||
|
} else {
|
||||||
|
user = object.GetUser(userId)
|
||||||
|
}
|
||||||
|
return user
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSessionUsername ...
|
// GetSessionUsername ...
|
||||||
|
@ -162,7 +162,9 @@ func (c *ApiController) UpdateUser() {
|
|||||||
c.ResponseError(msg)
|
c.ResponseError(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if pass, err := checkPermissionForUpdateUser(oldUser, &user, c); !pass {
|
|
||||||
|
isAdmin := c.IsAdmin()
|
||||||
|
if pass, err := object.CheckPermissionForUpdateUser(oldUser, &user, isAdmin, c.GetAcceptLanguage()); !pass {
|
||||||
c.ResponseError(err)
|
c.ResponseError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -172,9 +174,7 @@ func (c *ApiController) UpdateUser() {
|
|||||||
columns = strings.Split(columnsStr, ",")
|
columns = strings.Split(columnsStr, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
isGlobalAdmin := c.IsGlobalAdmin()
|
affected := object.UpdateUser(id, &user, columns, isAdmin)
|
||||||
|
|
||||||
affected := object.UpdateUser(id, &user, columns, isGlobalAdmin)
|
|
||||||
if affected {
|
if affected {
|
||||||
object.UpdateUserToOriginalDatabase(&user)
|
object.UpdateUserToOriginalDatabase(&user)
|
||||||
}
|
}
|
||||||
|
@ -1,138 +0,0 @@
|
|||||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package controllers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/object"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkPermissionForUpdateUser(oldUser, newUser *object.User, c *ApiController) (bool, string) {
|
|
||||||
organization := object.GetOrganizationByUser(oldUser)
|
|
||||||
var itemsChanged []*object.AccountItem
|
|
||||||
|
|
||||||
if oldUser.Owner != newUser.Owner {
|
|
||||||
item := object.GetAccountItemByName("Organization", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Name != newUser.Name {
|
|
||||||
item := object.GetAccountItemByName("Name", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Id != newUser.Id {
|
|
||||||
item := object.GetAccountItemByName("ID", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.DisplayName != newUser.DisplayName {
|
|
||||||
item := object.GetAccountItemByName("Display name", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Avatar != newUser.Avatar {
|
|
||||||
item := object.GetAccountItemByName("Avatar", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Type != newUser.Type {
|
|
||||||
item := object.GetAccountItemByName("User type", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
// The password is *** when not modified
|
|
||||||
if oldUser.Password != newUser.Password && newUser.Password != "***" {
|
|
||||||
item := object.GetAccountItemByName("Password", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Email != newUser.Email {
|
|
||||||
item := object.GetAccountItemByName("Email", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Phone != newUser.Phone {
|
|
||||||
item := object.GetAccountItemByName("Phone", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.CountryCode != newUser.CountryCode {
|
|
||||||
item := object.GetAccountItemByName("Country code", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Region != newUser.Region {
|
|
||||||
item := object.GetAccountItemByName("Country/Region", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Location != newUser.Location {
|
|
||||||
item := object.GetAccountItemByName("Location", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Affiliation != newUser.Affiliation {
|
|
||||||
item := object.GetAccountItemByName("Affiliation", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Title != newUser.Title {
|
|
||||||
item := object.GetAccountItemByName("Title", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Homepage != newUser.Homepage {
|
|
||||||
item := object.GetAccountItemByName("Homepage", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Bio != newUser.Bio {
|
|
||||||
item := object.GetAccountItemByName("Bio", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.Tag != newUser.Tag {
|
|
||||||
item := object.GetAccountItemByName("Tag", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.SignupApplication != newUser.SignupApplication {
|
|
||||||
item := object.GetAccountItemByName("Signup application", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
oldUserPropertiesJson, _ := json.Marshal(oldUser.Properties)
|
|
||||||
newUserPropertiesJson, _ := json.Marshal(newUser.Properties)
|
|
||||||
if string(oldUserPropertiesJson) != string(newUserPropertiesJson) {
|
|
||||||
item := object.GetAccountItemByName("Properties", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
if oldUser.IsAdmin != newUser.IsAdmin {
|
|
||||||
item := object.GetAccountItemByName("Is admin", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.IsGlobalAdmin != newUser.IsGlobalAdmin {
|
|
||||||
item := object.GetAccountItemByName("Is global admin", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.IsForbidden != newUser.IsForbidden {
|
|
||||||
item := object.GetAccountItemByName("Is forbidden", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
if oldUser.IsDeleted != newUser.IsDeleted {
|
|
||||||
item := object.GetAccountItemByName("Is deleted", organization)
|
|
||||||
itemsChanged = append(itemsChanged, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentUser := c.getCurrentUser()
|
|
||||||
if currentUser == nil && c.IsGlobalAdmin() {
|
|
||||||
currentUser = &object.User{
|
|
||||||
IsGlobalAdmin: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range itemsChanged {
|
|
||||||
if pass, err := object.CheckAccountItemModifyRule(itemsChanged[i], currentUser, c.GetAcceptLanguage()); !pass {
|
|
||||||
return pass, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true, ""
|
|
||||||
}
|
|
@ -21,6 +21,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/captcha"
|
"github.com/casdoor/casdoor/captcha"
|
||||||
|
"github.com/casdoor/casdoor/form"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
)
|
)
|
||||||
@ -32,60 +33,29 @@ const (
|
|||||||
ForgetVerification = "forget"
|
ForgetVerification = "forget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *ApiController) getCurrentUser() *object.User {
|
|
||||||
var user *object.User
|
|
||||||
userId := c.GetSessionUsername()
|
|
||||||
if userId == "" {
|
|
||||||
user = nil
|
|
||||||
} else {
|
|
||||||
user = object.GetUser(userId)
|
|
||||||
}
|
|
||||||
return user
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendVerificationCode ...
|
// SendVerificationCode ...
|
||||||
// @Title SendVerificationCode
|
// @Title SendVerificationCode
|
||||||
// @Tag Verification API
|
// @Tag Verification API
|
||||||
// @router /send-verification-code [post]
|
// @router /send-verification-code [post]
|
||||||
func (c *ApiController) SendVerificationCode() {
|
func (c *ApiController) SendVerificationCode() {
|
||||||
destType := c.Ctx.Request.Form.Get("type")
|
var vform form.VerificationForm
|
||||||
dest := c.Ctx.Request.Form.Get("dest")
|
err := c.ParseForm(&vform)
|
||||||
countryCode := c.Ctx.Request.Form.Get("countryCode")
|
if err != nil {
|
||||||
checkType := c.Ctx.Request.Form.Get("checkType")
|
c.ResponseError(err.Error())
|
||||||
clientSecret := c.Ctx.Request.Form.Get("clientSecret")
|
return
|
||||||
captchaToken := c.Ctx.Request.Form.Get("captchaToken")
|
}
|
||||||
applicationId := c.Ctx.Request.Form.Get("applicationId")
|
|
||||||
method := c.Ctx.Request.Form.Get("method")
|
|
||||||
checkUser := c.Ctx.Request.Form.Get("checkUser")
|
|
||||||
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
|
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
|
||||||
|
|
||||||
if dest == "" {
|
if msg := vform.CheckParameter(form.SendVerifyCode, c.GetAcceptLanguage()); msg != "" {
|
||||||
c.ResponseError(c.T("general:Missing parameter") + ": dest.")
|
c.ResponseError(msg)
|
||||||
return
|
|
||||||
}
|
|
||||||
if applicationId == "" {
|
|
||||||
c.ResponseError(c.T("general:Missing parameter") + ": applicationId.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if checkType == "" {
|
|
||||||
c.ResponseError(c.T("general:Missing parameter") + ": checkType.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !strings.Contains(applicationId, "/") {
|
|
||||||
c.ResponseError(c.T("verification:Wrong parameter") + ": applicationId.")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if checkType != "none" {
|
if vform.CaptchaType != "none" {
|
||||||
if captchaToken == "" {
|
if captchaProvider := captcha.GetCaptchaProvider(vform.CaptchaType); captchaProvider == nil {
|
||||||
c.ResponseError(c.T("general:Missing parameter") + ": captchaToken.")
|
c.ResponseError(c.T("general:don't support captchaProvider: ") + vform.CaptchaType)
|
||||||
return
|
return
|
||||||
}
|
} else if isHuman, err := captchaProvider.VerifyCaptcha(vform.CaptchaToken, vform.ClientSecret); err != nil {
|
||||||
|
|
||||||
if captchaProvider := captcha.GetCaptchaProvider(checkType); captchaProvider == nil {
|
|
||||||
c.ResponseError(c.T("general:don't support captchaProvider: ") + checkType)
|
|
||||||
return
|
|
||||||
} else if isHuman, err := captchaProvider.VerifyCaptcha(captchaToken, clientSecret); err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
} else if !isHuman {
|
} else if !isHuman {
|
||||||
@ -94,7 +64,7 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
application := object.GetApplication(applicationId)
|
application := object.GetApplication(vform.ApplicationId)
|
||||||
organization := object.GetOrganization(util.GetId(application.Owner, application.Organization))
|
organization := object.GetOrganization(util.GetId(application.Owner, application.Organization))
|
||||||
if organization == nil {
|
if organization == nil {
|
||||||
c.ResponseError(c.T("check:Organization does not exist"))
|
c.ResponseError(c.T("check:Organization does not exist"))
|
||||||
@ -103,57 +73,57 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
|
|
||||||
var user *object.User
|
var user *object.User
|
||||||
// checkUser != "", means method is ForgetVerification
|
// checkUser != "", means method is ForgetVerification
|
||||||
if checkUser != "" {
|
if vform.CheckUser != "" {
|
||||||
owner := application.Organization
|
owner := application.Organization
|
||||||
user = object.GetUser(util.GetId(owner, checkUser))
|
user = object.GetUser(util.GetId(owner, vform.CheckUser))
|
||||||
}
|
}
|
||||||
|
|
||||||
sendResp := errors.New("invalid dest type")
|
sendResp := errors.New("invalid dest type")
|
||||||
|
|
||||||
switch destType {
|
switch vform.Type {
|
||||||
case object.VerifyTypeEmail:
|
case object.VerifyTypeEmail:
|
||||||
if !util.IsEmailValid(dest) {
|
if !util.IsEmailValid(vform.Dest) {
|
||||||
c.ResponseError(c.T("check:Email is invalid"))
|
c.ResponseError(c.T("check:Email is invalid"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if method == LoginVerification || method == ForgetVerification {
|
if vform.Method == LoginVerification || vform.Method == ForgetVerification {
|
||||||
if user != nil && util.GetMaskedEmail(user.Email) == dest {
|
if user != nil && util.GetMaskedEmail(user.Email) == vform.Dest {
|
||||||
dest = user.Email
|
vform.Dest = user.Email
|
||||||
}
|
}
|
||||||
|
|
||||||
user = object.GetUserByEmail(organization.Name, dest)
|
user = object.GetUserByEmail(organization.Name, vform.Dest)
|
||||||
if user == nil {
|
if user == nil {
|
||||||
c.ResponseError(c.T("verification:the user does not exist, please sign up first"))
|
c.ResponseError(c.T("verification:the user does not exist, please sign up first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if method == ResetVerification {
|
} else if vform.Method == ResetVerification {
|
||||||
user = c.getCurrentUser()
|
user = c.getCurrentUser()
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := application.GetEmailProvider()
|
provider := application.GetEmailProvider()
|
||||||
sendResp = object.SendVerificationCodeToEmail(organization, user, provider, remoteAddr, dest)
|
sendResp = object.SendVerificationCodeToEmail(organization, user, provider, remoteAddr, vform.Dest)
|
||||||
case object.VerifyTypePhone:
|
case object.VerifyTypePhone:
|
||||||
if method == LoginVerification || method == ForgetVerification {
|
if vform.Method == LoginVerification || vform.Method == ForgetVerification {
|
||||||
if user != nil && util.GetMaskedPhone(user.Phone) == dest {
|
if user != nil && util.GetMaskedPhone(user.Phone) == vform.Dest {
|
||||||
dest = user.Phone
|
vform.Dest = user.Phone
|
||||||
}
|
}
|
||||||
|
|
||||||
if user = object.GetUserByPhone(organization.Name, dest); user == nil {
|
if user = object.GetUserByPhone(organization.Name, vform.Dest); user == nil {
|
||||||
c.ResponseError(c.T("verification:the user does not exist, please sign up first"))
|
c.ResponseError(c.T("verification:the user does not exist, please sign up first"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
countryCode = user.GetCountryCode(countryCode)
|
vform.CountryCode = user.GetCountryCode(vform.CountryCode)
|
||||||
} else if method == ResetVerification {
|
} else if vform.Method == ResetVerification {
|
||||||
if user = c.getCurrentUser(); user != nil {
|
if user = c.getCurrentUser(); user != nil {
|
||||||
countryCode = user.GetCountryCode(countryCode)
|
vform.CountryCode = user.GetCountryCode(vform.CountryCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := application.GetSmsProvider()
|
provider := application.GetSmsProvider()
|
||||||
if phone, ok := util.GetE164Number(dest, countryCode); !ok {
|
if phone, ok := util.GetE164Number(vform.Dest, vform.CountryCode); !ok {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), countryCode))
|
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), vform.CountryCode))
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
sendResp = object.SendVerificationCodeToPhone(organization, user, provider, remoteAddr, phone)
|
sendResp = object.SendVerificationCodeToPhone(organization, user, provider, remoteAddr, phone)
|
||||||
@ -167,6 +137,38 @@ func (c *ApiController) SendVerificationCode() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VerifyCaptcha ...
|
||||||
|
// @Title VerifyCaptcha
|
||||||
|
// @Tag Verification API
|
||||||
|
// @router /verify-captcha [post]
|
||||||
|
func (c *ApiController) VerifyCaptcha() {
|
||||||
|
var vform form.VerificationForm
|
||||||
|
err := c.ParseForm(&vform)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if msg := vform.CheckParameter(form.VerifyCaptcha, c.GetAcceptLanguage()); msg != "" {
|
||||||
|
c.ResponseError(msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
provider := captcha.GetCaptchaProvider(vform.CaptchaType)
|
||||||
|
if provider == nil {
|
||||||
|
c.ResponseError(c.T("verification:Invalid captcha provider."))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isValid, err := provider.VerifyCaptcha(vform.CaptchaToken, vform.ClientSecret)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.ResponseOk(isValid)
|
||||||
|
}
|
||||||
|
|
||||||
// ResetEmailOrPhone ...
|
// ResetEmailOrPhone ...
|
||||||
// @Tag Account API
|
// @Tag Account API
|
||||||
// @Title ResetEmailOrPhone
|
// @Title ResetEmailOrPhone
|
||||||
@ -200,7 +202,7 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pass, errMsg := object.CheckAccountItemModifyRule(phoneItem, user, c.GetAcceptLanguage()); !pass {
|
if pass, errMsg := object.CheckAccountItemModifyRule(phoneItem, user.IsAdminUser(), c.GetAcceptLanguage()); !pass {
|
||||||
c.ResponseError(errMsg)
|
c.ResponseError(errMsg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -220,11 +222,12 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pass, errMsg := object.CheckAccountItemModifyRule(emailItem, user, c.GetAcceptLanguage()); !pass {
|
if pass, errMsg := object.CheckAccountItemModifyRule(emailItem, user.IsAdminUser(), c.GetAcceptLanguage()); !pass {
|
||||||
c.ResponseError(errMsg)
|
c.ResponseError(errMsg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if result := object.CheckVerificationCode(checkDest, code, c.GetAcceptLanguage()); result.Code != object.VerificationSuccess {
|
if result := object.CheckVerificationCode(checkDest, code, c.GetAcceptLanguage()); result.Code != object.VerificationSuccess {
|
||||||
c.ResponseError(result.Msg)
|
c.ResponseError(result.Msg)
|
||||||
return
|
return
|
||||||
@ -247,88 +250,55 @@ func (c *ApiController) ResetEmailOrPhone() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VerifyCode
|
// VerifyCode
|
||||||
// @Tag Account API
|
// @Tag Verification API
|
||||||
// @Title VerifyCode
|
// @Title VerifyCode
|
||||||
// @router /api/verify-code [post]
|
// @router /api/verify-code [post]
|
||||||
func (c *ApiController) VerifyCode() {
|
func (c *ApiController) VerifyCode() {
|
||||||
var form RequestForm
|
var authForm form.AuthForm
|
||||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &form)
|
err := json.Unmarshal(c.Ctx.Input.RequestBody, &authForm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var user *object.User
|
var user *object.User
|
||||||
if form.Name != "" {
|
if authForm.Name != "" {
|
||||||
user = object.GetUserByFields(form.Organization, form.Name)
|
user = object.GetUserByFields(authForm.Organization, authForm.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkDest string
|
var checkDest string
|
||||||
if strings.Contains(form.Username, "@") {
|
if strings.Contains(authForm.Username, "@") {
|
||||||
if user != nil && util.GetMaskedEmail(user.Email) == form.Username {
|
if user != nil && util.GetMaskedEmail(user.Email) == authForm.Username {
|
||||||
form.Username = user.Email
|
authForm.Username = user.Email
|
||||||
}
|
}
|
||||||
checkDest = form.Username
|
checkDest = authForm.Username
|
||||||
} else {
|
} else {
|
||||||
if user != nil && util.GetMaskedPhone(user.Phone) == form.Username {
|
if user != nil && util.GetMaskedPhone(user.Phone) == authForm.Username {
|
||||||
form.Username = user.Phone
|
authForm.Username = user.Phone
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if user = object.GetUserByFields(form.Organization, form.Username); user == nil {
|
if user = object.GetUserByFields(authForm.Organization, authForm.Username); user == nil {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
|
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(authForm.Organization, authForm.Username)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationCodeType := object.GetVerifyType(form.Username)
|
verificationCodeType := object.GetVerifyType(authForm.Username)
|
||||||
if verificationCodeType == object.VerifyTypePhone {
|
if verificationCodeType == object.VerifyTypePhone {
|
||||||
form.CountryCode = user.GetCountryCode(form.CountryCode)
|
authForm.CountryCode = user.GetCountryCode(authForm.CountryCode)
|
||||||
var ok bool
|
var ok bool
|
||||||
if checkDest, ok = util.GetE164Number(form.Username, form.CountryCode); !ok {
|
if checkDest, ok = util.GetE164Number(authForm.Username, authForm.CountryCode); !ok {
|
||||||
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), form.CountryCode))
|
c.ResponseError(fmt.Sprintf(c.T("verification:Phone number is invalid in your region %s"), authForm.CountryCode))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if result := object.CheckVerificationCode(checkDest, form.Code, c.GetAcceptLanguage()); result.Code != object.VerificationSuccess {
|
if result := object.CheckVerificationCode(checkDest, authForm.Code, c.GetAcceptLanguage()); result.Code != object.VerificationSuccess {
|
||||||
c.ResponseError(result.Msg)
|
c.ResponseError(result.Msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
object.DisableVerificationCode(checkDest)
|
object.DisableVerificationCode(checkDest)
|
||||||
c.SetSession("verifiedCode", form.Code)
|
c.SetSession("verifiedCode", authForm.Code)
|
||||||
|
|
||||||
c.ResponseOk()
|
c.ResponseOk()
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyCaptcha ...
|
|
||||||
// @Title VerifyCaptcha
|
|
||||||
// @Tag Verification API
|
|
||||||
// @router /verify-captcha [post]
|
|
||||||
func (c *ApiController) VerifyCaptcha() {
|
|
||||||
captchaType := c.Ctx.Request.Form.Get("captchaType")
|
|
||||||
|
|
||||||
captchaToken := c.Ctx.Request.Form.Get("captchaToken")
|
|
||||||
clientSecret := c.Ctx.Request.Form.Get("clientSecret")
|
|
||||||
if captchaToken == "" {
|
|
||||||
c.ResponseError(c.T("general:Missing parameter") + ": captchaToken.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if clientSecret == "" {
|
|
||||||
c.ResponseError(c.T("general:Missing parameter") + ": clientSecret.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
provider := captcha.GetCaptchaProvider(captchaType)
|
|
||||||
if provider == nil {
|
|
||||||
c.ResponseError(c.T("verification:Invalid captcha provider."))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
isValid, err := provider.VerifyCaptcha(captchaToken, clientSecret)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
c.ResponseOk(isValid)
|
|
||||||
}
|
|
||||||
|
@ -19,6 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/form"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/go-webauthn/webauthn/protocol"
|
"github.com/go-webauthn/webauthn/protocol"
|
||||||
@ -147,9 +148,9 @@ func (c *ApiController) WebAuthnSigninFinish() {
|
|||||||
util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
|
util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
|
||||||
|
|
||||||
application := object.GetApplicationByUser(user)
|
application := object.GetApplicationByUser(user)
|
||||||
var form RequestForm
|
var authForm form.AuthForm
|
||||||
form.Type = responseType
|
authForm.Type = responseType
|
||||||
resp := c.HandleLoggedIn(application, user, &form)
|
resp := c.HandleLoggedIn(application, user, &authForm)
|
||||||
c.Data["json"] = resp
|
c.Data["json"] = resp
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
53
form/auth.go
Normal file
53
form/auth.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package form
|
||||||
|
|
||||||
|
type AuthForm struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
|
||||||
|
Organization string `json:"organization"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
FirstName string `json:"firstName"`
|
||||||
|
LastName string `json:"lastName"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Phone string `json:"phone"`
|
||||||
|
Affiliation string `json:"affiliation"`
|
||||||
|
IdCard string `json:"idCard"`
|
||||||
|
Region string `json:"region"`
|
||||||
|
|
||||||
|
Application string `json:"application"`
|
||||||
|
ClientId string `json:"clientId"`
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
Code string `json:"code"`
|
||||||
|
State string `json:"state"`
|
||||||
|
RedirectUri string `json:"redirectUri"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
|
||||||
|
EmailCode string `json:"emailCode"`
|
||||||
|
PhoneCode string `json:"phoneCode"`
|
||||||
|
CountryCode string `json:"countryCode"`
|
||||||
|
|
||||||
|
AutoSignin bool `json:"autoSignin"`
|
||||||
|
|
||||||
|
RelayState string `json:"relayState"`
|
||||||
|
SamlRequest string `json:"samlRequest"`
|
||||||
|
SamlResponse string `json:"samlResponse"`
|
||||||
|
|
||||||
|
CaptchaType string `json:"captchaType"`
|
||||||
|
CaptchaToken string `json:"captchaToken"`
|
||||||
|
ClientSecret string `json:"clientSecret"`
|
||||||
|
}
|
67
form/verification.go
Normal file
67
form/verification.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package form
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/i18n"
|
||||||
|
)
|
||||||
|
|
||||||
|
type VerificationForm struct {
|
||||||
|
Dest string `form:"dest"`
|
||||||
|
Type string `form:"type"`
|
||||||
|
CountryCode string `form:"countryCode"`
|
||||||
|
ApplicationId string `form:"applicationId"`
|
||||||
|
Method string `form:"method"`
|
||||||
|
CheckUser string `form:"checkUser"`
|
||||||
|
|
||||||
|
CaptchaType string `form:"captchaType"`
|
||||||
|
ClientSecret string `form:"clientSecret"`
|
||||||
|
CaptchaToken string `form:"captchaToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
SendVerifyCode = 0
|
||||||
|
VerifyCaptcha = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
func (form *VerificationForm) CheckParameter(checkType int, lang string) string {
|
||||||
|
if checkType == SendVerifyCode {
|
||||||
|
if form.Type == "" {
|
||||||
|
return i18n.Translate(lang, "general:Missing parameter") + ": type."
|
||||||
|
}
|
||||||
|
if form.Dest == "" {
|
||||||
|
return i18n.Translate(lang, "general:Missing parameter") + ": dest."
|
||||||
|
}
|
||||||
|
if form.CaptchaType == "" {
|
||||||
|
return i18n.Translate(lang, "general:Missing parameter") + ": checkType."
|
||||||
|
}
|
||||||
|
if !strings.Contains(form.ApplicationId, "/") {
|
||||||
|
return i18n.Translate(lang, "verification:Wrong parameter") + ": applicationId."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if form.CaptchaType != "none" {
|
||||||
|
if form.CaptchaToken == "" {
|
||||||
|
return i18n.Translate(lang, "general:Missing parameter") + ": captchaToken."
|
||||||
|
}
|
||||||
|
if form.ClientSecret == "" {
|
||||||
|
return i18n.Translate(lang, "general:Missing parameter") + ": clientSecret."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
@ -22,6 +22,7 @@ import (
|
|||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/cred"
|
"github.com/casdoor/casdoor/cred"
|
||||||
|
"github.com/casdoor/casdoor/form"
|
||||||
"github.com/casdoor/casdoor/i18n"
|
"github.com/casdoor/casdoor/i18n"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
goldap "github.com/go-ldap/ldap/v3"
|
goldap "github.com/go-ldap/ldap/v3"
|
||||||
@ -42,86 +43,86 @@ func init() {
|
|||||||
reFieldWhiteList, _ = regexp.Compile(`^[A-Za-z0-9]+$`)
|
reFieldWhiteList, _ = regexp.Compile(`^[A-Za-z0-9]+$`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, firstName string, lastName string, email string, phone string, countryCode string, affiliation string, lang string) string {
|
func CheckUserSignup(application *Application, organization *Organization, form *form.AuthForm, lang string) string {
|
||||||
if organization == nil {
|
if organization == nil {
|
||||||
return i18n.Translate(lang, "check:Organization does not exist")
|
return i18n.Translate(lang, "check:Organization does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Username") {
|
if application.IsSignupItemVisible("Username") {
|
||||||
if len(username) <= 1 {
|
if len(form.Username) <= 1 {
|
||||||
return i18n.Translate(lang, "check:Username must have at least 2 characters")
|
return i18n.Translate(lang, "check:Username must have at least 2 characters")
|
||||||
}
|
}
|
||||||
if unicode.IsDigit(rune(username[0])) {
|
if unicode.IsDigit(rune(form.Username[0])) {
|
||||||
return i18n.Translate(lang, "check:Username cannot start with a digit")
|
return i18n.Translate(lang, "check:Username cannot start with a digit")
|
||||||
}
|
}
|
||||||
if util.IsEmailValid(username) {
|
if util.IsEmailValid(form.Username) {
|
||||||
return i18n.Translate(lang, "check:Username cannot be an email address")
|
return i18n.Translate(lang, "check:Username cannot be an email address")
|
||||||
}
|
}
|
||||||
if reWhiteSpace.MatchString(username) {
|
if reWhiteSpace.MatchString(form.Username) {
|
||||||
return i18n.Translate(lang, "check:Username cannot contain white spaces")
|
return i18n.Translate(lang, "check:Username cannot contain white spaces")
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg := CheckUsername(username, lang); msg != "" {
|
if msg := CheckUsername(form.Username, lang); msg != "" {
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
if HasUserByField(organization.Name, "name", username) {
|
if HasUserByField(organization.Name, "name", form.Username) {
|
||||||
return i18n.Translate(lang, "check:Username already exists")
|
return i18n.Translate(lang, "check:Username already exists")
|
||||||
}
|
}
|
||||||
if HasUserByField(organization.Name, "email", email) {
|
if HasUserByField(organization.Name, "email", form.Email) {
|
||||||
return i18n.Translate(lang, "check:Email already exists")
|
return i18n.Translate(lang, "check:Email already exists")
|
||||||
}
|
}
|
||||||
if HasUserByField(organization.Name, "phone", phone) {
|
if HasUserByField(organization.Name, "phone", form.Phone) {
|
||||||
return i18n.Translate(lang, "check:Phone already exists")
|
return i18n.Translate(lang, "check:Phone already exists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(password) <= 5 {
|
if len(form.Password) <= 5 {
|
||||||
return i18n.Translate(lang, "check:Password must have at least 6 characters")
|
return i18n.Translate(lang, "check:Password must have at least 6 characters")
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Email") {
|
if application.IsSignupItemVisible("Email") {
|
||||||
if email == "" {
|
if form.Email == "" {
|
||||||
if application.IsSignupItemRequired("Email") {
|
if application.IsSignupItemRequired("Email") {
|
||||||
return i18n.Translate(lang, "check:Email cannot be empty")
|
return i18n.Translate(lang, "check:Email cannot be empty")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if HasUserByField(organization.Name, "email", email) {
|
if HasUserByField(organization.Name, "email", form.Email) {
|
||||||
return i18n.Translate(lang, "check:Email already exists")
|
return i18n.Translate(lang, "check:Email already exists")
|
||||||
} else if !util.IsEmailValid(email) {
|
} else if !util.IsEmailValid(form.Email) {
|
||||||
return i18n.Translate(lang, "check:Email is invalid")
|
return i18n.Translate(lang, "check:Email is invalid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Phone") {
|
if application.IsSignupItemVisible("Phone") {
|
||||||
if phone == "" {
|
if form.Phone == "" {
|
||||||
if application.IsSignupItemRequired("Phone") {
|
if application.IsSignupItemRequired("Phone") {
|
||||||
return i18n.Translate(lang, "check:Phone cannot be empty")
|
return i18n.Translate(lang, "check:Phone cannot be empty")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if HasUserByField(organization.Name, "phone", phone) {
|
if HasUserByField(organization.Name, "phone", form.Phone) {
|
||||||
return i18n.Translate(lang, "check:Phone already exists")
|
return i18n.Translate(lang, "check:Phone already exists")
|
||||||
} else if !util.IsPhoneAllowInRegin(countryCode, organization.CountryCodes) {
|
} else if !util.IsPhoneAllowInRegin(form.CountryCode, organization.CountryCodes) {
|
||||||
return i18n.Translate(lang, "check:Your region is not allow to signup by phone")
|
return i18n.Translate(lang, "check:Your region is not allow to signup by phone")
|
||||||
} else if !util.IsPhoneValid(phone, countryCode) {
|
} else if !util.IsPhoneValid(form.Phone, form.CountryCode) {
|
||||||
return i18n.Translate(lang, "check:Phone number is invalid")
|
return i18n.Translate(lang, "check:Phone number is invalid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Display name") {
|
if application.IsSignupItemVisible("Display name") {
|
||||||
if application.GetSignupItemRule("Display name") == "First, last" && (firstName != "" || lastName != "") {
|
if application.GetSignupItemRule("Display name") == "First, last" && (form.FirstName != "" || form.LastName != "") {
|
||||||
if firstName == "" {
|
if form.FirstName == "" {
|
||||||
return i18n.Translate(lang, "check:FirstName cannot be blank")
|
return i18n.Translate(lang, "check:FirstName cannot be blank")
|
||||||
} else if lastName == "" {
|
} else if form.LastName == "" {
|
||||||
return i18n.Translate(lang, "check:LastName cannot be blank")
|
return i18n.Translate(lang, "check:LastName cannot be blank")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if displayName == "" {
|
if form.Name == "" {
|
||||||
return i18n.Translate(lang, "check:DisplayName cannot be blank")
|
return i18n.Translate(lang, "check:DisplayName cannot be blank")
|
||||||
} else if application.GetSignupItemRule("Display name") == "Real name" {
|
} else if application.GetSignupItemRule("Display name") == "Real name" {
|
||||||
if !isValidRealName(displayName) {
|
if !isValidRealName(form.Name) {
|
||||||
return i18n.Translate(lang, "check:DisplayName is not valid real name")
|
return i18n.Translate(lang, "check:DisplayName is not valid real name")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -129,7 +130,7 @@ func CheckUserSignup(application *Application, organization *Organization, usern
|
|||||||
}
|
}
|
||||||
|
|
||||||
if application.IsSignupItemVisible("Affiliation") {
|
if application.IsSignupItemVisible("Affiliation") {
|
||||||
if affiliation == "" {
|
if form.Affiliation == "" {
|
||||||
return i18n.Translate(lang, "check:Affiliation cannot be blank")
|
return i18n.Translate(lang, "check:Affiliation cannot be blank")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,14 +209,14 @@ func GetAccountItemByName(name string, organization *Organization) *AccountItem
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckAccountItemModifyRule(accountItem *AccountItem, user *User, lang string) (bool, string) {
|
func CheckAccountItemModifyRule(accountItem *AccountItem, isAdmin bool, lang string) (bool, string) {
|
||||||
if accountItem == nil {
|
if accountItem == nil {
|
||||||
return true, ""
|
return true, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
switch accountItem.ModifyRule {
|
switch accountItem.ModifyRule {
|
||||||
case "Admin":
|
case "Admin":
|
||||||
if user == nil || !user.IsAdmin && !user.IsGlobalAdmin {
|
if isAdmin {
|
||||||
return false, fmt.Sprintf(i18n.Translate(lang, "organization:Only admin can modify the %s."), accountItem.Name)
|
return false, fmt.Sprintf(i18n.Translate(lang, "organization:Only admin can modify the %s."), accountItem.Name)
|
||||||
}
|
}
|
||||||
case "Immutable":
|
case "Immutable":
|
||||||
|
@ -425,7 +425,7 @@ func GetLastUser(owner string) *User {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateUser(id string, user *User, columns []string, isGlobalAdmin bool) bool {
|
func UpdateUser(id string, user *User, columns []string, isAdmin bool) bool {
|
||||||
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
|
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
|
||||||
oldUser := getUser(owner, name)
|
oldUser := getUser(owner, name)
|
||||||
if oldUser == nil {
|
if oldUser == nil {
|
||||||
@ -456,7 +456,7 @@ func UpdateUser(id string, user *User, columns []string, isGlobalAdmin bool) boo
|
|||||||
"signin_wrong_times", "last_signin_wrong_time",
|
"signin_wrong_times", "last_signin_wrong_time",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if isGlobalAdmin {
|
if isAdmin {
|
||||||
columns = append(columns, "name", "email", "phone", "country_code")
|
columns = append(columns, "name", "email", "phone", "country_code")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
@ -179,6 +180,116 @@ func ClearUserOAuthProperties(user *User, providerType string) bool {
|
|||||||
return affected != 0
|
return affected != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, lang string) (bool, string) {
|
||||||
|
organization := GetOrganizationByUser(oldUser)
|
||||||
|
var itemsChanged []*AccountItem
|
||||||
|
|
||||||
|
if oldUser.Owner != newUser.Owner {
|
||||||
|
item := GetAccountItemByName("Organization", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Name != newUser.Name {
|
||||||
|
item := GetAccountItemByName("Name", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Id != newUser.Id {
|
||||||
|
item := GetAccountItemByName("ID", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.DisplayName != newUser.DisplayName {
|
||||||
|
item := GetAccountItemByName("Display name", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Avatar != newUser.Avatar {
|
||||||
|
item := GetAccountItemByName("Avatar", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Type != newUser.Type {
|
||||||
|
item := GetAccountItemByName("User type", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
// The password is *** when not modified
|
||||||
|
if oldUser.Password != newUser.Password && newUser.Password != "***" {
|
||||||
|
item := GetAccountItemByName("Password", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Email != newUser.Email {
|
||||||
|
item := GetAccountItemByName("Email", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Phone != newUser.Phone {
|
||||||
|
item := GetAccountItemByName("Phone", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.CountryCode != newUser.CountryCode {
|
||||||
|
item := GetAccountItemByName("Country code", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Region != newUser.Region {
|
||||||
|
item := GetAccountItemByName("Country/Region", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Location != newUser.Location {
|
||||||
|
item := GetAccountItemByName("Location", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Affiliation != newUser.Affiliation {
|
||||||
|
item := GetAccountItemByName("Affiliation", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Title != newUser.Title {
|
||||||
|
item := GetAccountItemByName("Title", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Homepage != newUser.Homepage {
|
||||||
|
item := GetAccountItemByName("Homepage", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Bio != newUser.Bio {
|
||||||
|
item := GetAccountItemByName("Bio", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.Tag != newUser.Tag {
|
||||||
|
item := GetAccountItemByName("Tag", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.SignupApplication != newUser.SignupApplication {
|
||||||
|
item := GetAccountItemByName("Signup application", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
oldUserPropertiesJson, _ := json.Marshal(oldUser.Properties)
|
||||||
|
newUserPropertiesJson, _ := json.Marshal(newUser.Properties)
|
||||||
|
if string(oldUserPropertiesJson) != string(newUserPropertiesJson) {
|
||||||
|
item := GetAccountItemByName("Properties", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldUser.IsAdmin != newUser.IsAdmin {
|
||||||
|
item := GetAccountItemByName("Is admin", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.IsGlobalAdmin != newUser.IsGlobalAdmin {
|
||||||
|
item := GetAccountItemByName("Is global admin", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.IsForbidden != newUser.IsForbidden {
|
||||||
|
item := GetAccountItemByName("Is forbidden", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
if oldUser.IsDeleted != newUser.IsDeleted {
|
||||||
|
item := GetAccountItemByName("Is deleted", organization)
|
||||||
|
itemsChanged = append(itemsChanged, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range itemsChanged {
|
||||||
|
if pass, err := CheckAccountItemModifyRule(itemsChanged[i], isAdmin, lang); !pass {
|
||||||
|
return pass, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true, ""
|
||||||
|
}
|
||||||
|
|
||||||
func (user *User) GetCountryCode(countryCode string) string {
|
func (user *User) GetCountryCode(countryCode string) string {
|
||||||
if countryCode != "" {
|
if countryCode != "" {
|
||||||
return countryCode
|
return countryCode
|
||||||
@ -193,3 +304,11 @@ func (user *User) GetCountryCode(countryCode string) string {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (user *User) IsAdminUser() bool {
|
||||||
|
if user == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.IsAdmin || user.IsGlobalAdmin
|
||||||
|
}
|
||||||
|
@ -551,15 +551,33 @@
|
|||||||
"operationId": "ApiController.GetCaptcha"
|
"operationId": "ApiController.GetCaptcha"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/api/get-webhook-event": {
|
"/api/api/get-captcha-status": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"GetCaptchaStatus API"
|
"Token API"
|
||||||
],
|
],
|
||||||
"operationId": "ApiController.GetCaptchaStatus"
|
"description": "Get Login Error Counts",
|
||||||
|
"operationId": "ApiController.GetCaptchaStatus",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "id",
|
||||||
|
"description": "The id ( owner/name ) of user",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "The Response object",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controllers.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/api/get-captcha-status": {
|
"/api/api/get-webhook-event": {
|
||||||
"get": {
|
"get": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"GetWebhookEventType API"
|
"GetWebhookEventType API"
|
||||||
@ -662,7 +680,7 @@
|
|||||||
"/api/api/verify-code": {
|
"/api/api/verify-code": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"Account API"
|
"Verification API"
|
||||||
],
|
],
|
||||||
"operationId": "ApiController.VerifyCode"
|
"operationId": "ApiController.VerifyCode"
|
||||||
}
|
}
|
||||||
@ -2752,7 +2770,7 @@
|
|||||||
"description": "Login information",
|
"description": "Login information",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/definitions/controllers.RequestForm"
|
"$ref": "#/definitions/controllers.AuthForm"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -3891,11 +3909,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"2306.0xc0004a1410.false": {
|
"1183.0xc000455050.false": {
|
||||||
"title": "false",
|
"title": "false",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
"2340.0xc0004a1440.false": {
|
"1217.0xc000455080.false": {
|
||||||
"title": "false",
|
"title": "false",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
@ -3907,6 +3925,10 @@
|
|||||||
"title": "Response",
|
"title": "Response",
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"controllers.AuthForm": {
|
||||||
|
"title": "AuthForm",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"controllers.EmailForm": {
|
"controllers.EmailForm": {
|
||||||
"title": "EmailForm",
|
"title": "EmailForm",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -3931,108 +3953,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"controllers.RequestForm": {
|
|
||||||
"title": "RequestForm",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"affiliation": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"application": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"autoSignin": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"captchaToken": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"captchaType": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"clientId": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"clientSecret": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"code": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"countryCode": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"email": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"emailCode": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"firstName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"idCard": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"lastName": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"method": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"organization": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"password": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"phone": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"phoneCode": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"provider": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"redirectUri": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"region": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"relayState": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"samlRequest": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"samlResponse": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"username": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"controllers.Response": {
|
"controllers.Response": {
|
||||||
"title": "Response",
|
"title": "Response",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"$ref": "#/definitions/2306.0xc0004a1410.false"
|
"$ref": "#/definitions/1183.0xc000455050.false"
|
||||||
},
|
},
|
||||||
"data2": {
|
"data2": {
|
||||||
"$ref": "#/definitions/2340.0xc0004a1440.false"
|
"$ref": "#/definitions/1217.0xc000455080.false"
|
||||||
},
|
},
|
||||||
"msg": {
|
"msg": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -355,16 +355,28 @@ paths:
|
|||||||
tags:
|
tags:
|
||||||
- Login API
|
- Login API
|
||||||
operationId: ApiController.GetCaptcha
|
operationId: ApiController.GetCaptcha
|
||||||
|
/api/api/get-captcha-status:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Token API
|
||||||
|
description: Get Login Error Counts
|
||||||
|
operationId: ApiController.GetCaptchaStatus
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: id
|
||||||
|
description: The id ( owner/name ) of user
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The Response object
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/controllers.Response'
|
||||||
/api/api/get-webhook-event:
|
/api/api/get-webhook-event:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
- GetWebhookEventType API
|
- GetWebhookEventType API
|
||||||
operationId: ApiController.GetWebhookEventType
|
operationId: ApiController.GetWebhookEventType
|
||||||
/api/api/get-captcha-status:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- GetCaptchaStatus API
|
|
||||||
operationId: ApiController.GetCaptchaStatus
|
|
||||||
/api/api/reset-email-or-phone:
|
/api/api/reset-email-or-phone:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@ -429,7 +441,7 @@ paths:
|
|||||||
/api/api/verify-code:
|
/api/api/verify-code:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- Account API
|
- Verification API
|
||||||
operationId: ApiController.VerifyCode
|
operationId: ApiController.VerifyCode
|
||||||
/api/api/webhook:
|
/api/api/webhook:
|
||||||
post:
|
post:
|
||||||
@ -1798,7 +1810,7 @@ paths:
|
|||||||
description: Login information
|
description: Login information
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/controllers.RequestForm'
|
$ref: '#/definitions/controllers.AuthForm'
|
||||||
responses:
|
responses:
|
||||||
"200":
|
"200":
|
||||||
description: The Response object
|
description: The Response object
|
||||||
@ -2543,10 +2555,10 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/Response'
|
$ref: '#/definitions/Response'
|
||||||
definitions:
|
definitions:
|
||||||
2306.0xc0004a1410.false:
|
1183.0xc000455050.false:
|
||||||
title: "false"
|
title: "false"
|
||||||
type: object
|
type: object
|
||||||
2340.0xc0004a1440.false:
|
1217.0xc000455080.false:
|
||||||
title: "false"
|
title: "false"
|
||||||
type: object
|
type: object
|
||||||
LaravelResponse:
|
LaravelResponse:
|
||||||
@ -2555,6 +2567,9 @@ definitions:
|
|||||||
Response:
|
Response:
|
||||||
title: Response
|
title: Response
|
||||||
type: object
|
type: object
|
||||||
|
controllers.AuthForm:
|
||||||
|
title: AuthForm
|
||||||
|
type: object
|
||||||
controllers.EmailForm:
|
controllers.EmailForm:
|
||||||
title: EmailForm
|
title: EmailForm
|
||||||
type: object
|
type: object
|
||||||
@ -2571,76 +2586,14 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
title:
|
title:
|
||||||
type: string
|
type: string
|
||||||
controllers.RequestForm:
|
|
||||||
title: RequestForm
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
affiliation:
|
|
||||||
type: string
|
|
||||||
application:
|
|
||||||
type: string
|
|
||||||
autoSignin:
|
|
||||||
type: boolean
|
|
||||||
captchaToken:
|
|
||||||
type: string
|
|
||||||
captchaType:
|
|
||||||
type: string
|
|
||||||
clientId:
|
|
||||||
type: string
|
|
||||||
clientSecret:
|
|
||||||
type: string
|
|
||||||
code:
|
|
||||||
type: string
|
|
||||||
countryCode:
|
|
||||||
type: string
|
|
||||||
email:
|
|
||||||
type: string
|
|
||||||
emailCode:
|
|
||||||
type: string
|
|
||||||
firstName:
|
|
||||||
type: string
|
|
||||||
idCard:
|
|
||||||
type: string
|
|
||||||
lastName:
|
|
||||||
type: string
|
|
||||||
method:
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
organization:
|
|
||||||
type: string
|
|
||||||
password:
|
|
||||||
type: string
|
|
||||||
phone:
|
|
||||||
type: string
|
|
||||||
phoneCode:
|
|
||||||
type: string
|
|
||||||
provider:
|
|
||||||
type: string
|
|
||||||
redirectUri:
|
|
||||||
type: string
|
|
||||||
region:
|
|
||||||
type: string
|
|
||||||
relayState:
|
|
||||||
type: string
|
|
||||||
samlRequest:
|
|
||||||
type: string
|
|
||||||
samlResponse:
|
|
||||||
type: string
|
|
||||||
state:
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
type: string
|
|
||||||
username:
|
|
||||||
type: string
|
|
||||||
controllers.Response:
|
controllers.Response:
|
||||||
title: Response
|
title: Response
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
data:
|
data:
|
||||||
$ref: '#/definitions/2306.0xc0004a1410.false'
|
$ref: '#/definitions/1183.0xc000455050.false'
|
||||||
data2:
|
data2:
|
||||||
$ref: '#/definitions/2340.0xc0004a1440.false'
|
$ref: '#/definitions/1217.0xc000455080.false'
|
||||||
msg:
|
msg:
|
||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as AdapterBackend from "./backend/AdapterBackend";
|
import * as AdapterBackend from "./backend/AdapterBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class AdapterListPage extends BaseListPage {
|
class AdapterListPage extends BaseListPage {
|
||||||
newAdapter() {
|
newAdapter() {
|
||||||
|
@ -21,7 +21,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
import * as ApplicationBackend from "./backend/ApplicationBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class ApplicationListPage extends BaseListPage {
|
class ApplicationListPage extends BaseListPage {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as CertBackend from "./backend/CertBackend";
|
import * as CertBackend from "./backend/CertBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class CertListPage extends BaseListPage {
|
class CertListPage extends BaseListPage {
|
||||||
newCert() {
|
newCert() {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as ChatBackend from "./backend/ChatBackend";
|
import * as ChatBackend from "./backend/ChatBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class ChatListPage extends BaseListPage {
|
class ChatListPage extends BaseListPage {
|
||||||
newChat() {
|
newChat() {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as MessageBackend from "./backend/MessageBackend";
|
import * as MessageBackend from "./backend/MessageBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class MessageListPage extends BaseListPage {
|
class MessageListPage extends BaseListPage {
|
||||||
newMessage() {
|
newMessage() {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as ModelBackend from "./backend/ModelBackend";
|
import * as ModelBackend from "./backend/ModelBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class ModelListPage extends BaseListPage {
|
class ModelListPage extends BaseListPage {
|
||||||
newModel() {
|
newModel() {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class OrganizationListPage extends BaseListPage {
|
class OrganizationListPage extends BaseListPage {
|
||||||
newOrganization() {
|
newOrganization() {
|
||||||
|
@ -21,7 +21,7 @@ import * as PaymentBackend from "./backend/PaymentBackend";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import * as Provider from "./auth/Provider";
|
import * as Provider from "./auth/Provider";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class PaymentListPage extends BaseListPage {
|
class PaymentListPage extends BaseListPage {
|
||||||
newPayment() {
|
newPayment() {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as PermissionBackend from "./backend/PermissionBackend";
|
import * as PermissionBackend from "./backend/PermissionBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class PermissionListPage extends BaseListPage {
|
class PermissionListPage extends BaseListPage {
|
||||||
newPermission() {
|
newPermission() {
|
||||||
|
@ -21,7 +21,7 @@ import * as ProductBackend from "./backend/ProductBackend";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import {EditOutlined} from "@ant-design/icons";
|
import {EditOutlined} from "@ant-design/icons";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class ProductListPage extends BaseListPage {
|
class ProductListPage extends BaseListPage {
|
||||||
newProduct() {
|
newProduct() {
|
||||||
|
@ -21,7 +21,7 @@ import * as ProviderBackend from "./backend/ProviderBackend";
|
|||||||
import * as Provider from "./auth/Provider";
|
import * as Provider from "./auth/Provider";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class ProviderListPage extends BaseListPage {
|
class ProviderListPage extends BaseListPage {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -21,7 +21,7 @@ import * as ResourceBackend from "./backend/ResourceBackend";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class ResourceListPage extends BaseListPage {
|
class ResourceListPage extends BaseListPage {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as RoleBackend from "./backend/RoleBackend";
|
import * as RoleBackend from "./backend/RoleBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class RoleListPage extends BaseListPage {
|
class RoleListPage extends BaseListPage {
|
||||||
newRole() {
|
newRole() {
|
||||||
|
@ -19,7 +19,7 @@ import {Link} from "react-router-dom";
|
|||||||
import {Table, Tag} from "antd";
|
import {Table, Tag} from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import * as SessionBackend from "./backend/SessionBackend";
|
import * as SessionBackend from "./backend/SessionBackend";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class SessionListPage extends BaseListPage {
|
class SessionListPage extends BaseListPage {
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as SyncerBackend from "./backend/SyncerBackend";
|
import * as SyncerBackend from "./backend/SyncerBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class SyncerListPage extends BaseListPage {
|
class SyncerListPage extends BaseListPage {
|
||||||
newSyncer() {
|
newSyncer() {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as TokenBackend from "./backend/TokenBackend";
|
import * as TokenBackend from "./backend/TokenBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class TokenListPage extends BaseListPage {
|
class TokenListPage extends BaseListPage {
|
||||||
newToken() {
|
newToken() {
|
||||||
|
@ -22,7 +22,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as UserBackend from "./backend/UserBackend";
|
import * as UserBackend from "./backend/UserBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class UserListPage extends BaseListPage {
|
class UserListPage extends BaseListPage {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -20,7 +20,7 @@ import * as Setting from "./Setting";
|
|||||||
import * as WebhookBackend from "./backend/WebhookBackend";
|
import * as WebhookBackend from "./backend/WebhookBackend";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import BaseListPage from "./BaseListPage";
|
import BaseListPage from "./BaseListPage";
|
||||||
import PopconfirmModal from "./PopconfirmModal";
|
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class WebhookListPage extends BaseListPage {
|
class WebhookListPage extends BaseListPage {
|
||||||
newWebhook() {
|
newWebhook() {
|
||||||
|
@ -113,9 +113,9 @@ export function setPassword(userOwner, userName, oldPassword, newPassword, code
|
|||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendCode(checkType, captchaToken, clientSecret, method, countryCode = "", dest, type, applicationId, checkUser = "") {
|
export function sendCode(captchaType, captchaToken, clientSecret, method, countryCode = "", dest, type, applicationId, checkUser = "") {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("checkType", checkType);
|
formData.append("captchaType", captchaType);
|
||||||
formData.append("captchaToken", captchaToken);
|
formData.append("captchaToken", captchaToken);
|
||||||
formData.append("clientSecret", clientSecret);
|
formData.append("clientSecret", clientSecret);
|
||||||
formData.append("method", method);
|
formData.append("method", method);
|
||||||
|
@ -18,7 +18,7 @@ import * as Setting from "../Setting";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import * as LdapBackend from "../backend/LdapBackend";
|
import * as LdapBackend from "../backend/LdapBackend";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import PopconfirmModal from "../PopconfirmModal";
|
import PopconfirmModal from "../common/modal/PopconfirmModal";
|
||||||
|
|
||||||
class LdapTable extends React.Component {
|
class LdapTable extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user