mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-23 14:33:28 +08:00
Compare commits
48 Commits
Author | SHA1 | Date | |
---|---|---|---|
55d5ae10f2 | |||
6986dad295 | |||
949feb18af | |||
d1f88ca9b8 | |||
bfe8e5f3e7 | |||
702ee6acd0 | |||
0a9587901a | |||
577bd6ce58 | |||
3c4112dd44 | |||
b7a37126ad | |||
8669d5bb0d | |||
aee3ea4981 | |||
516f4b7569 | |||
7d7ca10481 | |||
a9d4978a0f | |||
09f40bb5ce | |||
a6f803aff1 | |||
fc9528be43 | |||
58e8f9f90b | |||
e850e33f37 | |||
d7110ff8bf | |||
f923a8f0d7 | |||
7bfb74ba18 | |||
38f031bc86 | |||
5c441d195c | |||
0639564d27 | |||
6c647818ca | |||
8bc73d17aa | |||
1f37c80177 | |||
7924fca403 | |||
bd06996bab | |||
19ab168b12 | |||
854a74b73e | |||
beefb0b432 | |||
d8969e6652 | |||
666ff48837 | |||
0a0c1b4788 | |||
438c999e11 | |||
a193ceb33d | |||
caec1d1bac | |||
0d48da24dc | |||
de9eeaa1ef | |||
ae6e35ee73 | |||
a58df645bf | |||
68417a2d7a | |||
9511fae9d9 | |||
347d3d2b53 | |||
6edfc08b28 |
2
ai/ai.go
2
ai/ai.go
@ -129,7 +129,7 @@ func QueryAnswerStream(authToken string, question string, writer io.Writer, buil
|
||||
fmt.Printf("%s", data)
|
||||
|
||||
// Write the streamed data as Server-Sent Events
|
||||
if _, err = fmt.Fprintf(writer, "data: %s\n\n", data); err != nil {
|
||||
if _, err = fmt.Fprintf(writer, "event: message\ndata: %s\n\n", data); err != nil {
|
||||
return err
|
||||
}
|
||||
flusher.Flush()
|
||||
|
@ -368,9 +368,11 @@ func (c *ApiController) GetAccount() {
|
||||
return
|
||||
}
|
||||
|
||||
user.Permissions = object.GetMaskedPermissions(user.Permissions)
|
||||
user.Roles = object.GetMaskedRoles(user.Roles)
|
||||
user.MultiFactorAuths = object.GetAllMfaProps(user, true)
|
||||
if user != nil {
|
||||
user.Permissions = object.GetMaskedPermissions(user.Permissions)
|
||||
user.Roles = object.GetMaskedRoles(user.Roles)
|
||||
user.MultiFactorAuths = object.GetAllMfaProps(user, true)
|
||||
}
|
||||
|
||||
organization, err := object.GetMaskedOrganization(object.GetOrganizationByUser(user))
|
||||
if err != nil {
|
||||
@ -378,7 +380,8 @@ func (c *ApiController) GetAccount() {
|
||||
return
|
||||
}
|
||||
|
||||
u, err := object.GetMaskedUser(user)
|
||||
isAdminOrSelf := c.IsAdminOrSelf(user)
|
||||
u, err := object.GetMaskedUser(user, isAdminOrSelf)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
@ -48,14 +48,11 @@ func (c *ApiController) GetApplications() {
|
||||
} else {
|
||||
applications, err = object.GetOrganizationApplications(owner, organization)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedApplications(applications, userId)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetMaskedApplications(applications, userId))
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetApplicationCount(owner, field, value)
|
||||
@ -86,14 +83,14 @@ func (c *ApiController) GetApplications() {
|
||||
func (c *ApiController) GetApplication() {
|
||||
userId := c.GetSessionUsername()
|
||||
id := c.Input().Get("id")
|
||||
|
||||
app, err := object.GetApplication(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedApplication(app, userId)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetMaskedApplication(app, userId))
|
||||
}
|
||||
|
||||
// GetUserApplication
|
||||
@ -106,25 +103,24 @@ func (c *ApiController) GetApplication() {
|
||||
func (c *ApiController) GetUserApplication() {
|
||||
userId := c.GetSessionUsername()
|
||||
id := c.Input().Get("id")
|
||||
|
||||
user, err := object.GetUser(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), id))
|
||||
return
|
||||
}
|
||||
|
||||
app, err := object.GetApplicationByUser(user)
|
||||
application, err := object.GetApplicationByUser(user)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedApplication(app, userId)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetMaskedApplication(application, userId))
|
||||
}
|
||||
|
||||
// GetOrganizationApplications
|
||||
@ -157,8 +153,7 @@ func (c *ApiController) GetOrganizationApplications() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedApplications(applications, userId)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetMaskedApplications(applications, userId))
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
|
||||
|
@ -78,12 +78,6 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
}
|
||||
}
|
||||
|
||||
if form.Password != "" && user.IsMfaEnabled() {
|
||||
c.setMfaSessionData(&object.MfaSessionData{UserId: userId})
|
||||
resp = &Response{Status: object.NextMfa, Data: user.GetPreferredMfaProps(true)}
|
||||
return
|
||||
}
|
||||
|
||||
if form.Type == ResponseTypeLogin {
|
||||
c.SetSessionUsername(userId)
|
||||
util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
|
||||
@ -129,6 +123,11 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
return
|
||||
}
|
||||
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: map[string]string{"redirectUrl": redirectUrl, "method": method}}
|
||||
|
||||
if application.EnableSigninSession || application.HasPromptPage() {
|
||||
// The prompt page needs the user to be signed in
|
||||
c.SetSessionUsername(userId)
|
||||
}
|
||||
} else if form.Type == ResponseTypeCas {
|
||||
// not oauth but CAS SSO protocol
|
||||
service := c.Input().Get("service")
|
||||
@ -141,11 +140,11 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
resp.Data = st
|
||||
}
|
||||
}
|
||||
|
||||
if application.EnableSigninSession || application.HasPromptPage() {
|
||||
// The prompt page needs the user to be signed in
|
||||
c.SetSessionUsername(userId)
|
||||
}
|
||||
|
||||
} else {
|
||||
resp = wrapErrorResponse(fmt.Errorf("unknown response type: %s", form.Type))
|
||||
}
|
||||
@ -353,17 +352,26 @@ func (c *ApiController) Login() {
|
||||
return
|
||||
}
|
||||
|
||||
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||
|
||||
organization, err := object.GetOrganizationByUser(user)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
}
|
||||
|
||||
if user != nil && organization.HasRequiredMfa() && !user.IsMfaEnabled() {
|
||||
resp.Msg = object.RequiredMfa
|
||||
if object.IsNeedPromptMfa(organization, user) {
|
||||
// The prompt page needs the user to be signed in
|
||||
c.SetSessionUsername(user.GetId())
|
||||
c.ResponseOk(object.RequiredMfa)
|
||||
return
|
||||
}
|
||||
|
||||
if user.IsMfaEnabled() {
|
||||
c.setMfaUserSession(user.GetId())
|
||||
c.ResponseOk(object.NextMfa, user.GetPreferredMfaProps(true))
|
||||
return
|
||||
}
|
||||
|
||||
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||
|
||||
record := object.NewRecord(c.Ctx)
|
||||
record.Organization = application.Organization
|
||||
record.User = user.Name
|
||||
@ -414,7 +422,7 @@ func (c *ApiController) Login() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if provider.Category == "OAuth" {
|
||||
} else if provider.Category == "OAuth" || provider.Category == "Web3" {
|
||||
// OAuth
|
||||
idpInfo := object.FromProviderToIdpInfo(c.Ctx, provider)
|
||||
idProvider := idp.GetIdProvider(idpInfo, authForm.RedirectUri)
|
||||
@ -457,7 +465,7 @@ func (c *ApiController) Login() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if provider.Category == "OAuth" {
|
||||
} else if provider.Category == "OAuth" || provider.Category == "Web3" {
|
||||
user, err = object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
@ -478,7 +486,7 @@ func (c *ApiController) Login() {
|
||||
record.Organization = application.Organization
|
||||
record.User = user.Name
|
||||
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||
} else if provider.Category == "OAuth" {
|
||||
} else if provider.Category == "OAuth" || provider.Category == "Web3" {
|
||||
// Sign up via OAuth
|
||||
if application.EnableLinkWithEmail {
|
||||
if userInfo.Email != "" {
|
||||
@ -649,13 +657,16 @@ func (c *ApiController) Login() {
|
||||
resp = &Response{Status: "error", Msg: "Failed to link user account", Data: isLinked}
|
||||
}
|
||||
}
|
||||
} else if c.getMfaSessionData() != nil {
|
||||
mfaSession := c.getMfaSessionData()
|
||||
user, err := object.GetUser(mfaSession.UserId)
|
||||
} else if c.getMfaUserSession() != "" {
|
||||
user, err := object.GetUser(c.getMfaUserSession())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if user == nil {
|
||||
c.ResponseError("expired user session")
|
||||
return
|
||||
}
|
||||
|
||||
if authForm.Passcode != "" {
|
||||
mfaUtil := object.GetMfaUtil(authForm.MfaType, user.GetPreferredMfaProps(false))
|
||||
@ -669,13 +680,15 @@ func (c *ApiController) Login() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
if authForm.RecoveryCode != "" {
|
||||
} else if authForm.RecoveryCode != "" {
|
||||
err = object.MfaRecover(user, authForm.RecoveryCode)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.ResponseError("missing passcode or recovery code")
|
||||
return
|
||||
}
|
||||
|
||||
application, err := object.GetApplication(fmt.Sprintf("admin/%s", authForm.Application))
|
||||
@ -690,6 +703,7 @@ func (c *ApiController) Login() {
|
||||
}
|
||||
|
||||
resp = c.HandleLoggedIn(application, user, &authForm)
|
||||
c.setMfaUserSession("")
|
||||
|
||||
record := object.NewRecord(c.Ctx)
|
||||
record.Organization = application.Organization
|
||||
|
@ -55,6 +55,18 @@ func (c *ApiController) IsAdmin() bool {
|
||||
return isGlobalAdmin || user.IsAdmin
|
||||
}
|
||||
|
||||
func (c *ApiController) IsAdminOrSelf(user2 *object.User) bool {
|
||||
isGlobalAdmin, user := c.isGlobalAdmin()
|
||||
if isGlobalAdmin || (user != nil && user.IsAdmin) {
|
||||
return true
|
||||
}
|
||||
|
||||
if user.Owner == user2.Owner && user.Name == user2.Name {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *ApiController) isGlobalAdmin() (bool, *object.User) {
|
||||
username := c.GetSessionUsername()
|
||||
if strings.HasPrefix(username, "app/") {
|
||||
@ -178,24 +190,16 @@ func (c *ApiController) SetSessionData(s *SessionData) {
|
||||
c.SetSession("SessionData", util.StructToJson(s))
|
||||
}
|
||||
|
||||
func (c *ApiController) setMfaSessionData(data *object.MfaSessionData) {
|
||||
if data == nil {
|
||||
c.SetSession(object.MfaSessionUserId, nil)
|
||||
return
|
||||
}
|
||||
c.SetSession(object.MfaSessionUserId, data.UserId)
|
||||
func (c *ApiController) setMfaUserSession(userId string) {
|
||||
c.SetSession(object.MfaSessionUserId, userId)
|
||||
}
|
||||
|
||||
func (c *ApiController) getMfaSessionData() *object.MfaSessionData {
|
||||
userId := c.GetSession(object.MfaSessionUserId)
|
||||
func (c *ApiController) getMfaUserSession() string {
|
||||
userId := c.Ctx.Input.CruSession.Get(object.MfaSessionUserId)
|
||||
if userId == nil {
|
||||
return nil
|
||||
return ""
|
||||
}
|
||||
|
||||
data := &object.MfaSessionData{
|
||||
UserId: userId.(string),
|
||||
}
|
||||
return data
|
||||
return userId.(string)
|
||||
}
|
||||
|
||||
func (c *ApiController) setExpireForSession() {
|
||||
|
226
controllers/casbin_api.go
Normal file
226
controllers/casbin_api.go
Normal file
@ -0,0 +1,226 @@
|
||||
// Copyright 2022 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"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// Enforce
|
||||
// @Title Enforce
|
||||
// @Tag Enforce API
|
||||
// @Description Call Casbin Enforce API
|
||||
// @Param body body object.CasbinRequest true "Casbin request"
|
||||
// @Param permissionId query string false "permission id"
|
||||
// @Param modelId query string false "model id"
|
||||
// @Param resourceId query string false "resource id"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /enforce [post]
|
||||
func (c *ApiController) Enforce() {
|
||||
permissionId := c.Input().Get("permissionId")
|
||||
modelId := c.Input().Get("modelId")
|
||||
resourceId := c.Input().Get("resourceId")
|
||||
|
||||
var request object.CasbinRequest
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &request)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if permissionId != "" {
|
||||
permission, err := object.GetPermission(permissionId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res := []bool{}
|
||||
|
||||
if permission == nil {
|
||||
res = append(res, false)
|
||||
} else {
|
||||
enforceResult, err := object.Enforce(permission, &request)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
return
|
||||
}
|
||||
|
||||
permissions := []*object.Permission{}
|
||||
if modelId != "" {
|
||||
owner, modelName := util.GetOwnerAndNameFromId(modelId)
|
||||
permissions, err = object.GetPermissionsByModel(owner, modelName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if resourceId != "" {
|
||||
permissions, err = object.GetPermissionsByResource(resourceId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
res := []bool{}
|
||||
|
||||
listPermissionIdMap := object.GroupPermissionsByModelAdapter(permissions)
|
||||
for _, permissionIds := range listPermissionIdMap {
|
||||
firstPermission, err := object.GetPermission(permissionIds[0])
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
enforceResult, err := object.Enforce(firstPermission, &request, permissionIds...)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
}
|
||||
|
||||
// BatchEnforce
|
||||
// @Title BatchEnforce
|
||||
// @Tag Enforce API
|
||||
// @Description Call Casbin BatchEnforce API
|
||||
// @Param body body object.CasbinRequest true "array of casbin requests"
|
||||
// @Param permissionId query string false "permission id"
|
||||
// @Param modelId query string false "model id"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /batch-enforce [post]
|
||||
func (c *ApiController) BatchEnforce() {
|
||||
permissionId := c.Input().Get("permissionId")
|
||||
modelId := c.Input().Get("modelId")
|
||||
|
||||
var requests []object.CasbinRequest
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &requests)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if permissionId != "" {
|
||||
permission, err := object.GetPermission(permissionId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res := [][]bool{}
|
||||
|
||||
if permission == nil {
|
||||
l := len(requests)
|
||||
resRequest := make([]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
resRequest[i] = false
|
||||
}
|
||||
|
||||
res = append(res, resRequest)
|
||||
} else {
|
||||
enforceResult, err := object.BatchEnforce(permission, &requests)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
return
|
||||
}
|
||||
|
||||
permissions := []*object.Permission{}
|
||||
if modelId != "" {
|
||||
owner, modelName := util.GetOwnerAndNameFromId(modelId)
|
||||
permissions, err = object.GetPermissionsByModel(owner, modelName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
res := [][]bool{}
|
||||
|
||||
listPermissionIdMap := object.GroupPermissionsByModelAdapter(permissions)
|
||||
for _, permissionIds := range listPermissionIdMap {
|
||||
firstPermission, err := object.GetPermission(permissionIds[0])
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
enforceResult, err := object.BatchEnforce(firstPermission, &requests, permissionIds...)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllObjects() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllObjects(userId))
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllActions() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllActions(userId))
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllRoles() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllRoles(userId))
|
||||
}
|
@ -45,8 +45,7 @@ func (c *ApiController) GetCerts() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedCerts
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedCerts)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetCertCount(owner, field, value)
|
||||
@ -87,8 +86,7 @@ func (c *ApiController) GetGlobleCerts() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedCerts
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedCerts)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetGlobalCertsCount(field, value)
|
||||
@ -123,8 +121,7 @@ func (c *ApiController) GetCert() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedCert(cert)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetMaskedCert(cert))
|
||||
}
|
||||
|
||||
// UpdateCert
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetChats() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedChats
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedChats)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetChatCount(owner, field, value)
|
||||
@ -82,8 +81,7 @@ func (c *ApiController) GetChat() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedChat
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedChat)
|
||||
}
|
||||
|
||||
// UpdateChat
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
|
||||
// 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.
|
||||
@ -17,210 +17,129 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// Enforce
|
||||
// @Title Enforce
|
||||
// @Tag Enforce API
|
||||
// @Description Call Casbin Enforce API
|
||||
// @Param body body object.CasbinRequest true "Casbin request"
|
||||
// @Param permissionId query string false "permission id"
|
||||
// @Param modelId query string false "model id"
|
||||
// @Param resourceId query string false "resource id"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /enforce [post]
|
||||
func (c *ApiController) Enforce() {
|
||||
permissionId := c.Input().Get("permissionId")
|
||||
modelId := c.Input().Get("modelId")
|
||||
resourceId := c.Input().Get("resourceId")
|
||||
// GetEnforcers
|
||||
// @Title GetEnforcers
|
||||
// @Tag Enforcer API
|
||||
// @Description get enforcers
|
||||
// @Param owner query string true "The owner of enforcers"
|
||||
// @Success 200 {array} object.Enforcer
|
||||
// @router /get-enforcers [get]
|
||||
func (c *ApiController) GetEnforcers() {
|
||||
owner := c.Input().Get("owner")
|
||||
limit := c.Input().Get("pageSize")
|
||||
page := c.Input().Get("p")
|
||||
field := c.Input().Get("field")
|
||||
value := c.Input().Get("value")
|
||||
sortField := c.Input().Get("sortField")
|
||||
sortOrder := c.Input().Get("sortOrder")
|
||||
|
||||
var request object.CasbinRequest
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &request)
|
||||
if limit == "" || page == "" {
|
||||
enforcers, err := object.GetEnforcers(owner)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(enforcers)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetEnforcerCount(owner, field, value)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, count)
|
||||
enforcers, err := object.GetPaginationEnforcers(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(enforcers)
|
||||
}
|
||||
}
|
||||
|
||||
// GetEnforcer
|
||||
// @Title GetEnforcer
|
||||
// @Tag Enforcer API
|
||||
// @Description get enforcer
|
||||
// @Param id query string true "The id ( owner/name ) of enforcer"
|
||||
// @Success 200 {object} object
|
||||
// @router /get-enforcer [get]
|
||||
func (c *ApiController) GetEnforcer() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
enforcer, err := object.GetEnforcer(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if permissionId != "" {
|
||||
permission, err := object.GetPermission(permissionId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res := []bool{}
|
||||
|
||||
if permission == nil {
|
||||
res = append(res, false)
|
||||
} else {
|
||||
enforceResult, err := object.Enforce(permission, &request)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
return
|
||||
}
|
||||
|
||||
permissions := []*object.Permission{}
|
||||
if modelId != "" {
|
||||
owner, modelName := util.GetOwnerAndNameFromId(modelId)
|
||||
permissions, err = object.GetPermissionsByModel(owner, modelName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if resourceId != "" {
|
||||
permissions, err = object.GetPermissionsByResource(resourceId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
res := []bool{}
|
||||
|
||||
listPermissionIdMap := object.GroupPermissionsByModelAdapter(permissions)
|
||||
for _, permissionIds := range listPermissionIdMap {
|
||||
firstPermission, err := object.GetPermission(permissionIds[0])
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
enforceResult, err := object.Enforce(firstPermission, &request, permissionIds...)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
c.ResponseOk(enforcer)
|
||||
}
|
||||
|
||||
// BatchEnforce
|
||||
// @Title BatchEnforce
|
||||
// @Tag Enforce API
|
||||
// @Description Call Casbin BatchEnforce API
|
||||
// @Param body body object.CasbinRequest true "array of casbin requests"
|
||||
// @Param permissionId query string false "permission id"
|
||||
// @Param modelId query string false "model id"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /batch-enforce [post]
|
||||
func (c *ApiController) BatchEnforce() {
|
||||
permissionId := c.Input().Get("permissionId")
|
||||
modelId := c.Input().Get("modelId")
|
||||
// UpdateEnforcer
|
||||
// @Title UpdateEnforcer
|
||||
// @Tag Enforcer API
|
||||
// @Description update enforcer
|
||||
// @Param id query string true "The id ( owner/name ) of enforcer"
|
||||
// @Param enforcer body object true "The enforcer object"
|
||||
// @Success 200 {object} object
|
||||
// @router /update-enforcer [post]
|
||||
func (c *ApiController) UpdateEnforcer() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var requests []object.CasbinRequest
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &requests)
|
||||
enforcer := object.Enforcer{}
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &enforcer)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if permissionId != "" {
|
||||
permission, err := object.GetPermission(permissionId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res := [][]bool{}
|
||||
|
||||
if permission == nil {
|
||||
l := len(requests)
|
||||
resRequest := make([]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
resRequest[i] = false
|
||||
}
|
||||
|
||||
res = append(res, resRequest)
|
||||
} else {
|
||||
enforceResult, err := object.BatchEnforce(permission, &requests)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
return
|
||||
}
|
||||
|
||||
permissions := []*object.Permission{}
|
||||
if modelId != "" {
|
||||
owner, modelName := util.GetOwnerAndNameFromId(modelId)
|
||||
permissions, err = object.GetPermissionsByModel(owner, modelName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
res := [][]bool{}
|
||||
|
||||
listPermissionIdMap := object.GroupPermissionsByModelAdapter(permissions)
|
||||
for _, permissionIds := range listPermissionIdMap {
|
||||
firstPermission, err := object.GetPermission(permissionIds[0])
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
enforceResult, err := object.BatchEnforce(firstPermission, &requests, permissionIds...)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateEnforcer(id, &enforcer))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllObjects() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
// AddEnforcer
|
||||
// @Title AddEnforcer
|
||||
// @Tag Enforcer API
|
||||
// @Description add enforcer
|
||||
// @Param enforcer body object true "The enforcer object"
|
||||
// @Success 200 {object} object
|
||||
// @router /add-enforcer [post]
|
||||
func (c *ApiController) AddEnforcer() {
|
||||
enforcer := object.Enforcer{}
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &enforcer)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllObjects(userId))
|
||||
c.Data["json"] = wrapActionResponse(object.AddEnforcer(&enforcer))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllActions() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
// DeleteEnforcer
|
||||
// @Title DeleteEnforcer
|
||||
// @Tag Enforcer API
|
||||
// @Description delete enforcer
|
||||
// @Param body body object.Enforce true "The enforcer object"
|
||||
// @Success 200 {object} object
|
||||
// @router /delete-enforcer [post]
|
||||
func (c *ApiController) DeleteEnforcer() {
|
||||
var enforcer object.Enforcer
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &enforcer)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllActions(userId))
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllRoles() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllRoles(userId))
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteEnforcer(&enforcer))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -82,9 +82,9 @@ func (c *ApiController) GetGroup() {
|
||||
group, err := object.GetGroup(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
} else {
|
||||
c.ResponseOk(group)
|
||||
return
|
||||
}
|
||||
c.ResponseOk(group)
|
||||
}
|
||||
|
||||
// UpdateGroup
|
||||
|
@ -38,8 +38,11 @@ type LdapSyncResp struct {
|
||||
}
|
||||
|
||||
// GetLdapUsers
|
||||
// @Tag Account API
|
||||
// @Title GetLdapser
|
||||
// @Tag Account API
|
||||
// @Description get ldap users
|
||||
// Param id string true "id"
|
||||
// @Success 200 {object} LdapResp The Response object
|
||||
// @router /get-ldap-users [get]
|
||||
func (c *ApiController) GetLdapUsers() {
|
||||
id := c.Input().Get("id")
|
||||
@ -94,18 +97,24 @@ func (c *ApiController) GetLdapUsers() {
|
||||
}
|
||||
|
||||
// GetLdaps
|
||||
// @Tag Account API
|
||||
// @Title GetLdaps
|
||||
// @Tag Account API
|
||||
// @Description get ldaps
|
||||
// @Param owner query string false "owner"
|
||||
// @Success 200 {array} object.Ldap The Response object
|
||||
// @router /get-ldaps [get]
|
||||
func (c *ApiController) GetLdaps() {
|
||||
owner := c.Input().Get("owner")
|
||||
|
||||
c.ResponseOk(object.GetLdaps(owner))
|
||||
c.ResponseOk(object.GetMaskedLdaps(object.GetLdaps(owner)))
|
||||
}
|
||||
|
||||
// GetLdap
|
||||
// @Tag Account API
|
||||
// @Title GetLdap
|
||||
// @Tag Account API
|
||||
// @Description get ldap
|
||||
// @Param id query string true "id"
|
||||
// @Success 200 {object} object.Ldap The Response object
|
||||
// @router /get-ldap [get]
|
||||
func (c *ApiController) GetLdap() {
|
||||
id := c.Input().Get("id")
|
||||
@ -116,12 +125,20 @@ func (c *ApiController) GetLdap() {
|
||||
}
|
||||
|
||||
_, name := util.GetOwnerAndNameFromId(id)
|
||||
c.ResponseOk(object.GetLdap(name))
|
||||
ldap, err := object.GetLdap(name)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.ResponseOk(object.GetMaskedLdap(ldap))
|
||||
}
|
||||
|
||||
// AddLdap
|
||||
// @Tag Account API
|
||||
// @Title AddLdap
|
||||
// @Tag Account API
|
||||
// @Description add ldap
|
||||
// @Param body body object.Ldap true "The details of the ldap"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /add-ldap [post]
|
||||
func (c *ApiController) AddLdap() {
|
||||
var ldap object.Ldap
|
||||
@ -160,8 +177,11 @@ func (c *ApiController) AddLdap() {
|
||||
}
|
||||
|
||||
// UpdateLdap
|
||||
// @Tag Account API
|
||||
// @Title UpdateLdap
|
||||
// @Tag Account API
|
||||
// @Description update ldap
|
||||
// @Param body body object.Ldap true "The details of the ldap"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /update-ldap [post]
|
||||
func (c *ApiController) UpdateLdap() {
|
||||
var ldap object.Ldap
|
||||
@ -198,8 +218,11 @@ func (c *ApiController) UpdateLdap() {
|
||||
}
|
||||
|
||||
// DeleteLdap
|
||||
// @Tag Account API
|
||||
// @Title DeleteLdap
|
||||
// @Tag Account API
|
||||
// @Description delete ldap
|
||||
// @Param body body object.Ldap true "The details of the ldap"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /delete-ldap [post]
|
||||
func (c *ApiController) DeleteLdap() {
|
||||
var ldap object.Ldap
|
||||
@ -222,12 +245,16 @@ func (c *ApiController) DeleteLdap() {
|
||||
}
|
||||
|
||||
// SyncLdapUsers
|
||||
// @Tag Account API
|
||||
// @Title SyncLdapUsers
|
||||
// @Tag Account API
|
||||
// @Description sync ldap users
|
||||
// @Param id query string true "id"
|
||||
// @Success 200 {object} LdapSyncResp The Response object
|
||||
// @router /sync-ldap-users [post]
|
||||
func (c *ApiController) SyncLdapUsers() {
|
||||
owner := c.Input().Get("owner")
|
||||
ldapId := c.Input().Get("ldapId")
|
||||
id := c.Input().Get("id")
|
||||
|
||||
owner, ldapId := util.GetOwnerAndNameFromId(id)
|
||||
var users []object.LdapUser
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &users)
|
||||
if err != nil {
|
||||
|
@ -57,8 +57,7 @@ func (c *ApiController) GetMessages() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedMessages(messages)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetMaskedMessages(messages))
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetMessageCount(owner, organization, field, value)
|
||||
@ -94,8 +93,7 @@ func (c *ApiController) GetMessage() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedMessage(message)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(message)
|
||||
}
|
||||
|
||||
func (c *ApiController) ResponseErrorStream(errorText string) {
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetModels() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = models
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(models)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetModelCount(owner, field, value)
|
||||
@ -82,8 +81,7 @@ func (c *ApiController) GetModel() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = model
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(model)
|
||||
}
|
||||
|
||||
// UpdateModel
|
||||
|
@ -55,8 +55,7 @@ func (c *ApiController) GetOrganizations() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedOrganizations
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedOrganizations)
|
||||
} else {
|
||||
if !isGlobalAdmin {
|
||||
maskedOrganizations, err := object.GetMaskedOrganizations(object.GetOrganizations(owner, c.getCurrentUser().Owner))
|
||||
@ -184,6 +183,8 @@ func (c *ApiController) DeleteOrganization() {
|
||||
func (c *ApiController) GetDefaultApplication() {
|
||||
userId := c.GetSessionUsername()
|
||||
id := c.Input().Get("id")
|
||||
redirectUri := c.Input().Get("redirectUri")
|
||||
typ := c.Input().Get("type")
|
||||
|
||||
application, err := object.GetDefaultApplication(id)
|
||||
if err != nil {
|
||||
@ -191,6 +192,14 @@ func (c *ApiController) GetDefaultApplication() {
|
||||
return
|
||||
}
|
||||
|
||||
if typ == "cas" {
|
||||
err = object.CheckCasRestrict(application, c.GetAcceptLanguage(), redirectUri)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
maskedApplication := object.GetMaskedApplication(application, userId)
|
||||
c.ResponseOk(maskedApplication)
|
||||
}
|
||||
|
@ -46,8 +46,7 @@ func (c *ApiController) GetPayments() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = payments
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(payments)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetPaymentCount(owner, organization, field, value)
|
||||
@ -106,8 +105,7 @@ func (c *ApiController) GetPayment() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = payment
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(payment)
|
||||
}
|
||||
|
||||
// UpdatePayment
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetPermissions() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = permissions
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(permissions)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetPermissionCount(owner, field, value)
|
||||
@ -85,7 +84,6 @@ func (c *ApiController) GetPermissionsBySubmitter() {
|
||||
}
|
||||
|
||||
c.ResponseOk(permissions, len(permissions))
|
||||
return
|
||||
}
|
||||
|
||||
// GetPermissionsByRole
|
||||
@ -104,7 +102,6 @@ func (c *ApiController) GetPermissionsByRole() {
|
||||
}
|
||||
|
||||
c.ResponseOk(permissions, len(permissions))
|
||||
return
|
||||
}
|
||||
|
||||
// GetPermission
|
||||
@ -123,8 +120,7 @@ func (c *ApiController) GetPermission() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = permission
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(permission)
|
||||
}
|
||||
|
||||
// UpdatePermission
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetPlans() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = plans
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(plans)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetPlanCount(owner, field, value)
|
||||
@ -95,11 +94,10 @@ func (c *ApiController) GetPlan() {
|
||||
plan.Options = append(plan.Options, option.DisplayName)
|
||||
}
|
||||
|
||||
c.Data["json"] = plan
|
||||
c.ResponseOk(plan)
|
||||
} else {
|
||||
c.Data["json"] = plan
|
||||
c.ResponseOk(plan)
|
||||
}
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdatePlan
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetPricings() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = pricings
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(pricings)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetPricingCount(owner, field, value)
|
||||
@ -82,8 +81,7 @@ func (c *ApiController) GetPricing() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = pricing
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(pricing)
|
||||
}
|
||||
|
||||
// UpdatePricing
|
||||
|
@ -46,8 +46,7 @@ func (c *ApiController) GetProducts() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = products
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(products)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetProductCount(owner, field, value)
|
||||
@ -89,8 +88,7 @@ func (c *ApiController) GetProduct() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = product
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(product)
|
||||
}
|
||||
|
||||
// UpdateProduct
|
||||
|
@ -51,8 +51,7 @@ func (c *ApiController) GetRecords() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = records
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(records)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
if c.IsGlobalAdmin() && organizationName != "" {
|
||||
@ -99,8 +98,7 @@ func (c *ApiController) GetRecordsByFilter() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = records
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(records)
|
||||
}
|
||||
|
||||
// AddRecord
|
||||
|
@ -29,9 +29,19 @@ import (
|
||||
)
|
||||
|
||||
// GetResources
|
||||
// @router /get-resources [get]
|
||||
// @Tag Resource API
|
||||
// @Title GetResources
|
||||
// @Description get resources
|
||||
// @Param owner query string true "Owner"
|
||||
// @Param user query string true "User"
|
||||
// @Param pageSize query integer false "Page Size"
|
||||
// @Param p query integer false "Page Number"
|
||||
// @Param field query string false "Field"
|
||||
// @Param value query string false "Value"
|
||||
// @Param sortField query string false "Sort Field"
|
||||
// @Param sortOrder query string false "Sort Order"
|
||||
// @Success 200 {array} object.Resource The Response object
|
||||
// @router /get-resources [get]
|
||||
func (c *ApiController) GetResources() {
|
||||
owner := c.Input().Get("owner")
|
||||
user := c.Input().Get("user")
|
||||
@ -57,8 +67,7 @@ func (c *ApiController) GetResources() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = resources
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(resources)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetResourceCount(owner, user, field, value)
|
||||
@ -81,6 +90,9 @@ func (c *ApiController) GetResources() {
|
||||
// GetResource
|
||||
// @Tag Resource API
|
||||
// @Title GetResource
|
||||
// @Description get resource
|
||||
// @Param id query string true "The id ( owner/name ) of resource"
|
||||
// @Success 200 {object} object.Resource The Response object
|
||||
// @router /get-resource [get]
|
||||
func (c *ApiController) GetResource() {
|
||||
id := c.Input().Get("id")
|
||||
@ -91,13 +103,16 @@ func (c *ApiController) GetResource() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = resource
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(resource)
|
||||
}
|
||||
|
||||
// UpdateResource
|
||||
// @Tag Resource API
|
||||
// @Title UpdateResource
|
||||
// @Description get resource
|
||||
// @Param id query string true "The id ( owner/name ) of resource"
|
||||
// @Param resource body object.Resource true "The resource object"
|
||||
// @Success 200 {object} controllers.Response Success or error
|
||||
// @router /update-resource [post]
|
||||
func (c *ApiController) UpdateResource() {
|
||||
id := c.Input().Get("id")
|
||||
@ -116,6 +131,8 @@ func (c *ApiController) UpdateResource() {
|
||||
// AddResource
|
||||
// @Tag Resource API
|
||||
// @Title AddResource
|
||||
// @Param resource body object.Resource true "Resource object"
|
||||
// @Success 200 {object} controllers.Response Success or error
|
||||
// @router /add-resource [post]
|
||||
func (c *ApiController) AddResource() {
|
||||
var resource object.Resource
|
||||
@ -132,6 +149,8 @@ func (c *ApiController) AddResource() {
|
||||
// DeleteResource
|
||||
// @Tag Resource API
|
||||
// @Title DeleteResource
|
||||
// @Param resource body object.Resource true "Resource object"
|
||||
// @Success 200 {object} controllers.Response Success or error
|
||||
// @router /delete-resource [post]
|
||||
func (c *ApiController) DeleteResource() {
|
||||
var resource object.Resource
|
||||
@ -160,6 +179,16 @@ func (c *ApiController) DeleteResource() {
|
||||
// UploadResource
|
||||
// @Tag Resource API
|
||||
// @Title UploadResource
|
||||
// @Param owner query string true "Owner"
|
||||
// @Param user query string true "User"
|
||||
// @Param application query string true "Application"
|
||||
// @Param tag query string false "Tag"
|
||||
// @Param parent query string false "Parent"
|
||||
// @Param fullFilePath query string true "Full File Path"
|
||||
// @Param createdTime query string false "Created Time"
|
||||
// @Param description query string false "Description"
|
||||
// @Param file formData file true "Resource file"
|
||||
// @Success 200 {object} object.Resource FileUrl, objectKey
|
||||
// @router /upload-resource [post]
|
||||
func (c *ApiController) UploadResource() {
|
||||
owner := c.Input().Get("owner")
|
||||
@ -198,12 +227,12 @@ func (c *ApiController) UploadResource() {
|
||||
|
||||
fileType := "unknown"
|
||||
contentType := header.Header.Get("Content-Type")
|
||||
fileType, _ = util.GetOwnerAndNameFromId(contentType)
|
||||
fileType, _ = util.GetOwnerAndNameFromIdNoCheck(contentType + "/")
|
||||
|
||||
if fileType != "image" && fileType != "video" {
|
||||
ext := filepath.Ext(filename)
|
||||
mimeType := mime.TypeByExtension(ext)
|
||||
fileType, _ = util.GetOwnerAndNameFromId(mimeType)
|
||||
fileType, _ = util.GetOwnerAndNameFromIdNoCheck(mimeType + "/")
|
||||
}
|
||||
|
||||
fullFilePath = object.GetTruncatedPath(provider, fullFilePath, 175)
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetRoles() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = roles
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(roles)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetRoleCount(owner, field, value)
|
||||
@ -82,8 +81,7 @@ func (c *ApiController) GetRole() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = role
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(role)
|
||||
}
|
||||
|
||||
// UpdateRole
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetSessions() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = sessions
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(sessions)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetSessionCount(owner, field, value)
|
||||
@ -81,8 +80,7 @@ func (c *ApiController) GetSingleSession() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = session
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(session)
|
||||
}
|
||||
|
||||
// UpdateSession
|
||||
@ -161,7 +159,5 @@ func (c *ApiController) IsSessionDuplicated() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = &Response{Status: "ok", Msg: "", Data: isUserSessionDuplicated}
|
||||
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(isUserSessionDuplicated)
|
||||
}
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetSubscriptions() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = subscriptions
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(subscriptions)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetSubscriptionCount(owner, field, value)
|
||||
@ -82,8 +81,7 @@ func (c *ApiController) GetSubscription() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = subscription
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(subscription)
|
||||
}
|
||||
|
||||
// UpdateSubscription
|
||||
|
@ -46,8 +46,7 @@ func (c *ApiController) GetSyncers() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = organizationSyncers
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(organizationSyncers)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetSyncerCount(owner, organization, field, value)
|
||||
@ -83,8 +82,7 @@ func (c *ApiController) GetSyncer() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = syncer
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(syncer)
|
||||
}
|
||||
|
||||
// UpdateSyncer
|
||||
|
@ -47,8 +47,7 @@ func (c *ApiController) GetTokens() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = token
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(token)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetTokenCount(owner, organization, field, value)
|
||||
@ -83,8 +82,7 @@ func (c *ApiController) GetToken() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = token
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(token)
|
||||
}
|
||||
|
||||
// UpdateToken
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetGlobalUsers() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedUsers
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedUsers)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetGlobalUserCount(field, value)
|
||||
@ -106,8 +105,7 @@ func (c *ApiController) GetUsers() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedUsers
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedUsers)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetUserCount(owner, field, value, groupName)
|
||||
@ -198,21 +196,24 @@ func (c *ApiController) GetUser() {
|
||||
return
|
||||
}
|
||||
|
||||
user.MultiFactorAuths = object.GetAllMfaProps(user, true)
|
||||
if user != nil {
|
||||
user.MultiFactorAuths = object.GetAllMfaProps(user, true)
|
||||
}
|
||||
|
||||
err = object.ExtendUserWithRolesAndPermissions(user)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
maskedUser, err := object.GetMaskedUser(user)
|
||||
isAdminOrSelf := c.IsAdminOrSelf(user)
|
||||
maskedUser, err := object.GetMaskedUser(user, isAdminOrSelf)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedUser
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedUser)
|
||||
}
|
||||
|
||||
// UpdateUser
|
||||
@ -509,8 +510,7 @@ func (c *ApiController) GetSortedUsers() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedUsers
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedUsers)
|
||||
}
|
||||
|
||||
// GetUserCount
|
||||
@ -537,8 +537,7 @@ func (c *ApiController) GetUserCount() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = count
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(count)
|
||||
}
|
||||
|
||||
// AddUserkeys
|
||||
|
@ -93,10 +93,9 @@ func (c *ApiController) SendVerificationCode() {
|
||||
}
|
||||
}
|
||||
|
||||
// mfaSessionData != nil, means method is MfaAuthVerification
|
||||
if mfaSessionData := c.getMfaSessionData(); mfaSessionData != nil {
|
||||
user, err = object.GetUser(mfaSessionData.UserId)
|
||||
c.setMfaSessionData(nil)
|
||||
// mfaUserSession != "", means method is MfaAuthVerification
|
||||
if mfaUserSession := c.getMfaUserSession(); mfaUserSession != "" {
|
||||
user, err = object.GetUser(mfaUserSession)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
@ -134,6 +133,8 @@ func (c *ApiController) SendVerificationCode() {
|
||||
if user != nil && util.GetMaskedEmail(mfaProps.Secret) == vform.Dest {
|
||||
vform.Dest = mfaProps.Secret
|
||||
}
|
||||
} else if vform.Method == MfaSetupVerification {
|
||||
c.SetSession(object.MfaDestSession, vform.Dest)
|
||||
}
|
||||
|
||||
provider, err := application.GetEmailProvider()
|
||||
@ -164,6 +165,11 @@ func (c *ApiController) SendVerificationCode() {
|
||||
vform.CountryCode = user.GetCountryCode(vform.CountryCode)
|
||||
}
|
||||
}
|
||||
|
||||
if vform.Method == MfaSetupVerification {
|
||||
c.SetSession(object.MfaCountryCodeSession, vform.CountryCode)
|
||||
c.SetSession(object.MfaDestSession, vform.Dest)
|
||||
}
|
||||
} else if vform.Method == MfaAuthVerification {
|
||||
mfaProps := user.GetPreferredMfaProps(false)
|
||||
if user != nil && util.GetMaskedPhone(mfaProps.Secret) == vform.Dest {
|
||||
@ -187,11 +193,6 @@ func (c *ApiController) SendVerificationCode() {
|
||||
}
|
||||
}
|
||||
|
||||
if vform.Method == MfaSetupVerification {
|
||||
c.SetSession(object.MfaSmsCountryCodeSession, vform.CountryCode)
|
||||
c.SetSession(object.MfaSmsDestSession, vform.Dest)
|
||||
}
|
||||
|
||||
if sendResp != nil {
|
||||
c.ResponseError(sendResp.Error())
|
||||
} else {
|
||||
|
@ -46,8 +46,7 @@ func (c *ApiController) GetWebhooks() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = webhooks
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(webhooks)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetWebhookCount(owner, organization, field, value)
|
||||
@ -84,8 +83,7 @@ func (c *ApiController) GetWebhook() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = webhook
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(webhook)
|
||||
}
|
||||
|
||||
// UpdateWebhook
|
||||
|
@ -25,6 +25,12 @@ import (
|
||||
)
|
||||
|
||||
func TestDeployStaticFiles(t *testing.T) {
|
||||
provider := object.GetProvider(util.GetId("admin", "provider_storage_aliyun_oss"))
|
||||
object.InitConfig()
|
||||
|
||||
provider, err := object.GetProvider(util.GetId("admin", "provider_storage_aliyun_oss"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
deployStaticFiles(provider)
|
||||
}
|
||||
|
2
go.sum
2
go.sum
@ -546,8 +546,6 @@ github.com/russellhaering/goxmldsig v1.2.0 h1:Y6GTTc9Un5hCxSzVz4UIWQ/zuVwDvzJk80
|
||||
github.com/russellhaering/goxmldsig v1.2.0/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sashabaranov/go-openai v1.9.1 h1:3N52HkJKo9Zlo/oe1AVv5ZkCOny0ra58/ACvAxkN3MM=
|
||||
github.com/sashabaranov/go-openai v1.9.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/sashabaranov/go-openai v1.12.0 h1:aRNHH0gtVfrpIaEolD0sWrLLRnYQNK4cH/bIAHwL8Rk=
|
||||
github.com/sashabaranov/go-openai v1.12.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
|
@ -21,15 +21,39 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
const GoogleIdTokenKey = "GoogleIdToken"
|
||||
|
||||
type GoogleIdProvider struct {
|
||||
Client *http.Client
|
||||
Config *oauth2.Config
|
||||
}
|
||||
|
||||
// https://developers.google.com/identity/sign-in/web/backend-auth#calling-the-tokeninfo-endpoint
|
||||
type GoogleIdToken struct {
|
||||
// These six fields are included in all Google ID Tokens.
|
||||
Iss string `json:"iss"` // The issuer, or signer, of the token. For Google-signed ID tokens, this value is https://accounts.google.com.
|
||||
Sub string `json:"sub"` // The subject: the ID that represents the principal making the request.
|
||||
Azp string `json:"azp"` // Optional. Who the token was issued to. Here is the ClientID
|
||||
Aud string `json:"aud"` // The audience of the token. Here is the ClientID
|
||||
Iat string `json:"iat"` // Unix epoch time when the token was issued.
|
||||
Exp string `json:"exp"` // Unix epoch time when the token expires.
|
||||
// These seven fields are only included when the user has granted the "profile" and "email" OAuth scopes to the application.
|
||||
Email string `json:"email"`
|
||||
EmailVerified string `json:"email_verified"`
|
||||
Name string `json:"name"`
|
||||
Picture string `json:"picture"`
|
||||
GivenName string `json:"given_name"`
|
||||
FamilyName string `json:"family_name"`
|
||||
Locale string `json:"locale"`
|
||||
}
|
||||
|
||||
func NewGoogleIdProvider(clientId string, clientSecret string, redirectUrl string) *GoogleIdProvider {
|
||||
idp := &GoogleIdProvider{}
|
||||
|
||||
@ -61,6 +85,25 @@ func (idp *GoogleIdProvider) getConfig() *oauth2.Config {
|
||||
}
|
||||
|
||||
func (idp *GoogleIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
// Obtained the GoogleIdToken through Google OneTap authorization.
|
||||
if strings.HasPrefix(code, GoogleIdTokenKey) {
|
||||
code = strings.TrimPrefix(code, GoogleIdTokenKey+"-")
|
||||
var googleIdToken GoogleIdToken
|
||||
if err := json.Unmarshal([]byte(code), &googleIdToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
expiry := int64(util.ParseInt(googleIdToken.Exp))
|
||||
token := &oauth2.Token{
|
||||
AccessToken: fmt.Sprintf("%v-%v", GoogleIdTokenKey, googleIdToken.Sub),
|
||||
TokenType: "Bearer",
|
||||
Expiry: time.Unix(expiry, 0),
|
||||
}
|
||||
token = token.WithExtra(map[string]interface{}{
|
||||
GoogleIdTokenKey: googleIdToken,
|
||||
})
|
||||
return token, nil
|
||||
}
|
||||
|
||||
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, idp.Client)
|
||||
return idp.Config.Exchange(ctx, code)
|
||||
}
|
||||
@ -88,6 +131,20 @@ type GoogleUserInfo struct {
|
||||
}
|
||||
|
||||
func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
if strings.HasPrefix(token.AccessToken, GoogleIdTokenKey) {
|
||||
googleIdToken, ok := token.Extra(GoogleIdTokenKey).(GoogleIdToken)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid googleIdToken")
|
||||
}
|
||||
userInfo := UserInfo{
|
||||
Id: googleIdToken.Sub,
|
||||
Username: googleIdToken.Email,
|
||||
DisplayName: googleIdToken.Name,
|
||||
Email: googleIdToken.Email,
|
||||
AvatarUrl: googleIdToken.Picture,
|
||||
}
|
||||
return &userInfo, nil
|
||||
}
|
||||
url := fmt.Sprintf("https://www.googleapis.com/oauth2/v2/userinfo?alt=json&access_token=%s", token.AccessToken)
|
||||
resp, err := idp.Client.Get(url)
|
||||
if err != nil {
|
||||
|
80
idp/metamask.go
Normal file
80
idp/metamask.go
Normal file
@ -0,0 +1,80 @@
|
||||
// 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 idp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
const Web3AuthTokenKey = "web3AuthToken"
|
||||
|
||||
type MetaMaskIdProvider struct {
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
type Web3AuthToken struct {
|
||||
Address string `json:"address"`
|
||||
Nonce string `json:"nonce"`
|
||||
CreateAt uint64 `json:"createAt"`
|
||||
TypedData string `json:"typedData"`
|
||||
Signature string `json:"signature"` // signature for typed data
|
||||
}
|
||||
|
||||
func NewMetaMaskIdProvider() *MetaMaskIdProvider {
|
||||
idp := &MetaMaskIdProvider{}
|
||||
return idp
|
||||
}
|
||||
|
||||
func (idp *MetaMaskIdProvider) SetHttpClient(client *http.Client) {
|
||||
idp.Client = client
|
||||
}
|
||||
|
||||
func (idp *MetaMaskIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
web3AuthToken := Web3AuthToken{}
|
||||
if err := json.Unmarshal([]byte(code), &web3AuthToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token := &oauth2.Token{
|
||||
AccessToken: web3AuthToken.Signature,
|
||||
TokenType: "Bearer",
|
||||
Expiry: time.Now().AddDate(0, 1, 0),
|
||||
}
|
||||
|
||||
token = token.WithExtra(map[string]interface{}{
|
||||
Web3AuthTokenKey: web3AuthToken,
|
||||
})
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (idp *MetaMaskIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
// TODO use "github.com/ethereum/go-ethereum" to check address's eth balance or transaction
|
||||
web3AuthToken, ok := token.Extra(Web3AuthTokenKey).(Web3AuthToken)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid web3AuthToken")
|
||||
}
|
||||
userInfo := &UserInfo{
|
||||
Id: web3AuthToken.Address,
|
||||
Username: web3AuthToken.Address,
|
||||
DisplayName: web3AuthToken.Address,
|
||||
AvatarUrl: fmt.Sprintf("metamask:%v", web3AuthToken.Address),
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
@ -109,6 +109,8 @@ func GetIdProvider(idpInfo *ProviderInfo, redirectUrl string) IdProvider {
|
||||
return NewDouyinIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
||||
case "Bilibili":
|
||||
return NewBilibiliIdProvider(idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl)
|
||||
case "MetaMask":
|
||||
return NewMetaMaskIdProvider()
|
||||
default:
|
||||
if isGothSupport(idpInfo.Type) {
|
||||
return NewGothIdProvider(idpInfo.Type, idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
||||
|
@ -34,7 +34,7 @@ func StartLdapServer() {
|
||||
server.Handle(routes)
|
||||
err := server.ListenAndServe("0.0.0.0:" + conf.GetConfigString("ldapServerPort"))
|
||||
if err != nil {
|
||||
return
|
||||
log.Printf("StartLdapServer() failed, ErrMsg = %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
|
2
main.go
2
main.go
@ -39,7 +39,7 @@ func getCreateDatabaseFlag() bool {
|
||||
func main() {
|
||||
createDatabase := getCreateDatabaseFlag()
|
||||
|
||||
object.InitAdapter()
|
||||
object.InitAdapter(createDatabase)
|
||||
object.CreateTables(createDatabase)
|
||||
object.DoMigration()
|
||||
|
||||
|
@ -15,8 +15,10 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
@ -40,12 +42,19 @@ func InitConfig() {
|
||||
|
||||
beego.BConfig.WebConfig.Session.SessionOn = true
|
||||
|
||||
InitAdapter()
|
||||
InitAdapter(true)
|
||||
CreateTables(true)
|
||||
DoMigration()
|
||||
}
|
||||
|
||||
func InitAdapter() {
|
||||
func InitAdapter(createDatabase bool) {
|
||||
if createDatabase {
|
||||
err := createDatabaseForPostgres(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
adapter = NewAdapter(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
|
||||
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
@ -96,7 +105,32 @@ func NewAdapter(driverName string, dataSourceName string, dbName string) *Adapte
|
||||
return a
|
||||
}
|
||||
|
||||
func createDatabaseForPostgres(driverName string, dataSourceName string, dbName string) error {
|
||||
if driverName == "postgres" {
|
||||
db, err := sql.Open(driverName, dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
_, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s;", dbName))
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "already exists") {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Adapter) CreateDatabase() error {
|
||||
if a.driverName == "postgres" {
|
||||
return nil
|
||||
}
|
||||
|
||||
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -165,6 +199,11 @@ func (a *Adapter) createTable() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = a.Engine.Sync2(new(Enforcer))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = a.Engine.Sync2(new(Provider))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -100,6 +100,13 @@ func UpdateCasbinAdapter(id string, casbinAdapter *CasbinAdapter) (bool, error)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if name != casbinAdapter.Name {
|
||||
err := casbinAdapterChangeTrigger(name, casbinAdapter.Name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
||||
if casbinAdapter.Password == "***" {
|
||||
session.Omit("password")
|
||||
@ -180,6 +187,26 @@ func initEnforcer(modelObj *Model, casbinAdapter *CasbinAdapter) (*casbin.Enforc
|
||||
return enforcer, nil
|
||||
}
|
||||
|
||||
func casbinAdapterChangeTrigger(oldName string, newName string) error {
|
||||
session := adapter.Engine.NewSession()
|
||||
defer session.Close()
|
||||
|
||||
err := session.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
enforcer := new(Enforcer)
|
||||
enforcer.Adapter = newName
|
||||
_, err = session.Where("adapter=?", oldName).Update(enforcer)
|
||||
if err != nil {
|
||||
session.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
return session.Commit()
|
||||
}
|
||||
|
||||
func safeReturn(policy []string, i int) string {
|
||||
if len(policy) > i {
|
||||
return policy[i]
|
||||
|
@ -365,7 +365,7 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
||||
if containsAsterisk {
|
||||
return true, err
|
||||
}
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
if allowed, err = enforcer.Enforce(userId, application.Name, "read"); allowed {
|
||||
return allowed, err
|
||||
}
|
||||
|
119
object/enforcer.go
Normal file
119
object/enforcer.go
Normal file
@ -0,0 +1,119 @@
|
||||
// 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 object
|
||||
|
||||
import (
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/xorm-io/core"
|
||||
)
|
||||
|
||||
type Enforcer struct {
|
||||
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
||||
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||
UpdatedTime string `xorm:"varchar(100) updated" json:"updatedTime"`
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
Description string `xorm:"varchar(100)" json:"description"`
|
||||
|
||||
Model string `xorm:"varchar(100)" json:"model"`
|
||||
Adapter string `xorm:"varchar(100)" json:"adapter"`
|
||||
IsEnabled bool `json:"isEnabled"`
|
||||
|
||||
*casbin.Enforcer
|
||||
}
|
||||
|
||||
func GetEnforcerCount(owner, field, value string) (int64, error) {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
return session.Count(&Enforcer{})
|
||||
}
|
||||
|
||||
func GetEnforcers(owner string) ([]*Enforcer, error) {
|
||||
enforcers := []*Enforcer{}
|
||||
err := adapter.Engine.Desc("created_time").Find(&enforcers, &Enforcer{Owner: owner})
|
||||
if err != nil {
|
||||
return enforcers, err
|
||||
}
|
||||
|
||||
return enforcers, nil
|
||||
}
|
||||
|
||||
func GetPaginationEnforcers(owner string, offset, limit int, field, value, sortField, sortOrder string) ([]*Enforcer, error) {
|
||||
enforcers := []*Enforcer{}
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&enforcers)
|
||||
if err != nil {
|
||||
return enforcers, err
|
||||
}
|
||||
|
||||
return enforcers, nil
|
||||
}
|
||||
|
||||
func getEnforcer(owner string, name string) (*Enforcer, error) {
|
||||
if owner == "" || name == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
enforcer := Enforcer{Owner: owner, Name: name}
|
||||
existed, err := adapter.Engine.Get(&enforcer)
|
||||
if err != nil {
|
||||
return &enforcer, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return &enforcer, nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func GetEnforcer(id string) (*Enforcer, error) {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
return getEnforcer(owner, name)
|
||||
}
|
||||
|
||||
func UpdateEnforcer(id string, enforcer *Enforcer) (bool, error) {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
if oldEnforcer, err := getEnforcer(owner, name); err != nil {
|
||||
return false, err
|
||||
} else if oldEnforcer == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(enforcer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func AddEnforcer(enforcer *Enforcer) (bool, error) {
|
||||
affected, err := adapter.Engine.Insert(enforcer)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteEnforcer(enforcer *Enforcer) (bool, error) {
|
||||
affected, err := adapter.Engine.ID(core.PK{enforcer.Owner, enforcer.Name}).Delete(&Enforcer{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
@ -107,6 +107,11 @@ func UpdateGroup(id string, group *Group) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = checkGroupName(group.Name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if name != group.Name {
|
||||
err := GroupChangeTrigger(name, group.Name)
|
||||
if err != nil {
|
||||
@ -123,6 +128,11 @@ func UpdateGroup(id string, group *Group) (bool, error) {
|
||||
}
|
||||
|
||||
func AddGroup(group *Group) (bool, error) {
|
||||
err := checkGroupName(group.Name)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.Insert(group)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@ -168,6 +178,17 @@ func DeleteGroup(group *Group) (bool, error) {
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func checkGroupName(name string) error {
|
||||
exist, err := adapter.Engine.Exist(&Organization{Owner: "admin", Name: name})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exist {
|
||||
return errors.New("group name can't be same as the organization name")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (group *Group) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", group.Owner, group.Name)
|
||||
}
|
||||
@ -225,7 +246,7 @@ func GetGroupUserCount(groupName string, field, value string) (int64, error) {
|
||||
func GetPaginationGroupUsers(groupName string, offset, limit int, field, value, sortField, sortOrder string) ([]*User, error) {
|
||||
users := []*User{}
|
||||
session := adapter.Engine.Table("user").
|
||||
Where(builder.Like{"`groups`", groupName})
|
||||
Where(builder.Like{"`groups`", groupName + "\""})
|
||||
|
||||
if offset != -1 && limit != -1 {
|
||||
session.Limit(limit, offset)
|
||||
@ -255,7 +276,7 @@ func GetPaginationGroupUsers(groupName string, offset, limit int, field, value,
|
||||
func GetGroupUsers(groupName string) ([]*User, error) {
|
||||
users := []*User{}
|
||||
err := adapter.Engine.Table("user").
|
||||
Where(builder.Like{"`groups`", groupName}).
|
||||
Where(builder.Like{"`groups`", groupName + "\""}).
|
||||
Find(&users)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -61,7 +61,7 @@ func getBuiltInAccountItems() []*AccountItem {
|
||||
{Name: "Signup application", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
{Name: "Roles", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"},
|
||||
{Name: "Permissions", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"},
|
||||
{Name: "Groups", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"},
|
||||
{Name: "Groups", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
{Name: "3rd-party logins", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Properties", Visible: false, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is admin", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
@ -93,7 +93,7 @@ func initBuiltInOrganization() bool {
|
||||
Favicon: fmt.Sprintf("%s/img/casbin/favicon.ico", conf.GetConfigString("staticBaseUrl")),
|
||||
PasswordType: "plain",
|
||||
PasswordOptions: []string{"AtLeast6"},
|
||||
CountryCodes: []string{"US", "ES", "CN", "FR", "DE", "GB", "JP", "KR", "VN", "ID", "SG", "IN"},
|
||||
CountryCodes: []string{"US", "ES", "FR", "DE", "GB", "CN", "JP", "KR", "VN", "ID", "SG", "IN"},
|
||||
DefaultAvatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")),
|
||||
Tags: []string{},
|
||||
Languages: []string{"en", "zh", "es", "fr", "de", "id", "ja", "ko", "ru", "vi", "pt"},
|
||||
@ -130,7 +130,7 @@ func initBuiltInUser() {
|
||||
Avatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")),
|
||||
Email: "admin@example.com",
|
||||
Phone: "12345678910",
|
||||
CountryCode: "CN",
|
||||
CountryCode: "US",
|
||||
Address: []string{},
|
||||
Affiliation: "Example Inc.",
|
||||
Tag: "staff",
|
||||
|
@ -103,6 +103,37 @@ func GetLdap(id string) (*Ldap, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func GetMaskedLdap(ldap *Ldap, errs ...error) (*Ldap, error) {
|
||||
if len(errs) > 0 && errs[0] != nil {
|
||||
return nil, errs[0]
|
||||
}
|
||||
|
||||
if ldap == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if ldap.Password != "" {
|
||||
ldap.Password = "***"
|
||||
}
|
||||
|
||||
return ldap, nil
|
||||
}
|
||||
|
||||
func GetMaskedLdaps(ldaps []*Ldap, errs ...error) ([]*Ldap, error) {
|
||||
if len(errs) > 0 && errs[0] != nil {
|
||||
return nil, errs[0]
|
||||
}
|
||||
|
||||
var err error
|
||||
for _, ldap := range ldaps {
|
||||
ldap, err = GetMaskedLdap(ldap)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return ldaps, nil
|
||||
}
|
||||
|
||||
func UpdateLdap(ldap *Ldap) (bool, error) {
|
||||
if l, err := GetLdap(ldap.Id); err != nil {
|
||||
return false, nil
|
||||
|
@ -24,10 +24,6 @@ import (
|
||||
|
||||
const MfaRecoveryCodesSession = "mfa_recovery_codes"
|
||||
|
||||
type MfaSessionData struct {
|
||||
UserId string
|
||||
}
|
||||
|
||||
type MfaProps struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
IsPreferred bool `json:"isPreferred"`
|
||||
|
@ -24,8 +24,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MfaSmsCountryCodeSession = "mfa_country_code"
|
||||
MfaSmsDestSession = "mfa_dest"
|
||||
MfaCountryCodeSession = "mfa_country_code"
|
||||
MfaDestSession = "mfa_dest"
|
||||
)
|
||||
|
||||
type SmsMfa struct {
|
||||
@ -48,9 +48,19 @@ func (mfa *SmsMfa) Initiate(ctx *context.Context, userId string) (*MfaProps, err
|
||||
}
|
||||
|
||||
func (mfa *SmsMfa) SetupVerify(ctx *context.Context, passCode string) error {
|
||||
dest := ctx.Input.CruSession.Get(MfaSmsDestSession).(string)
|
||||
countryCode := ctx.Input.CruSession.Get(MfaSmsCountryCodeSession).(string)
|
||||
destSession := ctx.Input.CruSession.Get(MfaDestSession)
|
||||
if destSession == nil {
|
||||
return errors.New("dest session is missing")
|
||||
}
|
||||
dest := destSession.(string)
|
||||
|
||||
if !util.IsEmailValid(dest) {
|
||||
countryCodeSession := ctx.Input.CruSession.Get(MfaCountryCodeSession)
|
||||
if countryCodeSession == nil {
|
||||
return errors.New("country code is missing")
|
||||
}
|
||||
countryCode := countryCodeSession.(string)
|
||||
|
||||
dest, _ = util.GetE164Number(dest, countryCode)
|
||||
}
|
||||
|
||||
@ -78,8 +88,8 @@ func (mfa *SmsMfa) Enable(ctx *context.Context, user *User) error {
|
||||
columns = append(columns, "mfa_phone_enabled")
|
||||
|
||||
if user.Phone == "" {
|
||||
user.Phone = ctx.Input.CruSession.Get(MfaSmsDestSession).(string)
|
||||
user.CountryCode = ctx.Input.CruSession.Get(MfaSmsCountryCodeSession).(string)
|
||||
user.Phone = ctx.Input.CruSession.Get(MfaDestSession).(string)
|
||||
user.CountryCode = ctx.Input.CruSession.Get(MfaCountryCodeSession).(string)
|
||||
columns = append(columns, "phone", "country_code")
|
||||
}
|
||||
} else if mfa.Config.MfaType == EmailType {
|
||||
@ -87,7 +97,7 @@ func (mfa *SmsMfa) Enable(ctx *context.Context, user *User) error {
|
||||
columns = append(columns, "mfa_email_enabled")
|
||||
|
||||
if user.Email == "" {
|
||||
user.Email = ctx.Input.CruSession.Get(MfaSmsDestSession).(string)
|
||||
user.Email = ctx.Input.CruSession.Get(MfaDestSession).(string)
|
||||
columns = append(columns, "email")
|
||||
}
|
||||
}
|
||||
@ -96,6 +106,11 @@ func (mfa *SmsMfa) Enable(ctx *context.Context, user *User) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Input.CruSession.Delete(MfaRecoveryCodesSession)
|
||||
ctx.Input.CruSession.Delete(MfaDestSession)
|
||||
ctx.Input.CruSession.Delete(MfaCountryCodeSession)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,11 @@ func (mfa *TotpMfa) Initiate(ctx *context.Context, userId string) (*MfaProps, er
|
||||
}
|
||||
|
||||
func (mfa *TotpMfa) SetupVerify(ctx *context.Context, passcode string) error {
|
||||
secret := ctx.Input.CruSession.Get(MfaTotpSecretSession).(string)
|
||||
result := totp.Validate(passcode, secret)
|
||||
secret := ctx.Input.CruSession.Get(MfaTotpSecretSession)
|
||||
if secret == nil {
|
||||
return errors.New("totp secret is missing")
|
||||
}
|
||||
result := totp.Validate(passcode, secret.(string))
|
||||
|
||||
if result {
|
||||
return nil
|
||||
@ -104,6 +107,10 @@ func (mfa *TotpMfa) Enable(ctx *context.Context, user *User) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctx.Input.CruSession.Delete(MfaRecoveryCodesSession)
|
||||
ctx.Input.CruSession.Delete(MfaTotpSecretSession)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,15 @@ func modelChangeTrigger(oldName string, newName string) error {
|
||||
permission.Model = newName
|
||||
_, err = session.Where("model=?", oldName).Update(permission)
|
||||
if err != nil {
|
||||
session.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
enforcer := new(Enforcer)
|
||||
enforcer.Model = newName
|
||||
_, err = session.Where("model=?", oldName).Update(enforcer)
|
||||
if err != nil {
|
||||
session.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
@ -161,5 +170,8 @@ func modelChangeTrigger(oldName string, newName string) error {
|
||||
}
|
||||
|
||||
func HasRoleDefinition(m model.Model) bool {
|
||||
if m == nil {
|
||||
return false
|
||||
}
|
||||
return m["g"] != nil
|
||||
}
|
||||
|
@ -123,6 +123,10 @@ func GetJsonWebKeySet() (jose.JSONWebKeySet, error) {
|
||||
// link here: https://self-issued.info/docs/draft-ietf-jose-json-web-key.html
|
||||
// or https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key
|
||||
for _, cert := range certs {
|
||||
if cert.Type != "x509" {
|
||||
continue
|
||||
}
|
||||
|
||||
certPemBlock := []byte(cert.Certificate)
|
||||
certDerBlock, _ := pem.Decode(certPemBlock)
|
||||
x509Cert, _ := x509.ParseCertificate(certDerBlock.Bytes)
|
||||
|
@ -69,7 +69,7 @@ type Organization struct {
|
||||
IsProfilePublic bool `json:"isProfilePublic"`
|
||||
|
||||
MfaItems []*MfaItem `xorm:"varchar(300)" json:"mfaItems"`
|
||||
AccountItems []*AccountItem `xorm:"varchar(3000)" json:"accountItems"`
|
||||
AccountItems []*AccountItem `xorm:"varchar(5000)" json:"accountItems"`
|
||||
}
|
||||
|
||||
func GetOrganizationCount(owner, field, value string) (int64, error) {
|
||||
@ -476,10 +476,21 @@ func organizationChangeTrigger(oldName string, newName string) error {
|
||||
return session.Commit()
|
||||
}
|
||||
|
||||
func (org *Organization) HasRequiredMfa() bool {
|
||||
func IsNeedPromptMfa(org *Organization, user *User) bool {
|
||||
if org == nil || user == nil {
|
||||
return false
|
||||
}
|
||||
for _, item := range org.MfaItems {
|
||||
if item.Rule == "Required" {
|
||||
return true
|
||||
if item.Name == EmailType && !user.MfaEmailEnabled {
|
||||
return true
|
||||
}
|
||||
if item.Name == SmsType && !user.MfaPhoneEnabled {
|
||||
return true
|
||||
}
|
||||
if item.Name == TotpType && user.TotpSecret == "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
@ -118,7 +118,7 @@ func GetPermission(id string) (*Permission, error) {
|
||||
|
||||
// checkPermissionValid verifies if the permission is valid
|
||||
func checkPermissionValid(permission *Permission) error {
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
enforcer.EnableAutoSave(false)
|
||||
|
||||
policies := getPolicies(permission)
|
||||
|
@ -26,42 +26,7 @@ import (
|
||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||
)
|
||||
|
||||
func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforcer {
|
||||
tableName := "permission_rule"
|
||||
if len(permission.Adapter) != 0 {
|
||||
adapterObj, err := getCasbinAdapter(permission.Owner, permission.Adapter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if adapterObj != nil && adapterObj.Table != "" {
|
||||
tableName = adapterObj.Table
|
||||
}
|
||||
}
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
driverName := conf.GetConfigString("driverName")
|
||||
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
|
||||
adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
permissionModel, err := getModel(permission.Owner, permission.Model)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
m := model.Model{}
|
||||
if permissionModel != nil {
|
||||
m, err = GetBuiltInModel(permissionModel.ModelText)
|
||||
} else {
|
||||
m, err = GetBuiltInModel("")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
func getPermissionEnforcer(p *Permission, permissionIDs ...string) *casbin.Enforcer {
|
||||
// Init an enforcer instance without specifying a model or adapter.
|
||||
// If you specify an adapter, it will load all policies, which is a
|
||||
// heavy process that can slow down the application.
|
||||
@ -70,14 +35,17 @@ func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforc
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = enforcer.InitWithModelAndAdapter(m, nil)
|
||||
err = p.setEnforcerModel(enforcer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
enforcer.SetAdapter(adapter)
|
||||
err = p.setEnforcerAdapter(enforcer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
policyFilterV5 := []string{permission.GetId()}
|
||||
policyFilterV5 := []string{p.GetId()}
|
||||
if len(permissionIDs) != 0 {
|
||||
policyFilterV5 = permissionIDs
|
||||
}
|
||||
@ -86,7 +54,7 @@ func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforc
|
||||
V5: policyFilterV5,
|
||||
}
|
||||
|
||||
if !HasRoleDefinition(m) {
|
||||
if !HasRoleDefinition(enforcer.GetModel()) {
|
||||
policyFilter.Ptype = []string{"p"}
|
||||
}
|
||||
|
||||
@ -98,35 +66,70 @@ func getEnforcer(permission *Permission, permissionIDs ...string) *casbin.Enforc
|
||||
return enforcer
|
||||
}
|
||||
|
||||
func (p *Permission) setEnforcerAdapter(enforcer *casbin.Enforcer) error {
|
||||
tableName := "permission_rule"
|
||||
if len(p.Adapter) != 0 {
|
||||
adapterObj, err := getCasbinAdapter(p.Owner, p.Adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if adapterObj != nil && adapterObj.Table != "" {
|
||||
tableName = adapterObj.Table
|
||||
}
|
||||
}
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
driverName := conf.GetConfigString("driverName")
|
||||
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
|
||||
casbinAdapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
enforcer.SetAdapter(casbinAdapter)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Permission) setEnforcerModel(enforcer *casbin.Enforcer) error {
|
||||
permissionModel, err := getModel(p.Owner, p.Model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: return error if permissionModel is nil.
|
||||
m := model.Model{}
|
||||
if permissionModel != nil {
|
||||
m, err = GetBuiltInModel(permissionModel.ModelText)
|
||||
} else {
|
||||
m, err = GetBuiltInModel("")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = enforcer.InitWithModelAndAdapter(m, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPolicies(permission *Permission) [][]string {
|
||||
var policies [][]string
|
||||
|
||||
permissionId := permission.GetId()
|
||||
domainExist := len(permission.Domains) > 0
|
||||
|
||||
for _, user := range permission.Users {
|
||||
usersAndRoles := append(permission.Users, permission.Roles...)
|
||||
for _, userOrRole := range usersAndRoles {
|
||||
for _, resource := range permission.Resources {
|
||||
for _, action := range permission.Actions {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
policies = append(policies, []string{user, domain, resource, strings.ToLower(action), "", permissionId})
|
||||
policies = append(policies, []string{userOrRole, domain, resource, strings.ToLower(action), strings.ToLower(permission.Effect), permissionId})
|
||||
}
|
||||
} else {
|
||||
policies = append(policies, []string{user, resource, strings.ToLower(action), "", "", permissionId})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, role := range permission.Roles {
|
||||
for _, resource := range permission.Resources {
|
||||
for _, action := range permission.Actions {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
policies = append(policies, []string{role, domain, resource, strings.ToLower(action), "", permissionId})
|
||||
}
|
||||
} else {
|
||||
policies = append(policies, []string{role, resource, strings.ToLower(action), "", "", permissionId})
|
||||
policies = append(policies, []string{userOrRole, resource, strings.ToLower(action), strings.ToLower(permission.Effect), "", permissionId})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -201,7 +204,7 @@ func getGroupingPolicies(permission *Permission) [][]string {
|
||||
}
|
||||
|
||||
func addPolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
policies := getPolicies(permission)
|
||||
|
||||
_, err := enforcer.AddPolicies(policies)
|
||||
@ -211,7 +214,7 @@ func addPolicies(permission *Permission) {
|
||||
}
|
||||
|
||||
func addGroupingPolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
groupingPolicies := getGroupingPolicies(permission)
|
||||
|
||||
if len(groupingPolicies) > 0 {
|
||||
@ -223,7 +226,7 @@ func addGroupingPolicies(permission *Permission) {
|
||||
}
|
||||
|
||||
func removeGroupingPolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
groupingPolicies := getGroupingPolicies(permission)
|
||||
|
||||
if len(groupingPolicies) > 0 {
|
||||
@ -235,7 +238,7 @@ func removeGroupingPolicies(permission *Permission) {
|
||||
}
|
||||
|
||||
func removePolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
policies := getPolicies(permission)
|
||||
|
||||
_, err := enforcer.RemovePolicies(policies)
|
||||
@ -247,12 +250,12 @@ func removePolicies(permission *Permission) {
|
||||
type CasbinRequest = []interface{}
|
||||
|
||||
func Enforce(permission *Permission, request *CasbinRequest, permissionIds ...string) (bool, error) {
|
||||
enforcer := getEnforcer(permission, permissionIds...)
|
||||
enforcer := getPermissionEnforcer(permission, permissionIds...)
|
||||
return enforcer.Enforce(*request...)
|
||||
}
|
||||
|
||||
func BatchEnforce(permission *Permission, requests *[]CasbinRequest, permissionIds ...string) ([]bool, error) {
|
||||
enforcer := getEnforcer(permission, permissionIds...)
|
||||
enforcer := getPermissionEnforcer(permission, permissionIds...)
|
||||
return enforcer.BatchEnforce(*requests)
|
||||
}
|
||||
|
||||
@ -273,7 +276,7 @@ func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) []
|
||||
|
||||
var values []string
|
||||
for _, permission := range permissions {
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer := getPermissionEnforcer(permission)
|
||||
values = append(values, fn(enforcer)...)
|
||||
}
|
||||
return values
|
||||
|
@ -229,7 +229,7 @@ func UpdateProvider(id string, provider *Provider) (bool, error) {
|
||||
session = session.Omit("client_secret2")
|
||||
}
|
||||
|
||||
if provider.Type != "Keycloak" {
|
||||
if provider.Type == "Tencent Cloud COS" {
|
||||
provider.Endpoint = util.GetEndPoint(provider.Endpoint)
|
||||
provider.IntranetEndpoint = util.GetEndPoint(provider.IntranetEndpoint)
|
||||
}
|
||||
@ -243,7 +243,7 @@ func UpdateProvider(id string, provider *Provider) (bool, error) {
|
||||
}
|
||||
|
||||
func AddProvider(provider *Provider) (bool, error) {
|
||||
if provider.Type != "Keycloak" {
|
||||
if provider.Type == "Tencent Cloud COS" {
|
||||
provider.Endpoint = util.GetEndPoint(provider.Endpoint)
|
||||
provider.IntranetEndpoint = util.GetEndPoint(provider.IntranetEndpoint)
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ func (pi *ProviderItem) IsProviderVisible() bool {
|
||||
if pi.Provider == nil {
|
||||
return false
|
||||
}
|
||||
return pi.Provider.Category == "OAuth" || pi.Provider.Category == "SAML"
|
||||
return pi.Provider.Category == "OAuth" || pi.Provider.Category == "SAML" || pi.Provider.Category == "Web3"
|
||||
}
|
||||
|
||||
func (pi *ProviderItem) isProviderPrompted() bool {
|
||||
|
@ -161,7 +161,8 @@ func SendWebhooks(record *Record) error {
|
||||
|
||||
if matched {
|
||||
if webhook.IsUserExtended {
|
||||
user, err := GetMaskedUser(getUser(record.Organization, record.User))
|
||||
user, err := getUser(record.Organization, record.User)
|
||||
user, err = GetMaskedUser(user, false, err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/xorm-io/core"
|
||||
@ -76,6 +77,10 @@ func GetPaginationResources(owner, user string, offset, limit int, field, value,
|
||||
}
|
||||
|
||||
func getResource(owner string, name string) (*Resource, error) {
|
||||
if !strings.HasPrefix(name, "/") {
|
||||
name = "/" + name
|
||||
}
|
||||
|
||||
resource := Resource{Owner: owner, Name: name}
|
||||
existed, err := adapter.Engine.Get(&resource)
|
||||
if err != nil {
|
||||
|
@ -391,10 +391,13 @@ func GetAncestorRoles(roleIds ...string) ([]*Role, error) {
|
||||
|
||||
// containsRole is a helper function to check if a roles is related to any role in the given list roles
|
||||
func containsRole(role *Role, roleMap map[string]*Role, visited map[string]bool, roleIds ...string) bool {
|
||||
if isContain, ok := visited[role.GetId()]; ok {
|
||||
roleId := role.GetId()
|
||||
if isContain, ok := visited[roleId]; ok {
|
||||
return isContain
|
||||
}
|
||||
|
||||
visited[role.GetId()] = false
|
||||
|
||||
for _, subRole := range role.Roles {
|
||||
if util.HasString(roleIds, subRole) {
|
||||
return true
|
||||
|
@ -42,7 +42,11 @@ func SendSms(provider *Provider, content string, phoneNumbers ...string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if provider.Type == sender.Aliyun {
|
||||
if provider.Type == sender.Twilio {
|
||||
if provider.AppId != "" {
|
||||
phoneNumbers = append([]string{provider.AppId}, phoneNumbers...)
|
||||
}
|
||||
} else if provider.Type == sender.Aliyun {
|
||||
for i, number := range phoneNumbers {
|
||||
phoneNumbers[i] = strings.TrimPrefix(number, "+86")
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/casdoor/casdoor/i18n"
|
||||
"github.com/casdoor/casdoor/storage"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/casdoor/oss"
|
||||
)
|
||||
|
||||
var isCloudIntranet bool
|
||||
@ -102,11 +103,11 @@ func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool
|
||||
return fileUrl, objectKey
|
||||
}
|
||||
|
||||
func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffer, lang string) (string, string, error) {
|
||||
func getStorageProvider(provider *Provider, lang string) (oss.StorageInterface, error) {
|
||||
endpoint := getProviderEndpoint(provider)
|
||||
storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
|
||||
if storageProvider == nil {
|
||||
return "", "", fmt.Errorf(i18n.Translate(lang, "storage:The provider type: %s is not supported"), provider.Type)
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "storage:The provider type: %s is not supported"), provider.Type)
|
||||
}
|
||||
|
||||
if provider.Domain == "" {
|
||||
@ -114,9 +115,18 @@ func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffe
|
||||
UpdateProvider(provider.GetId(), provider)
|
||||
}
|
||||
|
||||
return storageProvider, nil
|
||||
}
|
||||
|
||||
func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffer, lang string) (string, string, error) {
|
||||
storageProvider, err := getStorageProvider(provider, lang)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
fileUrl, objectKey := GetUploadFileUrl(provider, fullFilePath, true)
|
||||
|
||||
_, err := storageProvider.Put(objectKey, fileBuffer)
|
||||
_, err = storageProvider.Put(objectKey, fileBuffer)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
@ -154,15 +164,9 @@ func DeleteFile(provider *Provider, objectKey string, lang string) error {
|
||||
return fmt.Errorf(i18n.Translate(lang, "storage:The objectKey: %s is not allowed"), objectKey)
|
||||
}
|
||||
|
||||
endpoint := getProviderEndpoint(provider)
|
||||
storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
|
||||
if storageProvider == nil {
|
||||
return fmt.Errorf(i18n.Translate(lang, "storage:The provider type: %s is not supported"), provider.Type)
|
||||
}
|
||||
|
||||
if provider.Domain == "" {
|
||||
provider.Domain = storageProvider.GetEndpoint()
|
||||
UpdateProvider(provider.GetId(), provider)
|
||||
storageProvider, err := getStorageProvider(provider, lang)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return storageProvider.Delete(objectKey)
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/beevik/etree"
|
||||
"github.com/casdoor/casdoor/i18n"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
dsig "github.com/russellhaering/goxmldsig"
|
||||
)
|
||||
@ -122,6 +123,13 @@ var stToServiceResponse sync.Map
|
||||
// pgt is short for proxy granting ticket
|
||||
var pgtToServiceResponse sync.Map
|
||||
|
||||
func CheckCasRestrict(application *Application, lang string, service string) error {
|
||||
if len(application.RedirectUris) > 0 && !application.IsRedirectUriValid(service) {
|
||||
return fmt.Errorf(i18n.Translate(lang, "token:Redirect URI: %s doesn't exist in the allowed Redirect URI list"), service)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func StoreCasTokenForPgt(token *CasAuthenticationSuccess, service, userId string) string {
|
||||
pgt := fmt.Sprintf("PGT-%s", util.GenerateId())
|
||||
pgtToServiceResponse.Store(pgt, &CasAuthenticationSuccessWrapper{
|
||||
|
@ -281,6 +281,14 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
if cert == nil {
|
||||
if application.Cert == "" {
|
||||
return "", "", "", fmt.Errorf("The cert field of the application \"%s\" should not be empty", application.GetId())
|
||||
} else {
|
||||
return "", "", "", fmt.Errorf("The cert \"%s\" does not exist", application.Cert)
|
||||
}
|
||||
}
|
||||
|
||||
// RSA private key
|
||||
key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(cert.PrivateKey))
|
||||
if err != nil {
|
||||
|
@ -156,12 +156,13 @@ type User struct {
|
||||
Yammer string `xorm:"yammer varchar(100)" json:"yammer"`
|
||||
Yandex string `xorm:"yandex varchar(100)" json:"yandex"`
|
||||
Zoom string `xorm:"zoom varchar(100)" json:"zoom"`
|
||||
MetaMask string `xorm:"metamask varchar(100)" json:"metamask"`
|
||||
Custom string `xorm:"custom varchar(100)" json:"custom"`
|
||||
|
||||
WebauthnCredentials []webauthn.Credential `xorm:"webauthnCredentials blob" json:"webauthnCredentials"`
|
||||
PreferredMfaType string `xorm:"varchar(100)" json:"preferredMfaType"`
|
||||
RecoveryCodes []string `xorm:"varchar(1000)" json:"recoveryCodes,omitempty"`
|
||||
TotpSecret string `xorm:"varchar(100)" json:"totpSecret,omitempty"`
|
||||
RecoveryCodes []string `xorm:"varchar(1000)" json:"recoveryCodes"`
|
||||
TotpSecret string `xorm:"varchar(100)" json:"totpSecret"`
|
||||
MfaPhoneEnabled bool `json:"mfaPhoneEnabled"`
|
||||
MfaEmailEnabled bool `json:"mfaEmailEnabled"`
|
||||
MultiFactorAuths []*MfaProps `xorm:"-" json:"multiFactorAuths,omitempty"`
|
||||
@ -418,7 +419,7 @@ func GetUserNoCheck(id string) (*User, error) {
|
||||
return getUser(owner, name)
|
||||
}
|
||||
|
||||
func GetMaskedUser(user *User, errs ...error) (*User, error) {
|
||||
func GetMaskedUser(user *User, isAdminOrSelf bool, errs ...error) (*User, error) {
|
||||
if len(errs) > 0 && errs[0] != nil {
|
||||
return nil, errs[0]
|
||||
}
|
||||
@ -430,9 +431,13 @@ func GetMaskedUser(user *User, errs ...error) (*User, error) {
|
||||
if user.Password != "" {
|
||||
user.Password = "***"
|
||||
}
|
||||
if user.AccessSecret != "" {
|
||||
user.AccessSecret = "***"
|
||||
|
||||
if !isAdminOrSelf {
|
||||
if user.AccessSecret != "" {
|
||||
user.AccessSecret = "***"
|
||||
}
|
||||
}
|
||||
|
||||
if user.ManagedAccounts != nil {
|
||||
for _, manageAccount := range user.ManagedAccounts {
|
||||
manageAccount.Password = "***"
|
||||
@ -456,7 +461,7 @@ func GetMaskedUsers(users []*User, errs ...error) ([]*User, error) {
|
||||
|
||||
var err error
|
||||
for _, user := range users {
|
||||
user, err = GetMaskedUser(user)
|
||||
user, err = GetMaskedUser(user, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -832,11 +837,14 @@ func userChangeTrigger(oldName string, newName string) error {
|
||||
}
|
||||
|
||||
func (user *User) IsMfaEnabled() bool {
|
||||
if user == nil {
|
||||
return false
|
||||
}
|
||||
return user.PreferredMfaType != ""
|
||||
}
|
||||
|
||||
func (user *User) GetPreferredMfaProps(masked bool) *MfaProps {
|
||||
if user.PreferredMfaType == "" {
|
||||
if user == nil || user.PreferredMfaType == "" {
|
||||
return nil
|
||||
}
|
||||
return user.GetMfaProps(user.PreferredMfaType, masked)
|
||||
|
@ -293,7 +293,13 @@ func CheckPermissionForUpdateUser(oldUser, newUser *User, isAdmin bool, lang str
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
|
||||
if oldUser.Groups == nil {
|
||||
oldUser.Groups = []string{}
|
||||
}
|
||||
oldUserGroupsJson, _ := json.Marshal(oldUser.Groups)
|
||||
if newUser.Groups == nil {
|
||||
newUser.Groups = []string{}
|
||||
}
|
||||
newUserGroupsJson, _ := json.Marshal(newUser.Groups)
|
||||
if string(oldUserGroupsJson) != string(newUserGroupsJson) {
|
||||
item := GetAccountItemByName("Groups", organization)
|
||||
|
@ -156,7 +156,7 @@ func AuthzFilter(ctx *context.Context) {
|
||||
urlPath := getUrlPath(ctx.Request.URL.Path)
|
||||
|
||||
objOwner, objName := "", ""
|
||||
if urlPath != "/api/get-app-login" {
|
||||
if urlPath != "/api/get-app-login" && urlPath != "/api/get-resource" {
|
||||
objOwner, objName = getObject(ctx)
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,13 @@ func CorsFilter(ctx *context.Context) {
|
||||
origin := ctx.Input.Header(headerOrigin)
|
||||
originConf := conf.GetConfigString("origin")
|
||||
|
||||
if ctx.Request.Method == "POST" && ctx.Request.RequestURI == "/api/login/oauth/access_token" {
|
||||
ctx.Output.Header(headerAllowOrigin, origin)
|
||||
ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS, DELETE")
|
||||
ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization")
|
||||
return
|
||||
}
|
||||
|
||||
if origin != "" && originConf != "" && origin != originConf {
|
||||
ok, err := object.IsOriginAllowed(origin)
|
||||
if err != nil {
|
||||
|
@ -123,6 +123,12 @@ func initAPI() {
|
||||
beego.Router("/api/add-policy", &controllers.ApiController{}, "POST:AddPolicy")
|
||||
beego.Router("/api/remove-policy", &controllers.ApiController{}, "POST:RemovePolicy")
|
||||
|
||||
beego.Router("/api/get-enforcers", &controllers.ApiController{}, "GET:GetEnforcers")
|
||||
beego.Router("/api/get-enforcer", &controllers.ApiController{}, "GET:GetEnforcer")
|
||||
beego.Router("/api/update-enforcer", &controllers.ApiController{}, "POST:UpdateEnforcer")
|
||||
beego.Router("/api/add-enforcer", &controllers.ApiController{}, "POST:AddEnforcer")
|
||||
beego.Router("/api/delete-enforcer", &controllers.ApiController{}, "POST:DeleteEnforcer")
|
||||
|
||||
beego.Router("/api/set-password", &controllers.ApiController{}, "POST:SetPassword")
|
||||
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
|
||||
beego.Router("/api/get-email-and-phone", &controllers.ApiController{}, "GET:GetEmailAndPhone")
|
||||
|
@ -23,7 +23,7 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin
|
||||
case "AWS S3":
|
||||
return NewAwsS3StorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||
case "MinIO":
|
||||
return NewMinIOS3StorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||
return NewMinIOS3StorageProvider(clientId, clientSecret, "_", bucket, endpoint)
|
||||
case "Aliyun OSS":
|
||||
return NewAliyunOssStorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||
case "Tencent Cloud COS":
|
||||
|
@ -155,6 +155,34 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-enforcer": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Enforcer API"
|
||||
],
|
||||
"description": "add enforcer",
|
||||
"operationId": "ApiController.AddEnforcer",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "enforcer",
|
||||
"description": "The enforcer object",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-group": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -188,7 +216,27 @@
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
"operationId": "ApiController.AddLdap"
|
||||
"description": "add ldap",
|
||||
"operationId": "ApiController.AddLdap",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "The details of the ldap",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Ldap"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-message": {
|
||||
@ -476,7 +524,26 @@
|
||||
"tags": [
|
||||
"Resource API"
|
||||
],
|
||||
"operationId": "ApiController.AddResource"
|
||||
"operationId": "ApiController.AddResource",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "resource",
|
||||
"description": "Resource object",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Resource"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success or error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-role": {
|
||||
@ -1034,6 +1101,34 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/delete-enforcer": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Enforcer API"
|
||||
],
|
||||
"description": "delete enforcer",
|
||||
"operationId": "ApiController.DeleteEnforcer",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "The enforcer object",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Enforce"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/delete-group": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -1067,7 +1162,27 @@
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
"operationId": "ApiController.DeleteLdap"
|
||||
"description": "delete ldap",
|
||||
"operationId": "ApiController.DeleteLdap",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "The details of the ldap",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Ldap"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/delete-message": {
|
||||
@ -1344,7 +1459,26 @@
|
||||
"tags": [
|
||||
"Resource API"
|
||||
],
|
||||
"operationId": "ApiController.DeleteResource"
|
||||
"operationId": "ApiController.DeleteResource",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "resource",
|
||||
"description": "Resource object",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Resource"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success or error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/delete-role": {
|
||||
@ -1940,6 +2074,61 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-enforcer": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Enforcer API"
|
||||
],
|
||||
"description": "get enforcer",
|
||||
"operationId": "ApiController.GetEnforcer",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id ( owner/name ) of enforcer",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-enforcers": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Enforcer API"
|
||||
],
|
||||
"description": "get enforcers",
|
||||
"operationId": "ApiController.GetEnforcers",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "owner",
|
||||
"description": "The owner of enforcers",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Enforcer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-global-providers": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -2060,7 +2249,25 @@
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
"operationId": "ApiController.GetLdap"
|
||||
"description": "get ldap",
|
||||
"operationId": "ApiController.GetLdap",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "id",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Ldap"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-ldap-users": {
|
||||
@ -2068,7 +2275,16 @@
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
"operationId": "ApiController.GetLdapser"
|
||||
"description": "get ldap users",
|
||||
"operationId": "ApiController.GetLdapser",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/LdapResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-ldaps": {
|
||||
@ -2076,7 +2292,27 @@
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
"operationId": "ApiController.GetLdaps"
|
||||
"description": "get ldaps",
|
||||
"operationId": "ApiController.GetLdaps",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "owner",
|
||||
"description": "owner",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Ldap"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-message": {
|
||||
@ -2797,7 +3033,25 @@
|
||||
"tags": [
|
||||
"Resource API"
|
||||
],
|
||||
"operationId": "ApiController.GetResource"
|
||||
"description": "get resource",
|
||||
"operationId": "ApiController.GetResource",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id ( owner/name ) of resource",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Resource"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-resources": {
|
||||
@ -2805,7 +3059,71 @@
|
||||
"tags": [
|
||||
"Resource API"
|
||||
],
|
||||
"operationId": "ApiController.GetResources"
|
||||
"description": "get resources",
|
||||
"operationId": "ApiController.GetResources",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "owner",
|
||||
"description": "Owner",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "user",
|
||||
"description": "User",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "pageSize",
|
||||
"description": "Page Size",
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "p",
|
||||
"description": "Page Number",
|
||||
"type": "integer"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "field",
|
||||
"description": "Field",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "value",
|
||||
"description": "Value",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "sortField",
|
||||
"description": "Sort Field",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "sortOrder",
|
||||
"description": "Sort Order",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Resource"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-role": {
|
||||
@ -4019,7 +4337,25 @@
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
"operationId": "ApiController.SyncLdapUsers"
|
||||
"description": "sync ldap users",
|
||||
"operationId": "ApiController.SyncLdapUsers",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "id",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/LdapSyncResp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/unlink": {
|
||||
@ -4169,6 +4505,41 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/update-enforcer": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Enforcer API"
|
||||
],
|
||||
"description": "update enforcer",
|
||||
"operationId": "ApiController.UpdateEnforcer",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id ( owner/name ) of enforcer",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "body",
|
||||
"name": "enforcer",
|
||||
"description": "The enforcer object",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/update-group": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -4209,7 +4580,27 @@
|
||||
"tags": [
|
||||
"Account API"
|
||||
],
|
||||
"operationId": "ApiController.UpdateLdap"
|
||||
"description": "update ldap",
|
||||
"operationId": "ApiController.UpdateLdap",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "The details of the ldap",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Ldap"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/update-message": {
|
||||
@ -4532,7 +4923,34 @@
|
||||
"tags": [
|
||||
"Resource API"
|
||||
],
|
||||
"operationId": "ApiController.UpdateResource"
|
||||
"description": "get resource",
|
||||
"operationId": "ApiController.UpdateResource",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id ( owner/name ) of resource",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "body",
|
||||
"name": "resource",
|
||||
"description": "The resource object",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Resource"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success or error",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/update-role": {
|
||||
@ -4779,7 +5197,76 @@
|
||||
"tags": [
|
||||
"Resource API"
|
||||
],
|
||||
"operationId": "ApiController.UploadResource"
|
||||
"operationId": "ApiController.UploadResource",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "owner",
|
||||
"description": "Owner",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "user",
|
||||
"description": "User",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "application",
|
||||
"description": "Application",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "tag",
|
||||
"description": "Tag",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "parent",
|
||||
"description": "Parent",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "fullFilePath",
|
||||
"description": "Full File Path",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "createdTime",
|
||||
"description": "Created Time",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "description",
|
||||
"description": "Description",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "formData",
|
||||
"name": "file",
|
||||
"description": "Resource file",
|
||||
"required": true,
|
||||
"type": "file"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "FileUrl, objectKey",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Resource"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/user": {
|
||||
@ -4932,14 +5419,34 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"1225.0xc000333110.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
"1260.0xc000333140.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
"LaravelResponse": {
|
||||
"title": "LaravelResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"LdapResp": {
|
||||
"title": "LdapResp",
|
||||
"type": "object"
|
||||
},
|
||||
"LdapSyncResp": {
|
||||
"title": "LdapSyncResp",
|
||||
"type": "object"
|
||||
},
|
||||
"Response": {
|
||||
"title": "Response",
|
||||
"type": "object"
|
||||
},
|
||||
"casbin.Enforcer": {
|
||||
"title": "Enforcer",
|
||||
"type": "object"
|
||||
},
|
||||
"controllers.AuthForm": {
|
||||
"title": "AuthForm",
|
||||
"type": "object"
|
||||
@ -4973,16 +5480,10 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"additionalProperties": {
|
||||
"description": "support string | class | List\u003cclass\u003e and os on",
|
||||
"type": "string"
|
||||
}
|
||||
"$ref": "#/definitions/1225.0xc000333110.false"
|
||||
},
|
||||
"data2": {
|
||||
"additionalProperties": {
|
||||
"description": "support string | class | List\u003cclass\u003e and os on",
|
||||
"type": "string"
|
||||
}
|
||||
"$ref": "#/definitions/1260.0xc000333140.false"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
@ -5024,6 +5525,10 @@
|
||||
"title": "object",
|
||||
"type": "object"
|
||||
},
|
||||
"object.\u0026{197582 0xc000ace360 false}": {
|
||||
"title": "\u0026{197582 0xc000ace360 false}",
|
||||
"type": "object"
|
||||
},
|
||||
"object.AccountItem": {
|
||||
"title": "AccountItem",
|
||||
"type": "object",
|
||||
@ -5196,6 +5701,12 @@
|
||||
"signupUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"termsOfUse": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -5211,7 +5722,7 @@
|
||||
"title": "CasbinRequest",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.CasbinRequest"
|
||||
"$ref": "#/definitions/object.\u0026{197582 0xc000ace360 false}"
|
||||
}
|
||||
},
|
||||
"object.Cert": {
|
||||
@ -5307,6 +5818,43 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.Enforce": {
|
||||
"title": "Enforce",
|
||||
"type": "object"
|
||||
},
|
||||
"object.Enforcer": {
|
||||
"title": "Enforcer",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"adapter": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"isEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"updatedTime": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.GaugeVecInfo": {
|
||||
"title": "GaugeVecInfo",
|
||||
"type": "object",
|
||||
@ -5459,6 +6007,59 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.Ldap": {
|
||||
"title": "Ldap",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"autoSync": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"baseDn": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"enableSsl": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"filter": {
|
||||
"type": "string"
|
||||
},
|
||||
"filterFields": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastSync": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"serverName": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.ManagedAccount": {
|
||||
"title": "ManagedAccount",
|
||||
"type": "object",
|
||||
@ -6126,9 +6727,6 @@
|
||||
"customLogo": {
|
||||
"type": "string"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "string"
|
||||
},
|
||||
"customTokenUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -6190,6 +6788,9 @@
|
||||
"regionId": {
|
||||
"type": "string"
|
||||
},
|
||||
"scopes": {
|
||||
"type": "string"
|
||||
},
|
||||
"signName": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -6204,6 +6805,11 @@
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"userMapping": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6286,6 +6892,55 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.Resource": {
|
||||
"title": "Resource",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"application": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileFormat": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileName": {
|
||||
"type": "string"
|
||||
},
|
||||
"fileSize": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"fileType": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"parent": {
|
||||
"type": "string"
|
||||
},
|
||||
"provider": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"user": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.Role": {
|
||||
"title": "Role",
|
||||
"type": "object",
|
||||
@ -6861,6 +7516,9 @@
|
||||
"meetup": {
|
||||
"type": "string"
|
||||
},
|
||||
"metamask": {
|
||||
"type": "string"
|
||||
},
|
||||
"mfaEmailEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
@ -100,6 +100,24 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/add-enforcer:
|
||||
post:
|
||||
tags:
|
||||
- Enforcer API
|
||||
description: add enforcer
|
||||
operationId: ApiController.AddEnforcer
|
||||
parameters:
|
||||
- in: body
|
||||
name: enforcer
|
||||
description: The enforcer object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/object'
|
||||
/api/add-group:
|
||||
post:
|
||||
tags:
|
||||
@ -122,7 +140,20 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Account API
|
||||
description: add ldap
|
||||
operationId: ApiController.AddLdap
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
description: The details of the ldap
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Ldap'
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/add-message:
|
||||
post:
|
||||
tags:
|
||||
@ -308,6 +339,18 @@ paths:
|
||||
tags:
|
||||
- Resource API
|
||||
operationId: ApiController.AddResource
|
||||
parameters:
|
||||
- in: body
|
||||
name: resource
|
||||
description: Resource object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Resource'
|
||||
responses:
|
||||
"200":
|
||||
description: Success or error
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/add-role:
|
||||
post:
|
||||
tags:
|
||||
@ -668,6 +711,24 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/delete-enforcer:
|
||||
post:
|
||||
tags:
|
||||
- Enforcer API
|
||||
description: delete enforcer
|
||||
operationId: ApiController.DeleteEnforcer
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
description: The enforcer object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Enforce'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/object'
|
||||
/api/delete-group:
|
||||
post:
|
||||
tags:
|
||||
@ -690,7 +751,20 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Account API
|
||||
description: delete ldap
|
||||
operationId: ApiController.DeleteLdap
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
description: The details of the ldap
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Ldap'
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/delete-message:
|
||||
post:
|
||||
tags:
|
||||
@ -869,6 +943,18 @@ paths:
|
||||
tags:
|
||||
- Resource API
|
||||
operationId: ApiController.DeleteResource
|
||||
parameters:
|
||||
- in: body
|
||||
name: resource
|
||||
description: Resource object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Resource'
|
||||
responses:
|
||||
"200":
|
||||
description: Success or error
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/delete-role:
|
||||
post:
|
||||
tags:
|
||||
@ -1257,6 +1343,42 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/get-enforcer:
|
||||
get:
|
||||
tags:
|
||||
- Enforcer API
|
||||
description: get enforcer
|
||||
operationId: ApiController.GetEnforcer
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id ( owner/name ) of enforcer
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/object'
|
||||
/api/get-enforcers:
|
||||
get:
|
||||
tags:
|
||||
- Enforcer API
|
||||
description: get enforcers
|
||||
operationId: ApiController.GetEnforcers
|
||||
parameters:
|
||||
- in: query
|
||||
name: owner
|
||||
description: The owner of enforcers
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Enforcer'
|
||||
/api/get-global-providers:
|
||||
get:
|
||||
tags:
|
||||
@ -1336,17 +1458,48 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Account API
|
||||
description: get ldap
|
||||
operationId: ApiController.GetLdap
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: id
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/object.Ldap'
|
||||
/api/get-ldap-users:
|
||||
get:
|
||||
tags:
|
||||
- Account API
|
||||
description: get ldap users
|
||||
operationId: ApiController.GetLdapser
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/LdapResp'
|
||||
/api/get-ldaps:
|
||||
get:
|
||||
tags:
|
||||
- Account API
|
||||
description: get ldaps
|
||||
operationId: ApiController.GetLdaps
|
||||
parameters:
|
||||
- in: query
|
||||
name: owner
|
||||
description: owner
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Ldap'
|
||||
/api/get-message:
|
||||
get:
|
||||
tags:
|
||||
@ -1818,12 +1971,67 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Resource API
|
||||
description: get resource
|
||||
operationId: ApiController.GetResource
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id ( owner/name ) of resource
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/object.Resource'
|
||||
/api/get-resources:
|
||||
get:
|
||||
tags:
|
||||
- Resource API
|
||||
description: get resources
|
||||
operationId: ApiController.GetResources
|
||||
parameters:
|
||||
- in: query
|
||||
name: owner
|
||||
description: Owner
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: user
|
||||
description: User
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: pageSize
|
||||
description: Page Size
|
||||
type: integer
|
||||
- in: query
|
||||
name: p
|
||||
description: Page Number
|
||||
type: integer
|
||||
- in: query
|
||||
name: field
|
||||
description: Field
|
||||
type: string
|
||||
- in: query
|
||||
name: value
|
||||
description: Value
|
||||
type: string
|
||||
- in: query
|
||||
name: sortField
|
||||
description: Sort Field
|
||||
type: string
|
||||
- in: query
|
||||
name: sortOrder
|
||||
description: Sort Order
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Resource'
|
||||
/api/get-role:
|
||||
get:
|
||||
tags:
|
||||
@ -2624,7 +2832,19 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Account API
|
||||
description: sync ldap users
|
||||
operationId: ApiController.SyncLdapUsers
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: id
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/LdapSyncResp'
|
||||
/api/unlink:
|
||||
post:
|
||||
tags:
|
||||
@ -2721,6 +2941,29 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/update-enforcer:
|
||||
post:
|
||||
tags:
|
||||
- Enforcer API
|
||||
description: update enforcer
|
||||
operationId: ApiController.UpdateEnforcer
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id ( owner/name ) of enforcer
|
||||
required: true
|
||||
type: string
|
||||
- in: body
|
||||
name: enforcer
|
||||
description: The enforcer object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object'
|
||||
responses:
|
||||
"200":
|
||||
description: ""
|
||||
schema:
|
||||
$ref: '#/definitions/object'
|
||||
/api/update-group:
|
||||
post:
|
||||
tags:
|
||||
@ -2748,7 +2991,20 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Account API
|
||||
description: update ldap
|
||||
operationId: ApiController.UpdateLdap
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
description: The details of the ldap
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Ldap'
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/update-message:
|
||||
post:
|
||||
tags:
|
||||
@ -2960,7 +3216,25 @@ paths:
|
||||
post:
|
||||
tags:
|
||||
- Resource API
|
||||
description: get resource
|
||||
operationId: ApiController.UpdateResource
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id ( owner/name ) of resource
|
||||
required: true
|
||||
type: string
|
||||
- in: body
|
||||
name: resource
|
||||
description: The resource object
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Resource'
|
||||
responses:
|
||||
"200":
|
||||
description: Success or error
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/update-role:
|
||||
post:
|
||||
tags:
|
||||
@ -3123,6 +3397,53 @@ paths:
|
||||
tags:
|
||||
- Resource API
|
||||
operationId: ApiController.UploadResource
|
||||
parameters:
|
||||
- in: query
|
||||
name: owner
|
||||
description: Owner
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: user
|
||||
description: User
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: application
|
||||
description: Application
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: tag
|
||||
description: Tag
|
||||
type: string
|
||||
- in: query
|
||||
name: parent
|
||||
description: Parent
|
||||
type: string
|
||||
- in: query
|
||||
name: fullFilePath
|
||||
description: Full File Path
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: createdTime
|
||||
description: Created Time
|
||||
type: string
|
||||
- in: query
|
||||
name: description
|
||||
description: Description
|
||||
type: string
|
||||
- in: formData
|
||||
name: file
|
||||
description: Resource file
|
||||
required: true
|
||||
type: file
|
||||
responses:
|
||||
"200":
|
||||
description: FileUrl, objectKey
|
||||
schema:
|
||||
$ref: '#/definitions/object.Resource'
|
||||
/api/user:
|
||||
get:
|
||||
tags:
|
||||
@ -3220,12 +3541,27 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
definitions:
|
||||
1225.0xc000333110.false:
|
||||
title: "false"
|
||||
type: object
|
||||
1260.0xc000333140.false:
|
||||
title: "false"
|
||||
type: object
|
||||
LaravelResponse:
|
||||
title: LaravelResponse
|
||||
type: object
|
||||
LdapResp:
|
||||
title: LdapResp
|
||||
type: object
|
||||
LdapSyncResp:
|
||||
title: LdapSyncResp
|
||||
type: object
|
||||
Response:
|
||||
title: Response
|
||||
type: object
|
||||
casbin.Enforcer:
|
||||
title: Enforcer
|
||||
type: object
|
||||
controllers.AuthForm:
|
||||
title: AuthForm
|
||||
type: object
|
||||
@ -3250,13 +3586,9 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
additionalProperties:
|
||||
description: support string | class | List<class> and os on
|
||||
type: string
|
||||
$ref: '#/definitions/1225.0xc000333110.false'
|
||||
data2:
|
||||
additionalProperties:
|
||||
description: support string | class | List<class> and os on
|
||||
type: string
|
||||
$ref: '#/definitions/1260.0xc000333140.false'
|
||||
msg:
|
||||
type: string
|
||||
name:
|
||||
@ -3283,6 +3615,9 @@ definitions:
|
||||
object:
|
||||
title: object
|
||||
type: object
|
||||
object.&{197582 0xc000ace360 false}:
|
||||
title: '&{197582 0xc000ace360 false}'
|
||||
type: object
|
||||
object.AccountItem:
|
||||
title: AccountItem
|
||||
type: object
|
||||
@ -3400,6 +3735,10 @@ definitions:
|
||||
$ref: '#/definitions/object.SignupItem'
|
||||
signupUrl:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
termsOfUse:
|
||||
type: string
|
||||
themeData:
|
||||
@ -3410,7 +3749,7 @@ definitions:
|
||||
title: CasbinRequest
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.CasbinRequest'
|
||||
$ref: '#/definitions/object.&{197582 0xc000ace360 false}'
|
||||
object.Cert:
|
||||
title: Cert
|
||||
type: object
|
||||
@ -3474,6 +3813,31 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
object.Enforce:
|
||||
title: Enforce
|
||||
type: object
|
||||
object.Enforcer:
|
||||
title: Enforcer
|
||||
type: object
|
||||
properties:
|
||||
adapter:
|
||||
type: string
|
||||
createdTime:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
displayName:
|
||||
type: string
|
||||
isEnabled:
|
||||
type: boolean
|
||||
model:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
updatedTime:
|
||||
type: string
|
||||
object.GaugeVecInfo:
|
||||
title: GaugeVecInfo
|
||||
type: object
|
||||
@ -3577,6 +3941,42 @@ definitions:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
object.Ldap:
|
||||
title: Ldap
|
||||
type: object
|
||||
properties:
|
||||
autoSync:
|
||||
type: integer
|
||||
format: int64
|
||||
baseDn:
|
||||
type: string
|
||||
createdTime:
|
||||
type: string
|
||||
enableSsl:
|
||||
type: boolean
|
||||
filter:
|
||||
type: string
|
||||
filterFields:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
host:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
lastSync:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
format: int64
|
||||
serverName:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
object.ManagedAccount:
|
||||
title: ManagedAccount
|
||||
type: object
|
||||
@ -4026,8 +4426,6 @@ definitions:
|
||||
type: string
|
||||
customLogo:
|
||||
type: string
|
||||
scopes:
|
||||
type: string
|
||||
customTokenUrl:
|
||||
type: string
|
||||
customUserInfoUrl:
|
||||
@ -4069,6 +4467,8 @@ definitions:
|
||||
type: string
|
||||
regionId:
|
||||
type: string
|
||||
scopes:
|
||||
type: string
|
||||
signName:
|
||||
type: string
|
||||
subType:
|
||||
@ -4079,6 +4479,9 @@ definitions:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
userMapping:
|
||||
additionalProperties:
|
||||
type: string
|
||||
object.ProviderItem:
|
||||
title: ProviderItem
|
||||
type: object
|
||||
@ -4132,6 +4535,39 @@ definitions:
|
||||
type: string
|
||||
user:
|
||||
type: string
|
||||
object.Resource:
|
||||
title: Resource
|
||||
type: object
|
||||
properties:
|
||||
application:
|
||||
type: string
|
||||
createdTime:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
fileFormat:
|
||||
type: string
|
||||
fileName:
|
||||
type: string
|
||||
fileSize:
|
||||
type: integer
|
||||
format: int64
|
||||
fileType:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
parent:
|
||||
type: string
|
||||
provider:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
user:
|
||||
type: string
|
||||
object.Role:
|
||||
title: Role
|
||||
type: object
|
||||
@ -4520,6 +4956,8 @@ definitions:
|
||||
$ref: '#/definitions/object.ManagedAccount'
|
||||
meetup:
|
||||
type: string
|
||||
metamask:
|
||||
type: string
|
||||
mfaEmailEnabled:
|
||||
type: boolean
|
||||
mfaPhoneEnabled:
|
||||
|
@ -50,4 +50,32 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
],
|
||||
webpack: {
|
||||
// use polyfill Buffer with Webpack 5
|
||||
// https://viglucci.io/articles/how-to-polyfill-buffer-with-webpack-5
|
||||
// https://craco.js.org/docs/configuration/webpack/
|
||||
configure: (webpackConfig, { env, paths }) => {
|
||||
webpackConfig.resolve.fallback = {
|
||||
// "process": require.resolve('process/browser'),
|
||||
// "util": require.resolve("util/"),
|
||||
// "url": require.resolve("url/"),
|
||||
// "zlib": require.resolve("browserify-zlib"),
|
||||
// "stream": require.resolve("stream-browserify"),
|
||||
// "http": require.resolve("stream-http"),
|
||||
// "https": require.resolve("https-browserify"),
|
||||
// "assert": require.resolve("assert/"),
|
||||
"buffer": require.resolve('buffer/'),
|
||||
"process": false,
|
||||
"util": false,
|
||||
"url": false,
|
||||
"zlib": false,
|
||||
"stream": false,
|
||||
"http": false,
|
||||
"https": false,
|
||||
"assert": false,
|
||||
"buffer": false,
|
||||
};
|
||||
return webpackConfig;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
@ -9,11 +9,13 @@
|
||||
"@crowdin/cli": "^3.7.10",
|
||||
"@ctrl/tinycolor": "^3.5.0",
|
||||
"@emotion/react": "^11.10.5",
|
||||
"@metamask/eth-sig-util": "^6.0.0",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
"@testing-library/user-event": "^7.1.2",
|
||||
"antd": "5.2.3",
|
||||
"antd-token-previewer": "^1.1.0-22",
|
||||
"buffer": "^6.0.3",
|
||||
"codemirror": "^5.61.1",
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"core-js": "^3.25.0",
|
||||
@ -31,9 +33,11 @@
|
||||
"react-device-detect": "^2.2.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-github-corner": "^2.5.0",
|
||||
"react-google-one-tap-login": "^0.1.1",
|
||||
"react-helmet": "^6.1.0",
|
||||
"react-highlight-words": "^0.18.0",
|
||||
"react-i18next": "^11.8.7",
|
||||
"react-metamask-avatar": "^1.2.1",
|
||||
"react-router-dom": "^5.3.3",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-social-login-buttons": "^3.4.0"
|
||||
|
@ -68,7 +68,7 @@ class AdapterEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -80,8 +80,9 @@ class AdapterEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
models: res,
|
||||
models: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
114
web/src/App.js
114
web/src/App.js
@ -15,9 +15,7 @@
|
||||
import React, {Component} from "react";
|
||||
import "./App.less";
|
||||
import {Helmet} from "react-helmet";
|
||||
import GroupTreePage from "./GroupTreePage";
|
||||
import GroupEditPage from "./GroupEdit";
|
||||
import GroupListPage from "./GroupList";
|
||||
import {MfaRuleRequired} from "./Setting";
|
||||
import * as Setting from "./Setting";
|
||||
import {StyleProvider, legacyLogicalPropertiesTransformer} from "@ant-design/cssinjs";
|
||||
import {BarsOutlined, CommentOutlined, DownOutlined, InfoCircleFilled, LogoutOutlined, SettingOutlined} from "@ant-design/icons";
|
||||
@ -31,6 +29,11 @@ import RoleListPage from "./RoleListPage";
|
||||
import RoleEditPage from "./RoleEditPage";
|
||||
import PermissionListPage from "./PermissionListPage";
|
||||
import PermissionEditPage from "./PermissionEditPage";
|
||||
import EnforcerEditPage from "./EnforcerEditPage";
|
||||
import EnforcerListPage from "./EnforcerListPage";
|
||||
import GroupTreePage from "./GroupTreePage";
|
||||
import GroupEditPage from "./GroupEdit";
|
||||
import GroupListPage from "./GroupList";
|
||||
import ProviderListPage from "./ProviderListPage";
|
||||
import ProviderEditPage from "./ProviderEditPage";
|
||||
import ApplicationListPage from "./ApplicationListPage";
|
||||
@ -64,6 +67,13 @@ import ProductBuyPage from "./ProductBuyPage";
|
||||
import PaymentListPage from "./PaymentListPage";
|
||||
import PaymentEditPage from "./PaymentEditPage";
|
||||
import PaymentResultPage from "./PaymentResultPage";
|
||||
import ModelListPage from "./ModelListPage";
|
||||
import ModelEditPage from "./ModelEditPage";
|
||||
import AdapterListPage from "./AdapterListPage";
|
||||
import AdapterEditPage from "./AdapterEditPage";
|
||||
import SessionListPage from "./SessionListPage";
|
||||
import MfaSetupPage from "./auth/MfaSetupPage";
|
||||
import SystemInfo from "./SystemInfo";
|
||||
import AccountPage from "./account/AccountPage";
|
||||
import HomePage from "./basic/HomePage";
|
||||
import CustomGithubCorner from "./common/CustomGithubCorner";
|
||||
@ -73,20 +83,16 @@ import * as Auth from "./auth/Auth";
|
||||
import EntryPage from "./EntryPage";
|
||||
import * as AuthBackend from "./auth/AuthBackend";
|
||||
import AuthCallback from "./auth/AuthCallback";
|
||||
import LanguageSelect from "./common/select/LanguageSelect";
|
||||
import i18next from "i18next";
|
||||
import OdicDiscoveryPage from "./auth/OidcDiscoveryPage";
|
||||
import SamlCallback from "./auth/SamlCallback";
|
||||
import ModelListPage from "./ModelListPage";
|
||||
import ModelEditPage from "./ModelEditPage";
|
||||
import SystemInfo from "./SystemInfo";
|
||||
import AdapterListPage from "./AdapterListPage";
|
||||
import AdapterEditPage from "./AdapterEditPage";
|
||||
import i18next from "i18next";
|
||||
import {withTranslation} from "react-i18next";
|
||||
import EnableMfaNotification from "./common/notifaction/EnableMfaNotification";
|
||||
import LanguageSelect from "./common/select/LanguageSelect";
|
||||
import ThemeSelect from "./common/select/ThemeSelect";
|
||||
import SessionListPage from "./SessionListPage";
|
||||
import MfaSetupPage from "./auth/MfaSetupPage";
|
||||
import OrganizationSelect from "./common/select/OrganizationSelect";
|
||||
import {clearWeb3AuthToken} from "./auth/Web3Auth";
|
||||
import AccountAvatar from "./account/AccountAvatar";
|
||||
|
||||
const {Header, Footer, Content} = Layout;
|
||||
|
||||
@ -102,6 +108,7 @@ class App extends Component {
|
||||
themeAlgorithm: ["default"],
|
||||
themeData: Conf.ThemeDefault,
|
||||
logo: this.getLogo(Setting.getAlgorithmNames(Conf.ThemeDefault)),
|
||||
requiredEnableMfa: false,
|
||||
};
|
||||
|
||||
Setting.initServerUrl();
|
||||
@ -116,16 +123,29 @@ class App extends Component {
|
||||
this.getAccount();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
componentDidUpdate(prevProps, prevState, snapshot) {
|
||||
const uri = location.pathname;
|
||||
if (this.state.uri !== uri) {
|
||||
this.updateMenuKey();
|
||||
}
|
||||
|
||||
if (this.state.account !== prevState.account) {
|
||||
const requiredEnableMfa = Setting.isRequiredEnableMfa(this.state.account, this.state.account?.organization);
|
||||
this.setState({
|
||||
requiredEnableMfa: requiredEnableMfa,
|
||||
});
|
||||
|
||||
if (requiredEnableMfa === true) {
|
||||
const mfaType = Setting.getMfaItemsByRules(this.state.account, this.state.account?.organization, [MfaRuleRequired])
|
||||
.find((item) => item.rule === MfaRuleRequired)?.name;
|
||||
if (mfaType !== undefined) {
|
||||
this.props.history.push(`/mfa/setup?mfaType=${mfaType}`, {from: "/login"});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateMenuKey() {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const uri = location.pathname;
|
||||
this.setState({
|
||||
uri: uri,
|
||||
@ -146,6 +166,8 @@ class App extends Component {
|
||||
this.setState({selectedMenuKey: "/models"});
|
||||
} else if (uri.includes("/adapters")) {
|
||||
this.setState({selectedMenuKey: "/adapters"});
|
||||
} else if (uri.includes("/enforcers")) {
|
||||
this.setState({selectedMenuKey: "/enforcers"});
|
||||
} else if (uri.includes("/providers")) {
|
||||
this.setState({selectedMenuKey: "/providers"});
|
||||
} else if (uri.includes("/applications")) {
|
||||
@ -296,12 +318,11 @@ class App extends Component {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
const owner = this.state.account.owner;
|
||||
|
||||
this.setState({
|
||||
account: null,
|
||||
themeAlgorithm: ["default"],
|
||||
});
|
||||
|
||||
clearWeb3AuthToken();
|
||||
Setting.showMessage("success", i18next.t("application:Logged out successfully"));
|
||||
const redirectUri = res.data2;
|
||||
if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") {
|
||||
@ -332,7 +353,9 @@ class App extends Component {
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Avatar src={this.state.account.avatar} style={{verticalAlign: "middle"}} size="large">
|
||||
<Avatar src={this.state.account.avatar} style={{verticalAlign: "middle"}} size="large"
|
||||
icon={<AccountAvatar src={this.state.account.avatar} style={{verticalAlign: "middle"}} size={40} />}
|
||||
>
|
||||
{Setting.getShortName(this.state.account.name)}
|
||||
</Avatar>
|
||||
);
|
||||
@ -341,13 +364,15 @@ class App extends Component {
|
||||
|
||||
renderRightDropdown() {
|
||||
const items = [];
|
||||
items.push(Setting.getItem(<><SettingOutlined /> {i18next.t("account:My Account")}</>,
|
||||
"/account"
|
||||
));
|
||||
if (Conf.EnableChatPages) {
|
||||
items.push(Setting.getItem(<><CommentOutlined /> {i18next.t("account:Chats & Messages")}</>,
|
||||
"/chat"
|
||||
if (this.state.requiredEnableMfa === false) {
|
||||
items.push(Setting.getItem(<><SettingOutlined /> {i18next.t("account:My Account")}</>,
|
||||
"/account"
|
||||
));
|
||||
if (Conf.EnableChatPages) {
|
||||
items.push(Setting.getItem(<><CommentOutlined /> {i18next.t("account:Chats & Messages")}</>,
|
||||
"/chat"
|
||||
));
|
||||
}
|
||||
}
|
||||
items.push(Setting.getItem(<><LogoutOutlined /> {i18next.t("account:Logout")}</>,
|
||||
"/logout"));
|
||||
@ -460,6 +485,10 @@ class App extends Component {
|
||||
res.push(Setting.getItem(<Link to="/adapters">{i18next.t("general:Adapters")}</Link>,
|
||||
"/adapters"
|
||||
));
|
||||
|
||||
res.push(Setting.getItem(<Link to="/enforcers">{i18next.t("general:Enforcers")}</Link>,
|
||||
"/enforcers"
|
||||
));
|
||||
}
|
||||
|
||||
if (Setting.isLocalAdminUser(this.state.account)) {
|
||||
@ -547,14 +576,6 @@ class App extends Component {
|
||||
return res;
|
||||
}
|
||||
|
||||
renderHomeIfLoggedIn(component) {
|
||||
if (this.state.account !== null && this.state.account !== undefined) {
|
||||
return <Redirect to="/" />;
|
||||
} else {
|
||||
return component;
|
||||
}
|
||||
}
|
||||
|
||||
renderLoginIfNotLoggedIn(component) {
|
||||
if (this.state.account === null) {
|
||||
sessionStorage.setItem("from", window.location.pathname);
|
||||
@ -566,12 +587,6 @@ class App extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
isStartPages() {
|
||||
return window.location.pathname.startsWith("/login") ||
|
||||
window.location.pathname.startsWith("/signup") ||
|
||||
window.location.pathname === "/";
|
||||
}
|
||||
|
||||
renderRouter() {
|
||||
return (
|
||||
<Switch>
|
||||
@ -592,6 +607,8 @@ class App extends Component {
|
||||
<Route exact path="/permissions/:organizationName/:permissionName" render={(props) => this.renderLoginIfNotLoggedIn(<PermissionEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/models" render={(props) => this.renderLoginIfNotLoggedIn(<ModelListPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/models/:organizationName/:modelName" render={(props) => this.renderLoginIfNotLoggedIn(<ModelEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/enforcers" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerListPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/enforcers/:organizationName/:enforcerName" render={(props) => this.renderLoginIfNotLoggedIn(<EnforcerEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/adapters" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterListPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/adapters/:organizationName/:adapterName" render={(props) => this.renderLoginIfNotLoggedIn(<AdapterEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/providers" render={(props) => this.renderLoginIfNotLoggedIn(<ProviderListPage account={this.state.account} {...props} />)} />
|
||||
@ -629,7 +646,7 @@ class App extends Component {
|
||||
<Route exact path="/payments/:paymentName" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentEditPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/payments/:paymentName/result" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentResultPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/records" render={(props) => this.renderLoginIfNotLoggedIn(<RecordListPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/mfa-authentication/setup" render={(props) => this.renderLoginIfNotLoggedIn(<MfaSetupPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/mfa/setup" render={(props) => this.renderLoginIfNotLoggedIn(<MfaSetupPage account={this.state.account} onfinish={() => this.setState({requiredEnableMfa: false})} {...props} />)} />
|
||||
<Route exact path="/.well-known/openid-configuration" render={(props) => <OdicDiscoveryPage />} />
|
||||
<Route exact path="/sysinfo" render={(props) => this.renderLoginIfNotLoggedIn(<SystemInfo account={this.state.account} {...props} />)} />
|
||||
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
|
||||
@ -660,19 +677,24 @@ class App extends Component {
|
||||
if (key === "/swagger") {
|
||||
window.open(Setting.isLocalhost() ? `${Setting.ServerUrl}/swagger` : "/swagger", "_blank");
|
||||
} else {
|
||||
this.props.history.push(key);
|
||||
if (this.state.requiredEnableMfa) {
|
||||
Setting.showMessage("info", "Please enable MFA first!");
|
||||
} else {
|
||||
this.props.history.push(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
const menuStyleRight = Setting.isAdminUser(this.state.account) && !Setting.isMobile() ? "calc(180px + 260px)" : "260px";
|
||||
return (
|
||||
<Layout id="parent-area">
|
||||
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: this.state.themeAlgorithm.includes("dark") ? "black" : "white"}}>
|
||||
<EnableMfaNotification account={this.state.account} />
|
||||
<Header style={{padding: "0", marginBottom: "3px", backgroundColor: this.state.themeAlgorithm.includes("dark") ? "black" : "white"}} >
|
||||
{Setting.isMobile() ? null : (
|
||||
<Link to={"/"}>
|
||||
<div className="logo" style={{background: `url(${this.state.logo})`}} />
|
||||
</Link>
|
||||
)}
|
||||
{Setting.isMobile() ?
|
||||
{this.state.requiredEnableMfa || (Setting.isMobile() ?
|
||||
<React.Fragment>
|
||||
<Drawer title={i18next.t("general:Close")} placement="left" visible={this.state.menuVisible} onClose={this.onClose}>
|
||||
<Menu
|
||||
@ -695,7 +717,7 @@ class App extends Component {
|
||||
selectedKeys={[this.state.selectedMenuKey]}
|
||||
style={{position: "absolute", left: "145px", right: menuStyleRight}}
|
||||
/>
|
||||
}
|
||||
)}
|
||||
{
|
||||
this.renderAccountMenu()
|
||||
}
|
||||
@ -759,9 +781,11 @@ class App extends Component {
|
||||
<EntryPage
|
||||
account={this.state.account}
|
||||
theme={this.state.themeData}
|
||||
onUpdateAccount={(account) => {
|
||||
this.onUpdateAccount(account);
|
||||
onLoginSuccess={(redirectUrl) => {
|
||||
localStorage.setItem("mfaRedirectUrl", redirectUrl);
|
||||
this.getAccount();
|
||||
}}
|
||||
onUpdateAccount={(account) => this.onUpdateAccount(account)}
|
||||
updataThemeData={this.setTheme}
|
||||
/> :
|
||||
<Switch>
|
||||
|
@ -119,7 +119,7 @@ class ApplicationEditPage extends React.Component {
|
||||
getApplication() {
|
||||
ApplicationBackend.getApplication("admin", this.state.applicationName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -129,32 +129,33 @@ class ApplicationEditPage extends React.Component {
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.grantTypes === null || res.grantTypes === undefined || res.grantTypes.length === 0) {
|
||||
res.grantTypes = ["authorization_code"];
|
||||
const application = res.data;
|
||||
if (application.grantTypes === null || application.grantTypes === undefined || application.grantTypes.length === 0) {
|
||||
application.grantTypes = ["authorization_code"];
|
||||
}
|
||||
|
||||
if (res.tags === null || res.tags === undefined) {
|
||||
res.tags = [];
|
||||
if (application.tags === null || application.tags === undefined) {
|
||||
application.tags = [];
|
||||
}
|
||||
|
||||
this.setState({
|
||||
application: res,
|
||||
application: application,
|
||||
});
|
||||
|
||||
this.getCerts(res.organization);
|
||||
this.getCerts(application.organization);
|
||||
});
|
||||
}
|
||||
|
||||
getOrganizations() {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
if (res?.status === "error") {
|
||||
if (res.status === "error") {
|
||||
this.setState({
|
||||
isAuthorized: false,
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -164,7 +165,7 @@ class ApplicationEditPage extends React.Component {
|
||||
CertBackend.getCerts(owner)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
certs: (res.msg === undefined) ? res : [],
|
||||
certs: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -184,9 +185,9 @@ class ApplicationEditPage extends React.Component {
|
||||
|
||||
getSamlMetadata() {
|
||||
ApplicationBackend.getSamlMetadata("admin", this.state.applicationName)
|
||||
.then((res) => {
|
||||
.then((data) => {
|
||||
this.setState({
|
||||
samlMetadata: res,
|
||||
samlMetadata: data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ class CertEditPage extends React.Component {
|
||||
getCert() {
|
||||
CertBackend.getCert(this.state.owner, this.state.certName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -56,7 +56,7 @@ class CertEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
cert: res,
|
||||
cert: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -65,7 +65,7 @@ class CertEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -158,6 +158,7 @@ class CertEditPage extends React.Component {
|
||||
{
|
||||
[
|
||||
{id: "x509", name: "x509"},
|
||||
{id: "Payment", name: "Payment"},
|
||||
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
|
@ -151,6 +151,7 @@ class CertListPage extends BaseListPage {
|
||||
filterMultiple: false,
|
||||
filters: [
|
||||
{text: "x509", value: "x509"},
|
||||
{text: "Payment", value: "Payment"},
|
||||
],
|
||||
width: "110px",
|
||||
sorter: true,
|
||||
@ -213,7 +214,7 @@ class CertListPage extends BaseListPage {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={certs} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={certs} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
|
||||
title={() => (
|
||||
<div>
|
||||
{i18next.t("general:Certs")}
|
||||
|
@ -41,7 +41,7 @@ class ChatEditPage extends React.Component {
|
||||
getChat() {
|
||||
ChatBackend.getChat("admin", this.state.chatName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -51,10 +51,10 @@ class ChatEditPage extends React.Component {
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
chat: res,
|
||||
chat: res.data,
|
||||
});
|
||||
|
||||
this.getUsers(res.organization);
|
||||
this.getUsers(res.data.organization);
|
||||
});
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ class ChatEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -76,7 +76,7 @@ class ChatEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res,
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -79,7 +79,8 @@ class ChatPage extends BaseListPage {
|
||||
|
||||
getMessages(chatName) {
|
||||
MessageBackend.getChatMessages(chatName)
|
||||
.then((messages) => {
|
||||
.then((res) => {
|
||||
const messages = res.data;
|
||||
this.setState({
|
||||
messages: messages,
|
||||
});
|
||||
@ -229,7 +230,7 @@ class ChatPage extends BaseListPage {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<ChatBox messages={this.state.messages} sendMessage={(text) => {this.sendMessage(text);}} account={this.props.account} />
|
||||
<ChatBox messages={this.state.messages || []} sendMessage={(text) => {this.sendMessage(text);}} account={this.props.account} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
257
web/src/EnforcerEditPage.js
Normal file
257
web/src/EnforcerEditPage.js
Normal file
@ -0,0 +1,257 @@
|
||||
// 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.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, Row, Select, Switch} from "antd";
|
||||
import * as AdapterBackend from "./backend/AdapterBackend";
|
||||
import * as EnforcerBackend from "./backend/EnforcerBackend";
|
||||
import * as ModelBackend from "./backend/ModelBackend";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import * as Setting from "./Setting";
|
||||
import i18next from "i18next";
|
||||
|
||||
class EnforcerEditPage extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
classes: props,
|
||||
organizationName: props.organizationName !== undefined ? props.organizationName : props.match.params.organizationName,
|
||||
enforcerName: props.match.params.enforcerName,
|
||||
enforcer: null,
|
||||
organizations: [],
|
||||
models: [],
|
||||
adapters: [],
|
||||
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
||||
};
|
||||
}
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this.getEnforcer();
|
||||
this.getOrganizations();
|
||||
}
|
||||
|
||||
getEnforcer() {
|
||||
EnforcerBackend.getEnforcer(this.state.organizationName, this.state.enforcerName)
|
||||
.then((res) => {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
enforcer: res.data,
|
||||
});
|
||||
|
||||
this.getModels(this.state.organizationName);
|
||||
this.getAdapters(this.state.organizationName);
|
||||
});
|
||||
}
|
||||
|
||||
getOrganizations() {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getModels(organizationName) {
|
||||
ModelBackend.getModels(organizationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
models: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getAdapters(organizationName) {
|
||||
AdapterBackend.getAdapters(organizationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
adapters: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
parseEnforcerField(key, value) {
|
||||
if ([""].includes(key)) {
|
||||
value = Setting.myParseInt(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
updateEnforcerField(key, value) {
|
||||
value = this.parseEnforcerField(key, value);
|
||||
|
||||
const enforcer = this.state.enforcer;
|
||||
enforcer[key] = value;
|
||||
this.setState({
|
||||
enforcer: enforcer,
|
||||
});
|
||||
}
|
||||
|
||||
renderEnforcer() {
|
||||
return (
|
||||
<Card size="small" title={
|
||||
<div>
|
||||
{this.state.mode === "add" ? i18next.t("enforcer:New Enforcer") : i18next.t("enforcer:Edit Enforcer")}
|
||||
<Button onClick={() => this.submitEnforcerEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitEnforcerEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteEnforcer()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||
</div>
|
||||
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
|
||||
<Row style={{marginTop: "10px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} disabled={!Setting.isAdminUser(this.props.account)} value={this.state.enforcer.owner} onChange={(owner => {
|
||||
this.updateEnforcerField("owner", owner);
|
||||
this.getModels(owner);
|
||||
this.getAdapters(owner);
|
||||
})}
|
||||
options={this.state.organizations.map((organization) => Setting.getOption(organization.name, organization.name))
|
||||
} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.enforcer.name} onChange={e => {
|
||||
this.updateEnforcerField("name", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Display name"), i18next.t("general:Display name - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.enforcer.displayName} onChange={e => {
|
||||
this.updateEnforcerField("displayName", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Description"), i18next.t("general:Description - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.enforcer.description} onChange={e => {
|
||||
this.updateEnforcerField("description", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Model"), i18next.t("general:Model - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.enforcer.model} onChange={(model => {
|
||||
this.updateEnforcerField("model", model);
|
||||
})}
|
||||
options={this.state.models.map((model) => Setting.getOption(model.displayName, model.name))
|
||||
} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Adapter"), i18next.t("general:Adapter - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.enforcer.adapter} onChange={(adapter => {
|
||||
this.updateEnforcerField("adapter", adapter);
|
||||
})}
|
||||
options={this.state.adapters.map((adapter) => Setting.getOption(adapter.name, adapter.name))
|
||||
} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 19 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Is enabled"), i18next.t("general:Is enabled - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={1} >
|
||||
<Switch checked={this.state.enforcer.isEnabled} onChange={checked => {
|
||||
this.updateEnforcerField("isEnabled", checked);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
submitEnforcerEdit(willExist) {
|
||||
const enforcer = Setting.deepCopy(this.state.enforcer);
|
||||
EnforcerBackend.updateEnforcer(this.state.organizationName, this.state.enforcerName, enforcer)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully saved"));
|
||||
this.setState({
|
||||
enforcerName: this.state.enforcer.name,
|
||||
});
|
||||
|
||||
if (willExist) {
|
||||
this.props.history.push("/enforcers");
|
||||
} else {
|
||||
this.props.history.push(`/enforcers/${this.state.enforcer.owner}/${this.state.enforcer.name}`);
|
||||
}
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to save")}: ${res.msg}`);
|
||||
this.updateEnforcerField("name", this.state.enforcerName);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
deleteEnforcer() {
|
||||
EnforcerBackend.deleteEnforcer(this.state.enforcer)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.props.history.push("/enforcers");
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
this.state.enforcer !== null ? this.renderEnforcer() : null
|
||||
}
|
||||
<div style={{marginTop: "20px", marginLeft: "40px"}}>
|
||||
<Button size="large" onClick={() => this.submitEnforcerEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||
<Button style={{marginLeft: "20px"}} type="primary" size="large" onClick={() => this.submitEnforcerEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} size="large" onClick={() => this.deleteEnforcer()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EnforcerEditPage;
|
218
web/src/EnforcerListPage.js
Normal file
218
web/src/EnforcerListPage.js
Normal file
@ -0,0 +1,218 @@
|
||||
// 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.
|
||||
|
||||
import React from "react";
|
||||
import {Link} from "react-router-dom";
|
||||
import {Button, Switch, Table} from "antd";
|
||||
import moment from "moment";
|
||||
import * as Setting from "./Setting";
|
||||
import * as EnforcerBackend from "./backend/EnforcerBackend";
|
||||
import i18next from "i18next";
|
||||
import BaseListPage from "./BaseListPage";
|
||||
import PopconfirmModal from "./common/modal/PopconfirmModal";
|
||||
|
||||
class EnforcerListPage extends BaseListPage {
|
||||
newEnforcer() {
|
||||
const randomName = Setting.getRandomName();
|
||||
const owner = Setting.getRequestOrganization(this.props.account);
|
||||
return {
|
||||
owner: owner,
|
||||
name: `enforcer_${randomName}`,
|
||||
createdTime: moment().format(),
|
||||
displayName: `New Enforcer - ${randomName}`,
|
||||
isEnabled: true,
|
||||
};
|
||||
}
|
||||
|
||||
addEnforcer() {
|
||||
const newEnforcer = this.newEnforcer();
|
||||
EnforcerBackend.addEnforcer(newEnforcer)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.props.history.push({pathname: `/enforcers/${newEnforcer.owner}/${newEnforcer.name}`, mode: "add"});
|
||||
Setting.showMessage("success", i18next.t("general:Successfully added"));
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to add")}: ${res.msg}`);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
deleteEnforcer(i) {
|
||||
EnforcerBackend.deleteEnforcer(this.state.data[i])
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
Setting.showMessage("success", i18next.t("general:Successfully deleted"));
|
||||
this.setState({
|
||||
data: Setting.deleteRow(this.state.data, i),
|
||||
pagination: {total: this.state.pagination.total - 1},
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to delete")}: ${res.msg}`);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
Setting.showMessage("error", `${i18next.t("general:Failed to connect to server")}: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
renderTable(enforcers) {
|
||||
const columns = [
|
||||
{
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "name",
|
||||
key: "name",
|
||||
width: "150px",
|
||||
fixed: "left",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("name"),
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Link to={`/enforcers/${record.owner}/${text}`}>
|
||||
{text}
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Organization"),
|
||||
dataIndex: "owner",
|
||||
key: "owner",
|
||||
width: "120px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("owner"),
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Link to={`/organizations/${text}`}>
|
||||
{text}
|
||||
</Link>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Created time"),
|
||||
dataIndex: "createdTime",
|
||||
key: "createdTime",
|
||||
width: "160px",
|
||||
sorter: true,
|
||||
render: (text, record, index) => {
|
||||
return Setting.getFormattedDate(text);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Display name"),
|
||||
dataIndex: "displayName",
|
||||
key: "displayName",
|
||||
width: "200px",
|
||||
sorter: true,
|
||||
...this.getColumnSearchProps("displayName"),
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Is enabled"),
|
||||
dataIndex: "isEnabled",
|
||||
key: "isEnabled",
|
||||
width: "120px",
|
||||
sorter: true,
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Switch disabled checkedChildren="ON" unCheckedChildren="OFF" checked={text} />
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Action"),
|
||||
dataIndex: "",
|
||||
key: "op",
|
||||
width: "170px",
|
||||
fixed: (Setting.isMobile()) ? "false" : "right",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary"
|
||||
onClick={() => this.props.history.push(`/enforcers/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<PopconfirmModal
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteEnforcer(index)}
|
||||
>
|
||||
</PopconfirmModal>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const paginationProps = {
|
||||
total: this.state.pagination.total,
|
||||
showQuickJumper: true,
|
||||
showSizeChanger: true,
|
||||
showTotal: () => i18next.t("general:{total} in total").replace("{total}", this.state.pagination.total),
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={enforcers} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered
|
||||
pagination={paginationProps}
|
||||
title={() => (
|
||||
<div>
|
||||
{i18next.t("general:Enforcers")}
|
||||
<Button type="primary" size="small"
|
||||
onClick={this.addEnforcer.bind(this)}>{i18next.t("general:Add")}</Button>
|
||||
</div>
|
||||
)}
|
||||
loading={this.state.loading}
|
||||
onChange={this.handleTableChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
fetch = (params = {}) => {
|
||||
let field = params.searchedColumn, value = params.searchText;
|
||||
const sortField = params.sortField, sortOrder = params.sortOrder;
|
||||
if (params.type !== undefined && params.type !== null) {
|
||||
field = "type";
|
||||
value = params.type;
|
||||
}
|
||||
this.setState({loading: true});
|
||||
EnforcerBackend.getEnforcers(Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
loading: false,
|
||||
});
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
data: res.data,
|
||||
pagination: {
|
||||
...params.pagination,
|
||||
total: res.data2,
|
||||
},
|
||||
searchText: params.searchText,
|
||||
searchedColumn: params.searchedColumn,
|
||||
});
|
||||
} else {
|
||||
if (Setting.isResponseDenied(res)) {
|
||||
this.setState({
|
||||
isAuthorized: false,
|
||||
});
|
||||
} else {
|
||||
Setting.showMessage("error", res.msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default EnforcerListPage;
|
@ -41,7 +41,7 @@ class EntryPage extends React.Component {
|
||||
|
||||
renderHomeIfLoggedIn(component) {
|
||||
if (this.props.account !== null && this.props.account !== undefined) {
|
||||
return <Redirect to="/" />;
|
||||
return <Redirect to={{pathname: "/", state: {from: "/login"}}} />;
|
||||
} else {
|
||||
return component;
|
||||
}
|
||||
@ -79,7 +79,9 @@ class EntryPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
const themeData = res !== null ? Setting.getThemeData(res.organizationObj, res) : Conf.ThemeDefault;
|
||||
|
||||
const application = res.data;
|
||||
const themeData = application !== null ? Setting.getThemeData(application.organizationObj, application) : Conf.ThemeDefault;
|
||||
this.props.updataThemeData(themeData);
|
||||
});
|
||||
};
|
||||
|
@ -67,7 +67,7 @@ class GroupEditPage extends React.Component {
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
this.setState({
|
||||
organizations: res.data,
|
||||
organizations: res.data || [],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -55,7 +55,7 @@ class LdapEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ class MessageEditPage extends React.Component {
|
||||
getMessage() {
|
||||
MessageBackend.getMessage("admin", this.state.messageName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -54,11 +54,11 @@ class MessageEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
message: res,
|
||||
});
|
||||
|
||||
this.getUsers(res.organization);
|
||||
this.setState({
|
||||
message: res.data,
|
||||
});
|
||||
this.getUsers(res.data.organization);
|
||||
});
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ class MessageEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -75,7 +75,7 @@ class MessageEditPage extends React.Component {
|
||||
ChatBackend.getChats("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
chats: (res.msg === undefined) ? res : [],
|
||||
chats: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -87,8 +87,9 @@ class MessageEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res,
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class ModelEditPage extends React.Component {
|
||||
getModel() {
|
||||
ModelBackend.getModel(this.state.organizationName, this.state.modelName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -59,7 +59,7 @@ class ModelEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
model: res,
|
||||
model: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -68,7 +68,7 @@ class ModelEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ class OrganizationEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
applications: res,
|
||||
applications: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class OrganizationListPage extends BaseListPage {
|
||||
passwordType: "plain",
|
||||
PasswordSalt: "",
|
||||
passwordOptions: [],
|
||||
countryCodes: ["CN"],
|
||||
countryCodes: ["US"],
|
||||
defaultAvatar: `${Setting.StaticBaseUrl}/img/casbin.svg`,
|
||||
defaultApplication: "",
|
||||
tags: [],
|
||||
@ -53,25 +53,40 @@ class OrganizationListPage extends BaseListPage {
|
||||
{name: "Password", visible: true, viewRule: "Self", modifyRule: "Self"},
|
||||
{name: "Email", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Phone", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Country code", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Country/Region", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Location", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Address", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Affiliation", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Title", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "ID card type", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "ID card", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "ID card info", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Homepage", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Bio", visible: true, viewRule: "Public", modifyRule: "Self"},
|
||||
{name: "Tag", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Language", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Gender", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Birthday", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Education", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Score", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Karma", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Ranking", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Signup application", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "API key", label: i18next.t("general:API key")},
|
||||
{name: "API key", label: i18next.t("general:API key"), modifyRule: "Self"},
|
||||
{name: "Groups", visible: true, viewRule: "Public", modifyRule: "Admin"},
|
||||
{name: "Roles", visible: true, viewRule: "Public", modifyRule: "Immutable"},
|
||||
{name: "Permissions", visible: true, viewRule: "Public", modifyRule: "Immutable"},
|
||||
{name: "Groups", visible: true, viewRule: "Public", modifyRule: "Immutable"},
|
||||
{name: "3rd-party logins", visible: true, viewRule: "Self", modifyRule: "Self"},
|
||||
{Name: "Multi-factor authentication", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{name: "Properties", visible: false, viewRule: "Admin", modifyRule: "Admin"},
|
||||
{name: "Is online", visible: true, viewRule: "Admin", modifyRule: "Admin"},
|
||||
{name: "Is admin", visible: true, viewRule: "Admin", modifyRule: "Admin"},
|
||||
{name: "Is global admin", visible: true, viewRule: "Admin", modifyRule: "Admin"},
|
||||
{name: "Is forbidden", visible: true, viewRule: "Admin", modifyRule: "Admin"},
|
||||
{name: "Is deleted", visible: true, viewRule: "Admin", modifyRule: "Admin"},
|
||||
{Name: "Multi-factor authentication", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "WebAuthn credentials", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Managed accounts", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
@ -41,14 +41,14 @@ class PaymentEditPage extends React.Component {
|
||||
|
||||
getPayment() {
|
||||
PaymentBackend.getPayment("admin", this.state.paymentName)
|
||||
.then((payment) => {
|
||||
if (payment === null) {
|
||||
.then((res) => {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
payment: payment,
|
||||
payment: res.data,
|
||||
});
|
||||
|
||||
Setting.scrollToDiv("invoice-area");
|
||||
|
@ -41,12 +41,12 @@ class PaymentResultPage extends React.Component {
|
||||
|
||||
getPayment() {
|
||||
PaymentBackend.getPayment("admin", this.state.paymentName)
|
||||
.then((payment) => {
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
payment: payment,
|
||||
payment: res.data,
|
||||
});
|
||||
|
||||
if (payment.state === "Created") {
|
||||
if (res.data.state === "Created") {
|
||||
this.setState({timeout: setTimeout(() => this.getPayment(), 1000)});
|
||||
}
|
||||
});
|
||||
|
@ -50,7 +50,9 @@ class PermissionEditPage extends React.Component {
|
||||
getPermission() {
|
||||
PermissionBackend.getPermission(this.state.organizationName, this.state.permissionName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
const permission = res.data;
|
||||
|
||||
if (permission === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -61,14 +63,14 @@ class PermissionEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
permission: res,
|
||||
permission: permission,
|
||||
});
|
||||
|
||||
this.getUsers(res.owner);
|
||||
this.getRoles(res.owner);
|
||||
this.getModels(res.owner);
|
||||
this.getResources(res.owner);
|
||||
this.getModel(res.owner, res.model);
|
||||
this.getUsers(permission.owner);
|
||||
this.getRoles(permission.owner);
|
||||
this.getModels(permission.owner);
|
||||
this.getResources(permission.owner);
|
||||
this.getModel(permission.owner, permission.model);
|
||||
});
|
||||
}
|
||||
|
||||
@ -76,7 +78,7 @@ class PermissionEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -88,8 +90,9 @@ class PermissionEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res,
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -101,8 +104,9 @@ class PermissionEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
roles: res,
|
||||
roles: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -114,21 +118,21 @@ class PermissionEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
models: res,
|
||||
models: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getModel(organizationName, modelName) {
|
||||
if (modelName === "") {
|
||||
return;
|
||||
}
|
||||
ModelBackend.getModel(organizationName, modelName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
model: res,
|
||||
model: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -137,7 +141,7 @@ class PermissionEditPage extends React.Component {
|
||||
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
resources: (res.msg === undefined) ? res : [],
|
||||
resources: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -46,18 +46,18 @@ class PlanEditPage extends React.Component {
|
||||
|
||||
getPlan() {
|
||||
PlanBackend.getPlan(this.state.organizationName, this.state.planName)
|
||||
.then((plan) => {
|
||||
if (plan === null) {
|
||||
.then((res) => {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
plan: plan,
|
||||
plan: res.data,
|
||||
});
|
||||
|
||||
this.getUsers(plan.owner);
|
||||
this.getRoles(plan.owner);
|
||||
this.getUsers(this.state.organizationName);
|
||||
this.getRoles(this.state.organizationName);
|
||||
});
|
||||
}
|
||||
|
||||
@ -68,8 +68,9 @@ class PlanEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
roles: res,
|
||||
roles: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -81,8 +82,9 @@ class PlanEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res,
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -91,7 +93,7 @@ class PlanEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ class PlanListPage extends BaseListPage {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={plans} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={plans} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
|
||||
title={() => (
|
||||
<div>
|
||||
{i18next.t("general:Plans")}
|
||||
|
@ -44,13 +44,12 @@ class PricingEditPage extends React.Component {
|
||||
this.getPricing();
|
||||
this.getOrganizations();
|
||||
this.getApplicationsByOrganization(this.state.organizationName);
|
||||
this.getUserApplication();
|
||||
}
|
||||
|
||||
getPricing() {
|
||||
PricingBackend.getPricing(this.state.organizationName, this.state.pricingName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -61,9 +60,9 @@ class PricingEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
pricing: res,
|
||||
pricing: res.data,
|
||||
});
|
||||
this.getPlans(res.owner);
|
||||
this.getPlans(this.state.organizationName);
|
||||
});
|
||||
}
|
||||
|
||||
@ -74,8 +73,9 @@ class PricingEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
plans: res,
|
||||
plans: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -84,7 +84,16 @@ class PricingEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getApplicationsByOrganization(organizationName) {
|
||||
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
applications: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -107,28 +116,6 @@ class PricingEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getApplicationsByOrganization(organizationName) {
|
||||
ApplicationBackend.getApplicationsByOrganization("admin", organizationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
applications: (res.msg === undefined) ? res : [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getUserApplication() {
|
||||
ApplicationBackend.getUserApplication(this.state.organizationName, this.state.userName)
|
||||
.then((res) => {
|
||||
if (res.status === "error") {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
application: res,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
renderPricing() {
|
||||
return (
|
||||
<Card size="small" title={
|
||||
|
@ -165,7 +165,7 @@ class PricingListPage extends BaseListPage {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={pricings} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={pricings} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
|
||||
title={() => (
|
||||
<div>
|
||||
{i18next.t("general:Pricings")}
|
||||
|
@ -48,7 +48,7 @@ class ProductBuyPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
product: res,
|
||||
product: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -46,14 +46,14 @@ class ProductEditPage extends React.Component {
|
||||
|
||||
getProduct() {
|
||||
ProductBackend.getProduct(this.state.organizationName, this.state.productName)
|
||||
.then((product) => {
|
||||
if (product === null) {
|
||||
.then((res) => {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
product: product,
|
||||
product: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -62,7 +62,7 @@ class ProductEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class ProviderEditPage extends React.Component {
|
||||
getProvider() {
|
||||
ProviderBackend.getProvider(this.state.owner, this.state.providerName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -72,7 +72,7 @@ class ProviderEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: res.msg === undefined ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -236,7 +236,10 @@ class ProviderEditPage extends React.Component {
|
||||
tooltip = i18next.t("provider:Agent ID - Tooltip");
|
||||
}
|
||||
} else if (provider.category === "SMS") {
|
||||
if (provider.type === "Tencent Cloud SMS") {
|
||||
if (provider.type === "Twilio SMS") {
|
||||
text = i18next.t("provider:Sender number");
|
||||
tooltip = i18next.t("provider:Sender number - Tooltip");
|
||||
} else if (provider.type === "Tencent Cloud SMS") {
|
||||
text = i18next.t("provider:App ID");
|
||||
tooltip = i18next.t("provider:App ID - Tooltip");
|
||||
} else if (provider.type === "Volc Engine SMS") {
|
||||
@ -355,6 +358,8 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("type", "Default");
|
||||
} else if (value === "AI") {
|
||||
this.updateProviderField("type", "OpenAI API - GPT");
|
||||
} else if (value === "Web3") {
|
||||
this.updateProviderField("type", "MetaMask");
|
||||
}
|
||||
})}>
|
||||
{
|
||||
@ -367,6 +372,7 @@ class ProviderEditPage extends React.Component {
|
||||
{id: "SAML", name: "SAML"},
|
||||
{id: "SMS", name: "SMS"},
|
||||
{id: "Storage", name: "Storage"},
|
||||
{id: "Web3", name: "Web3"},
|
||||
]
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map((providerCategory, index) => <Option key={index} value={providerCategory.id}>{providerCategory.name}</Option>)
|
||||
@ -521,7 +527,7 @@ class ProviderEditPage extends React.Component {
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.provider.category === "Captcha" && this.state.provider.type === "Default" ? null : (
|
||||
(this.state.provider.category === "Captcha" && this.state.provider.type === "Default") || (this.state.provider.category === "Web3") || (this.state.provider.category === "Storage" && this.state.provider.type === "Local File System") ? null : (
|
||||
<React.Fragment>
|
||||
{
|
||||
this.state.provider.category === "AI" ? null : (
|
||||
@ -610,36 +616,42 @@ class ProviderEditPage extends React.Component {
|
||||
}
|
||||
{this.state.provider.category === "Storage" ? (
|
||||
<div>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Endpoint"), i18next.t("provider:Region endpoint for Internet"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.endpoint} onChange={e => {
|
||||
this.updateProviderField("endpoint", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.intranetEndpoint} onChange={e => {
|
||||
this.updateProviderField("intranetEndpoint", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.bucket} onChange={e => {
|
||||
this.updateProviderField("bucket", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
{["Local File System"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Endpoint"), i18next.t("provider:Region endpoint for Internet"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.endpoint} onChange={e => {
|
||||
this.updateProviderField("endpoint", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Local File System", "MinIO", "Tencent Cloud COS"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Endpoint (Intranet)"), i18next.t("provider:Region endpoint for Intranet"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.intranetEndpoint} onChange={e => {
|
||||
this.updateProviderField("intranetEndpoint", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["Local File System"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Bucket"), i18next.t("provider:Bucket - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.bucket} onChange={e => {
|
||||
this.updateProviderField("bucket", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Path prefix"), i18next.t("provider:Path prefix - Tooltip"))} :
|
||||
@ -650,17 +662,19 @@ class ProviderEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.domain} onChange={e => {
|
||||
this.updateProviderField("domain", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
{["AWS S3", "MinIO", "Tencent Cloud COS"].includes(this.state.provider.type) ? (
|
||||
{["MinIO"].includes(this.state.provider.type) ? null : (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<Input value={this.state.provider.domain} disabled={this.state.provider.type === "Local File System"} onChange={e => {
|
||||
this.updateProviderField("domain", e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
{["AWS S3", "Tencent Cloud COS"].includes(this.state.provider.type) ? (
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Region ID"), i18next.t("provider:Region ID - Tooltip"))} :
|
||||
@ -674,6 +688,7 @@ class ProviderEditPage extends React.Component {
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
{this.getAppIdRow(this.state.provider)}
|
||||
{
|
||||
this.state.provider.category === "Email" ? (
|
||||
<React.Fragment>
|
||||
@ -919,7 +934,6 @@ class ProviderEditPage extends React.Component {
|
||||
</Row>
|
||||
) : null
|
||||
}
|
||||
{this.getAppIdRow(this.state.provider)}
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Provider URL"), i18next.t("provider:Provider URL - Tooltip"))} :
|
||||
|
@ -43,7 +43,7 @@ class RoleEditPage extends React.Component {
|
||||
getRole() {
|
||||
RoleBackend.getRole(this.state.organizationName, this.state.roleName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -53,11 +53,11 @@ class RoleEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
role: res,
|
||||
role: res.data,
|
||||
});
|
||||
|
||||
this.getUsers(res.owner);
|
||||
this.getRoles(res.owner);
|
||||
this.getUsers(this.state.organizationName);
|
||||
this.getRoles(this.state.organizationName);
|
||||
});
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ class RoleEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -77,8 +77,9 @@ class RoleEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res,
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -90,8 +91,9 @@ class RoleEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
roles: res,
|
||||
roles: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -34,10 +34,10 @@ export const ServerUrl = "";
|
||||
export const StaticBaseUrl = "https://cdn.casbin.org";
|
||||
|
||||
export const Countries = [{label: "English", key: "en", country: "US", alt: "English"},
|
||||
{label: "中文", key: "zh", country: "CN", alt: "中文"},
|
||||
{label: "Español", key: "es", country: "ES", alt: "Español"},
|
||||
{label: "Français", key: "fr", country: "FR", alt: "Français"},
|
||||
{label: "Deutsch", key: "de", country: "DE", alt: "Deutsch"},
|
||||
{label: "中文", key: "zh", country: "CN", alt: "中文"},
|
||||
{label: "Indonesia", key: "id", country: "ID", alt: "Indonesia"},
|
||||
{label: "日本語", key: "ja", country: "JP", alt: "日本語"},
|
||||
{label: "한국어", key: "ko", country: "KR", alt: "한국어"},
|
||||
@ -216,6 +216,12 @@ export const OtherProviderInfo = {
|
||||
url: "https://platform.openai.com",
|
||||
},
|
||||
},
|
||||
Web3: {
|
||||
"MetaMask": {
|
||||
logo: `${StaticBaseUrl}/img/social_metamask.svg`,
|
||||
url: "https://metamask.io/",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export function initCountries() {
|
||||
@ -288,7 +294,7 @@ export function isProviderVisible(providerItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (providerItem.provider.category !== "OAuth" && providerItem.provider.category !== "SAML") {
|
||||
if (!["OAuth", "SAML", "Web3"].includes(providerItem.provider.category)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -482,6 +488,26 @@ export function isPromptAnswered(user, application) {
|
||||
return true;
|
||||
}
|
||||
|
||||
export const MfaRuleRequired = "Required";
|
||||
export const MfaRulePrompted = "Prompted";
|
||||
export const MfaRuleOptional = "Optional";
|
||||
|
||||
export function isRequiredEnableMfa(user, organization) {
|
||||
if (!user || !organization || !organization.mfaItems) {
|
||||
return false;
|
||||
}
|
||||
return getMfaItemsByRules(user, organization, [MfaRuleRequired]).length > 0;
|
||||
}
|
||||
|
||||
export function getMfaItemsByRules(user, organization, mfaRules = []) {
|
||||
if (!user || !organization || !organization.mfaItems) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return organization.mfaItems.filter((mfaItem) => mfaRules.includes(mfaItem.rule))
|
||||
.filter((mfaItem) => user.multiFactorAuths.some((mfa) => mfa.mfaType === mfaItem.name && !mfa.enabled));
|
||||
}
|
||||
|
||||
export function parseObject(s) {
|
||||
try {
|
||||
return eval("(" + s + ")");
|
||||
@ -871,6 +897,10 @@ export function getProviderTypeOptions(category) {
|
||||
return ([
|
||||
{id: "OpenAI API - GPT", name: "OpenAI API - GPT"},
|
||||
]);
|
||||
} else if (category === "Web3") {
|
||||
return ([
|
||||
{id: "MetaMask", name: "MetaMask"},
|
||||
]);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class SubscriptionEditPage extends React.Component {
|
||||
getSubscription() {
|
||||
SubscriptionBackend.getSubscription(this.state.organizationName, this.state.subscriptionName)
|
||||
.then((res) => {
|
||||
if (res === null) {
|
||||
if (res.data === null) {
|
||||
this.props.history.push("/404");
|
||||
return;
|
||||
}
|
||||
@ -58,11 +58,11 @@ class SubscriptionEditPage extends React.Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
subscription: res,
|
||||
subscription: res.data,
|
||||
});
|
||||
|
||||
this.getUsers(res.owner);
|
||||
this.getPlanes(res.owner);
|
||||
this.getUsers(this.state.organizationName);
|
||||
this.getPlanes(this.state.organizationName);
|
||||
});
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ class SubscriptionEditPage extends React.Component {
|
||||
PlanBackend.getPlans(organizationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
planes: res,
|
||||
planes: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -82,8 +82,9 @@ class SubscriptionEditPage extends React.Component {
|
||||
Setting.showMessage("error", res.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
users: res,
|
||||
users: res.data,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -92,7 +93,7 @@ class SubscriptionEditPage extends React.Component {
|
||||
OrganizationBackend.getOrganizations("admin")
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
organizations: (res.msg === undefined) ? res : [],
|
||||
organizations: res.data || [],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ class SubscriptionListPage extends BaseListPage {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={subscriptions} rowKey="name" size="middle" bordered pagination={paginationProps}
|
||||
<Table scroll={{x: "max-content"}} columns={columns} dataSource={subscriptions} rowKey={(record) => `${record.owner}/${record.name}`} size="middle" bordered pagination={paginationProps}
|
||||
title={() => (
|
||||
<div>
|
||||
{i18next.t("general:Subscriptions")}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user