Compare commits

..

54 Commits

Author SHA1 Message Date
Yaodong Yu
ea10f8e615 feat: make hard-coded authz adapter editable, rename adapter to ormer (#2149)
* refactor: rename casbinAdapter to casdoorAdapter

* feat: add initEnforcer

* fix: router

* refactor: make hard-coded code configurable

* fix: data type

* feat: support sqlite3

* feat: disable delete and edit name for built in resources

* feat: optimize code

* fix: init

* fix: e2e

* fix: remove datasourcename

* fix: revert rename

* refactor: change all ORM's Adatper to Ormer

* refactor: name
2023-07-29 15:07:04 +08:00
Yang Luo
74b058aa3f Fix sync-ldap-users() bug, brought by: 666ff48837 2023-07-29 13:14:55 +08:00
Yang Luo
6c628d7893 Fix static path not changed bug in makeGzipResponse() 2023-07-29 12:23:48 +08:00
Yang Luo
a38896e4d8 Improve swagger docs 2023-07-29 11:35:03 +08:00
Yang Luo
5f054c4989 Fix product links 2023-07-28 15:08:45 +08:00
Tower He
fb16d8cee6 fix: not set count of enforcers to the response (#2155) 2023-07-28 14:46:11 +08:00
Baihhh
5e4ba4f338 feat: add authorize button and defaultValue (#2152)
Signed-off-by: baihhh <2542274498@qq.com>
2023-07-27 23:55:35 +08:00
Yang Luo
ca47af2ee1 Make post_logout_redirect_uri optional for logout 2023-07-27 23:26:30 +08:00
Ilya Sulimanov
59da104463 fix: update ldap admin pwd only if changed (#2146)
* fix ldap pwd update

* fix: linter

* fix: simplify check
2023-07-27 17:49:15 +08:00
Yaodong Yu
c5bb916651 fix: fix response data in PricingPage.js (#2143) 2023-07-27 10:46:31 +08:00
WintBit
e98264f957 fix: application fails to call /api/get-resources (#2139)
just like other apis, resource.go.GetResources() no longer calls ApiController.RequireSignedInUser() to auth or check
2023-07-26 17:19:00 +08:00
June
6a952952a8 fix: unmask application for org admin (#2138)
* feat: unmask application with user admin

* Update application.go

---------

Co-authored-by: hsluoyz <hsluoyz@qq.com>
2023-07-26 17:17:49 +08:00
Yang Luo
ba8a0f36be Support custom actions in permission edit page 2023-07-26 14:49:45 +08:00
June
b5e9084e5d feat: en/decodeURI in permission/role name (#2137) 2023-07-26 13:08:35 +08:00
June
55d5ae10f2 fix: fix infinite loop in containsRole() (#2136) 2023-07-25 20:53:08 +08:00
Yang Luo
6986dad295 Use arg to control createDatabaseForPostgres() 2023-07-25 18:36:15 +08:00
Yaodong Yu
949feb18af feat: add basic enforcer manager (#2130)
* feat: add basic enforcer manager

* chore: generate swagger
2023-07-25 17:17:59 +08:00
haiwu
d1f88ca9b8 feat: support google one tap signin (#2131)
* feat: add google one tap support

* feat: gofumpt

* feat: add google provider rule conf

* feat: update i18n
2023-07-25 15:49:15 +08:00
Yaodong Yu
bfe8e5f3e7 fix: fix response data assignment error (#2129) 2023-07-25 13:52:31 +08:00
Yang Luo
702ee6acd0 Print log for StartLdapServer()'s error 2023-07-25 01:49:43 +08:00
Yaodong Yu
0a9587901a fix: fix response data assignment error in ApplicationEditPage.js (#2126) 2023-07-24 20:09:09 +08:00
Yaodong Yu
577bd6ce58 feat: fix response data assignment error (#2123) 2023-07-24 14:52:30 +08:00
Yaodong Yu
3c4112dd44 refactor: optimize the code to getEnforcer (#2120) 2023-07-24 14:02:34 +08:00
haiwu
b7a37126ad feat: restrict redirectUrls for CAS login (#2118)
* feat: support cas restricted login

* feat: add cas login i18n

* feat: add CheckCasService for all cas api

* feat: gofumpt

* feat: replace 404

* feat: reuse i18n

* feat: delete CheckCasService

* Update token_cas.go

* Update LoginPage.js

* Update token_cas.go

---------

Co-authored-by: hsluoyz <hsluoyz@qq.com>
2023-07-24 11:47:31 +08:00
UsherFall
8669d5bb0d chore: hide field of IntranetEndpoint in Tencent COS storage provider (#2117) 2023-07-23 19:02:42 +08:00
Baihhh
aee3ea4981 feat: improve TermsOfUse UI in mobile (#2106)
* style: Mobile interface adaptation

Signed-off-by: baihhh <2542274498@qq.com>

* Update index.css

---------

Signed-off-by: baihhh <2542274498@qq.com>
Co-authored-by: hsluoyz <hsluoyz@qq.com>
2023-07-23 15:28:13 +08:00
Yang Luo
516f4b7569 Fix response of /api/get-sorted-users and /api/get-user-count 2023-07-23 14:46:38 +08:00
UsherFall
7d7ca10481 fix: hide fields of minio storage provider (#2115)
* feat: hide field of minio storage provider

* feat: hide field of domain in minio storage provider
2023-07-23 14:40:30 +08:00
UsherFall
a9d4978a0f chore: hide fields of local file system storage provider (#2109)
* style: adjust local file system storage

* style: disable domain when use local file system
2023-07-23 11:48:15 +08:00
Yang Luo
09f40bb5ce Fix id of "/api/get-resource" API 2023-07-23 11:33:48 +08:00
Yaodong Yu
a6f803aff1 feat: refactor code to use responseOK everywhere (#2111)
* refactor: use responseOK return frontend format json data

* revert handle error

* revert handle error
2023-07-23 09:49:16 +08:00
Yang Luo
fc9528be43 Add createDatabaseForPostgres() 2023-07-22 16:19:13 +08:00
imp2002
58e8f9f90b feat: fix Effect in Casbin rule (#2103)
* fix: Add `Effect` to Casbin rule of role

fix: https://github.com/casdoor/casdoor/issues/2102

* Update permission_enforcer.go

---------

Co-authored-by: hsluoyz <hsluoyz@qq.com>
2023-07-21 18:01:37 +08:00
Yang Luo
e850e33f37 Fix error message of missing cert when login 2023-07-20 19:45:22 +08:00
haiwu
d7110ff8bf feat: support MetaMask provider (#2084)
* feat: add metamask provider

* feat: add eth login

* feat: check eth sign

* feat: finish metamask signin/signup

* feat: support MetaMask provider link/unlink

* feat: update web/craco.config.js to handle polyfill

* feat: gofumpt idp/metamask.go

* feat: update MetaMask logo path

* feat: support MetaMask avatar
2023-07-20 17:51:36 +08:00
f923a8f0d7 fix: provide detailed description of ldap in swagger (#2094)
* provide detailed description of ldap in swagger

* modify the directory of swagger

fix: provide detailed description of ldap in swagger
2023-07-20 12:32:48 +08:00
Yang Luo
7bfb74ba18 Fix typo 2023-07-19 19:34:43 +08:00
Yang Luo
38f031bc86 Show access secret if isAdminOrSelf is true in get-user and get-account APIs 2023-07-19 19:14:53 +08:00
Yang Luo
5c441d195c Add Effect to Casbin rule of add-permission 2023-07-19 18:52:22 +08:00
Yaodong Yu
0639564d27 fix: check group name cannot be same as organization name (#2090) 2023-07-19 11:37:28 +08:00
Yang Luo
6c647818ca feat: add "Sender number" input for Twilio SMS provider 2023-07-18 22:46:56 +08:00
Yaodong Yu
8bc73d17aa feat: fix bug that themeEditor can not load saved theme data (#2085) 2023-07-17 22:57:55 +08:00
Yang Luo
1f37c80177 feat: refactor code to add getStorageProvider() 2023-07-17 15:59:37 +08:00
Yaodong Yu
7924fca403 fix: hidden bug of "like" query (#2082) 2023-07-16 17:11:32 +08:00
Yang Luo
bd06996bab Improve CorsFilter for login API 2023-07-15 19:29:48 +08:00
Yang Luo
19ab168b12 Fix panic in func (c *ApiController) GetUser() if no user exists in DB 2023-07-14 20:57:59 +08:00
UsherFall
854a74b73e feat: fix the error when user uploads avatar to minio (https) (#2078)
* fix: Error reported when user uploads avatar to minio (https)

* Update provider.go

---------

Co-authored-by: hsluoyz <hsluoyz@qq.com>
2023-07-14 15:58:30 +08:00
yehong
beefb0b432 fix: fix event-stream streaming output in prod mode (#2076) 2023-07-14 11:59:26 +08:00
Yang Luo
d8969e6652 Support EnableSigninSession after SAML login 2023-07-14 11:27:18 +08:00
Yang Luo
666ff48837 Use id param in /sync-ldap-users API 2023-07-13 00:14:18 +08:00
Yang Luo
0a0c1b4788 Fix "Groups is immutable" bug when updating a user 2023-07-13 00:03:18 +08:00
Yang Luo
438c999e11 Add password mask to /get-ldaps and /get-ldap APIs 2023-07-12 23:21:47 +08:00
Yang Luo
a193ceb33d Fix bug in TestDeployStaticFiles() 2023-07-12 23:11:02 +08:00
Yang Luo
caec1d1bac Only consider x509 certs in /.well-known/jwks API 2023-07-12 22:39:39 +08:00
165 changed files with 4365 additions and 1679 deletions

View File

@@ -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()

View File

@@ -18,56 +18,22 @@ import (
"strings"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"
xormadapter "github.com/casdoor/xorm-adapter/v3"
stringadapter "github.com/qiangmzsx/string-adapter/v2"
)
var Enforcer *casbin.Enforcer
func InitAuthz() {
func InitApi() {
var err error
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
driverName := conf.GetConfigString("driverName")
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
a, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, "casbin_rule", tableNamePrefix, true)
e, err := object.GetEnforcer(util.GetId("built-in", "api-enforcer-built-in"))
if err != nil {
panic(err)
}
modelText := `
[request_definition]
r = subOwner, subName, method, urlPath, objOwner, objName
[policy_definition]
p = subOwner, subName, method, urlPath, objOwner, objName
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (r.subOwner == p.subOwner || p.subOwner == "*") && \
(r.subName == p.subName || p.subName == "*" || r.subName != "anonymous" && p.subName == "!anonymous") && \
(r.method == p.method || p.method == "*") && \
(r.urlPath == p.urlPath || p.urlPath == "*") && \
(r.objOwner == p.objOwner || p.objOwner == "*") && \
(r.objName == p.objName || p.objName == "*") || \
(r.subOwner == r.objOwner && r.subName == r.objName)
`
m, err := model.NewModelFromString(modelText)
if err != nil {
panic(err)
}
Enforcer, err = casbin.NewEnforcer(m, a)
Enforcer, err = e.InitEnforcer()
if err != nil {
panic(err)
}

View File

@@ -290,10 +290,11 @@ func (c *ApiController) Logout() {
c.ResponseOk(user, application.HomepageUrl)
return
} else {
if redirectUri == "" {
c.ResponseError(c.T("general:Missing parameter") + ": post_logout_redirect_uri")
return
}
// "post_logout_redirect_uri" has been made optional, see: https://github.com/casdoor/casdoor/issues/2151
// if redirectUri == "" {
// c.ResponseError(c.T("general:Missing parameter") + ": post_logout_redirect_uri")
// return
// }
if accessToken == "" {
c.ResponseError(c.T("general:Missing parameter") + ": id_token_hint")
return
@@ -368,9 +369,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 +381,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

View File

@@ -23,14 +23,14 @@ import (
xormadapter "github.com/casdoor/xorm-adapter/v3"
)
// GetCasbinAdapters
// @Title GetCasbinAdapters
// GetAdapters
// @Title GetAdapters
// @Tag Adapter API
// @Description get adapters
// @Param owner query string true "The owner of adapters"
// @Success 200 {array} object.Adapter The Response object
// @router /get-adapters [get]
func (c *ApiController) GetCasbinAdapters() {
func (c *ApiController) GetAdapters() {
owner := c.Input().Get("owner")
limit := c.Input().Get("pageSize")
page := c.Input().Get("p")
@@ -40,7 +40,7 @@ func (c *ApiController) GetCasbinAdapters() {
sortOrder := c.Input().Get("sortOrder")
if limit == "" || page == "" {
adapters, err := object.GetCasbinAdapters(owner)
adapters, err := object.GetAdapters(owner)
if err != nil {
c.ResponseError(err.Error())
return
@@ -49,14 +49,14 @@ func (c *ApiController) GetCasbinAdapters() {
c.ResponseOk(adapters)
} else {
limit := util.ParseInt(limit)
count, err := object.GetCasbinAdapterCount(owner, field, value)
count, err := object.GetAdapterCount(owner, field, value)
if err != nil {
c.ResponseError(err.Error())
return
}
paginator := pagination.SetPaginator(c.Ctx, limit, count)
adapters, err := object.GetPaginationCasbinAdapters(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
adapters, err := object.GetPaginationAdapters(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
if err != nil {
c.ResponseError(err.Error())
return
@@ -66,17 +66,17 @@ func (c *ApiController) GetCasbinAdapters() {
}
}
// GetCasbinAdapter
// @Title GetCasbinAdapter
// GetAdapter
// @Title GetAdapter
// @Tag Adapter API
// @Description get adapter
// @Param id query string true "The id ( owner/name ) of the adapter"
// @Success 200 {object} object.Adapter The Response object
// @router /get-adapter [get]
func (c *ApiController) GetCasbinAdapter() {
func (c *ApiController) GetAdapter() {
id := c.Input().Get("id")
adapter, err := object.GetCasbinAdapter(id)
adapter, err := object.GetAdapter(id)
if err != nil {
c.ResponseError(err.Error())
return
@@ -85,69 +85,69 @@ func (c *ApiController) GetCasbinAdapter() {
c.ResponseOk(adapter)
}
// UpdateCasbinAdapter
// @Title UpdateCasbinAdapter
// UpdateAdapter
// @Title UpdateAdapter
// @Tag Adapter API
// @Description update adapter
// @Param id query string true "The id ( owner/name ) of the adapter"
// @Param body body object.Adapter true "The details of the adapter"
// @Success 200 {object} controllers.Response The Response object
// @router /update-adapter [post]
func (c *ApiController) UpdateCasbinAdapter() {
func (c *ApiController) UpdateAdapter() {
id := c.Input().Get("id")
var casbinAdapter object.CasbinAdapter
err := json.Unmarshal(c.Ctx.Input.RequestBody, &casbinAdapter)
var adapter object.Adapter
err := json.Unmarshal(c.Ctx.Input.RequestBody, &adapter)
if err != nil {
c.ResponseError(err.Error())
return
}
c.Data["json"] = wrapActionResponse(object.UpdateCasbinAdapter(id, &casbinAdapter))
c.Data["json"] = wrapActionResponse(object.UpdateAdapter(id, &adapter))
c.ServeJSON()
}
// AddCasbinAdapter
// @Title AddCasbinAdapter
// AddAdapter
// @Title AddAdapter
// @Tag Adapter API
// @Description add adapter
// @Param body body object.Adapter true "The details of the adapter"
// @Success 200 {object} controllers.Response The Response object
// @router /add-adapter [post]
func (c *ApiController) AddCasbinAdapter() {
var casbinAdapter object.CasbinAdapter
err := json.Unmarshal(c.Ctx.Input.RequestBody, &casbinAdapter)
func (c *ApiController) AddAdapter() {
var adapter object.Adapter
err := json.Unmarshal(c.Ctx.Input.RequestBody, &adapter)
if err != nil {
c.ResponseError(err.Error())
return
}
c.Data["json"] = wrapActionResponse(object.AddCasbinAdapter(&casbinAdapter))
c.Data["json"] = wrapActionResponse(object.AddAdapter(&adapter))
c.ServeJSON()
}
// DeleteCasbinAdapter
// @Title DeleteCasbinAdapter
// DeleteAdapter
// @Title DeleteAdapter
// @Tag Adapter API
// @Description delete adapter
// @Param body body object.Adapter true "The details of the adapter"
// @Success 200 {object} controllers.Response The Response object
// @router /delete-adapter [post]
func (c *ApiController) DeleteCasbinAdapter() {
var casbinAdapter object.CasbinAdapter
err := json.Unmarshal(c.Ctx.Input.RequestBody, &casbinAdapter)
func (c *ApiController) DeleteAdapter() {
var adapter object.Adapter
err := json.Unmarshal(c.Ctx.Input.RequestBody, &adapter)
if err != nil {
c.ResponseError(err.Error())
return
}
c.Data["json"] = wrapActionResponse(object.DeleteCasbinAdapter(&casbinAdapter))
c.Data["json"] = wrapActionResponse(object.DeleteAdapter(&adapter))
c.ServeJSON()
}
func (c *ApiController) SyncPolicies() {
id := c.Input().Get("id")
adapter, err := object.GetCasbinAdapter(id)
adapter, err := object.GetAdapter(id)
if err != nil {
c.ResponseError(err.Error())
return
@@ -164,7 +164,7 @@ func (c *ApiController) SyncPolicies() {
func (c *ApiController) UpdatePolicy() {
id := c.Input().Get("id")
adapter, err := object.GetCasbinAdapter(id)
adapter, err := object.GetAdapter(id)
if err != nil {
c.ResponseError(err.Error())
return
@@ -188,7 +188,7 @@ func (c *ApiController) UpdatePolicy() {
func (c *ApiController) AddPolicy() {
id := c.Input().Get("id")
adapter, err := object.GetCasbinAdapter(id)
adapter, err := object.GetAdapter(id)
if err != nil {
c.ResponseError(err.Error())
return
@@ -212,7 +212,7 @@ func (c *ApiController) AddPolicy() {
func (c *ApiController) RemovePolicy() {
id := c.Input().Get("id")
adapter, err := object.GetCasbinAdapter(id)
adapter, err := object.GetAdapter(id)
if err != nil {
c.ResponseError(err.Error())
return

View File

@@ -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)

View File

@@ -123,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")
@@ -135,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))
}
@@ -417,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)
@@ -460,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())
@@ -481,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 != "" {

View File

@@ -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/") {

226
controllers/casbin_api.go Normal file
View 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))
}

View File

@@ -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

View File

@@ -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

View File

@@ -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, paginator.Nums())
}
}
// 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()
}

View File

@@ -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

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -52,14 +52,6 @@ func (c *ApiController) GetResources() {
sortField := c.Input().Get("sortField")
sortOrder := c.Input().Get("sortOrder")
userObj, ok := c.RequireSignedInUser()
if !ok {
return
}
if userObj.IsAdmin {
user = ""
}
if limit == "" || page == "" {
resources, err := object.GetResources(owner, user)
if err != nil {
@@ -67,8 +59,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)
@@ -104,8 +95,7 @@ func (c *ApiController) GetResource() {
return
}
c.Data["json"] = resource
c.ServeJSON()
c.ResponseOk(resource)
}
// UpdateResource

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -26,9 +26,10 @@ import (
// @Title GetWebhooks
// @Tag Webhook API
// @Description get webhooks
// @Param owner query string true "The owner of webhooks"
// @Param owner query string built-in/admin true "The owner of webhooks"
// @Success 200 {array} object.Webhook The Response object
// @router /get-webhooks [get]
// @Security test_apiKey
func (c *ApiController) GetWebhooks() {
owner := c.Input().Get("owner")
limit := c.Input().Get("pageSize")
@@ -46,8 +47,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)
@@ -72,7 +72,7 @@ func (c *ApiController) GetWebhooks() {
// @Title GetWebhook
// @Tag Webhook API
// @Description get webhook
// @Param id query string true "The id ( owner/name ) of the webhook"
// @Param id query string built-in/admin true "The id ( owner/name ) of the webhook"
// @Success 200 {object} object.Webhook The Response object
// @router /get-webhook [get]
func (c *ApiController) GetWebhook() {
@@ -84,15 +84,14 @@ func (c *ApiController) GetWebhook() {
return
}
c.Data["json"] = webhook
c.ServeJSON()
c.ResponseOk(webhook)
}
// UpdateWebhook
// @Title UpdateWebhook
// @Tag Webhook API
// @Description update webhook
// @Param id query string true "The id ( owner/name ) of the webhook"
// @Param id query string built-in/admin true "The id ( owner/name ) of the webhook"
// @Param body body object.Webhook true "The details of the webhook"
// @Success 200 {object} controllers.Response The Response object
// @router /update-webhook [post]

View File

@@ -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
View File

@@ -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=

View File

@@ -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
View 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
}

View File

@@ -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)

View File

@@ -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())
}
}

View File

@@ -39,7 +39,7 @@ func getCreateDatabaseFlag() bool {
func main() {
createDatabase := getCreateDatabaseFlag()
object.InitAdapter()
object.InitAdapter(createDatabase)
object.CreateTables(createDatabase)
object.DoMigration()
@@ -48,7 +48,7 @@ func main() {
object.InitDefaultStorageProvider()
object.InitLdapAutoSynchronizer()
proxy.InitHttpClient()
authz.InitAuthz()
authz.InitApi()
util.SafeGoroutine(func() { object.RunSyncUsersJob() })
@@ -62,7 +62,7 @@ func main() {
beego.InsertFilter("*", beego.BeforeRouter, routers.StaticFilter)
beego.InsertFilter("*", beego.BeforeRouter, routers.AutoSigninFilter)
beego.InsertFilter("*", beego.BeforeRouter, routers.CorsFilter)
beego.InsertFilter("*", beego.BeforeRouter, routers.AuthzFilter)
beego.InsertFilter("*", beego.BeforeRouter, routers.ApiFilter)
beego.InsertFilter("*", beego.BeforeRouter, routers.PrometheusFilter)
beego.InsertFilter("*", beego.BeforeRouter, routers.RecordMessage)

View File

@@ -1,4 +1,4 @@
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
// 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.
@@ -16,325 +16,351 @@ package object
import (
"fmt"
"runtime"
"strings"
"github.com/beego/beego"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/util"
xormadapter "github.com/casdoor/xorm-adapter/v3"
_ "github.com/denisenkom/go-mssqldb" // db = mssql
_ "github.com/go-sql-driver/mysql" // db = mysql
_ "github.com/lib/pq" // db = postgres
"github.com/xorm-io/core"
"github.com/xorm-io/xorm"
_ "modernc.org/sqlite" // db = sqlite
)
var adapter *Adapter
type Adapter 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"`
func InitConfig() {
err := beego.LoadAppConfig("ini", "../conf/app.conf")
Type string `xorm:"varchar(100)" json:"type"`
Model string `xorm:"varchar(100)" json:"model"`
DatabaseType string `xorm:"varchar(100)" json:"databaseType"`
Host string `xorm:"varchar(100)" json:"host"`
Port string `xorm:"varchar(20)" json:"port"`
User string `xorm:"varchar(100)" json:"user"`
Password string `xorm:"varchar(100)" json:"password"`
Database string `xorm:"varchar(100)" json:"database"`
Table string `xorm:"varchar(100)" json:"table"`
TableNamePrefix string `xorm:"varchar(100)" json:"tableNamePrefix"`
File string `xorm:"varchar(100)" json:"file"`
IsEnabled bool `json:"isEnabled"`
Adapter *xormadapter.Adapter `xorm:"-" json:"-"`
}
func GetAdapterCount(owner, field, value string) (int64, error) {
session := GetSession(owner, -1, -1, field, value, "", "")
return session.Count(&Adapter{})
}
func GetAdapters(owner string) ([]*Adapter, error) {
adapters := []*Adapter{}
err := ormer.Engine.Desc("created_time").Find(&adapters, &Adapter{Owner: owner})
if err != nil {
panic(err)
return adapters, err
}
beego.BConfig.WebConfig.Session.SessionOn = true
InitAdapter()
CreateTables(true)
DoMigration()
return adapters, nil
}
func InitAdapter() {
adapter = NewAdapter(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
func GetPaginationAdapters(owner string, offset, limit int, field, value, sortField, sortOrder string) ([]*Adapter, error) {
adapters := []*Adapter{}
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
err := session.Find(&adapters)
if err != nil {
return adapters, err
}
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, tableNamePrefix)
adapter.Engine.SetTableMapper(tbMapper)
return adapters, nil
}
func CreateTables(createDatabase bool) {
if createDatabase {
err := adapter.CreateDatabase()
func getAdapter(owner, name string) (*Adapter, error) {
if owner == "" || name == "" {
return nil, nil
}
adapter := Adapter{Owner: owner, Name: name}
existed, err := ormer.Engine.Get(&adapter)
if err != nil {
return nil, err
}
if existed {
return &adapter, nil
} else {
return nil, nil
}
}
func GetAdapter(id string) (*Adapter, error) {
owner, name := util.GetOwnerAndNameFromId(id)
return getAdapter(owner, name)
}
func UpdateAdapter(id string, adapter *Adapter) (bool, error) {
owner, name := util.GetOwnerAndNameFromId(id)
if adapter, err := getAdapter(owner, name); adapter == nil {
return false, err
}
if name != adapter.Name {
err := adapterChangeTrigger(name, adapter.Name)
if err != nil {
panic(err)
return false, err
}
}
adapter.createTable()
}
// Adapter represents the MySQL adapter for policy storage.
type Adapter struct {
driverName string
dataSourceName string
dbName string
Engine *xorm.Engine
}
// finalizer is the destructor for Adapter.
func finalizer(a *Adapter) {
err := a.Engine.Close()
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()
if adapter.Password == "***" {
session.Omit("password")
}
affected, err := session.Update(adapter)
if err != nil {
panic(err)
return false, err
}
return affected != 0, nil
}
func AddAdapter(adapter *Adapter) (bool, error) {
affected, err := ormer.Engine.Insert(adapter)
if err != nil {
return false, err
}
return affected != 0, nil
}
func DeleteAdapter(adapter *Adapter) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{adapter.Owner, adapter.Name}).Delete(&Adapter{})
if err != nil {
return false, err
}
return affected != 0, nil
}
func (adapter *Adapter) GetId() string {
return fmt.Sprintf("%s/%s", adapter.Owner, adapter.Name)
}
func (adapter *Adapter) getTable() string {
if adapter.DatabaseType == "mssql" {
return fmt.Sprintf("[%s]", adapter.Table)
} else {
return adapter.Table
}
}
// NewAdapter is the constructor for Adapter.
func NewAdapter(driverName string, dataSourceName string, dbName string) *Adapter {
a := &Adapter{}
a.driverName = driverName
a.dataSourceName = dataSourceName
a.dbName = dbName
func initEnforcer(modelObj *Model, adapter *Adapter) (*casbin.Enforcer, error) {
// init Adapter
if adapter.Adapter == nil {
var dataSourceName string
if adapter.DatabaseType == "mssql" {
dataSourceName = fmt.Sprintf("sqlserver://%s:%s@%s:%s?database=%s", adapter.User, adapter.Password, adapter.Host, adapter.Port, adapter.Database)
} else if adapter.DatabaseType == "postgres" {
dataSourceName = fmt.Sprintf("user=%s password=%s host=%s port=%s sslmode=disable dbname=%s", adapter.User, adapter.Password, adapter.Host, adapter.Port, adapter.Database)
} else {
dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%s)/", adapter.User, adapter.Password, adapter.Host, adapter.Port)
}
// Open the DB, create it if not existed.
a.open()
if !isCloudIntranet {
dataSourceName = strings.ReplaceAll(dataSourceName, "dbi.", "db.")
}
// Call the destructor when the object is released.
runtime.SetFinalizer(a, finalizer)
var err error
adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(NewAdapter(adapter.DatabaseType, dataSourceName, adapter.Database).Engine, adapter.getTable(), "")
if err != nil {
return nil, err
}
}
return a
// init Model
m, err := model.NewModelFromString(modelObj.ModelText)
if err != nil {
return nil, err
}
// init Enforcer
enforcer, err := casbin.NewEnforcer(m, adapter.Adapter)
if err != nil {
return nil, err
}
return enforcer, nil
}
func (a *Adapter) CreateDatabase() error {
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
func (adapter *Adapter) initAdapter() (*xormadapter.Adapter, error) {
// init Adapter
if adapter.Adapter == nil {
var dataSourceName string
if adapter.buildInAdapter() {
dataSourceName = conf.GetConfigString("dataSourceName")
} else {
switch adapter.DatabaseType {
case "mssql":
dataSourceName = fmt.Sprintf("sqlserver://%s:%s@%s:%s?database=%s", adapter.User,
adapter.Password, adapter.Host, adapter.Port, adapter.Database)
case "mysql":
dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%s)/", adapter.User,
adapter.Password, adapter.Host, adapter.Port)
case "postgres":
dataSourceName = fmt.Sprintf("user=%s password=%s host=%s port=%s sslmode=disable dbname=%s", adapter.User,
adapter.Password, adapter.Host, adapter.Port, adapter.Database)
case "CockroachDB":
dataSourceName = fmt.Sprintf("user=%s password=%s host=%s port=%s sslmode=disable dbname=%s serial_normalization=virtual_sequence",
adapter.User, adapter.Password, adapter.Host, adapter.Port, adapter.Database)
case "sqlite3":
dataSourceName = fmt.Sprintf("file:%s", adapter.File)
default:
return nil, fmt.Errorf("unsupported database type: %s", adapter.DatabaseType)
}
}
if !isCloudIntranet {
dataSourceName = strings.ReplaceAll(dataSourceName, "dbi.", "db.")
}
var err error
adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(NewAdapter(adapter.DatabaseType, dataSourceName, adapter.Database).Engine, adapter.getTable(), adapter.TableNamePrefix)
if err != nil {
return nil, err
}
}
return adapter.Adapter, nil
}
func adapterChangeTrigger(oldName string, newName string) error {
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
if err != nil {
return err
}
defer engine.Close()
_, err = engine.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s default charset utf8mb4 COLLATE utf8mb4_general_ci", a.dbName))
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 (a *Adapter) open() {
dataSourceName := a.dataSourceName + a.dbName
if a.driverName != "mysql" {
dataSourceName = a.dataSourceName
}
engine, err := xorm.NewEngine(a.driverName, dataSourceName)
if err != nil {
panic(err)
}
a.Engine = engine
}
func (a *Adapter) close() {
_ = a.Engine.Close()
a.Engine = nil
}
func (a *Adapter) createTable() {
showSql := conf.GetConfigBool("showSql")
a.Engine.ShowSQL(showSql)
err := a.Engine.Sync2(new(Organization))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(User))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Group))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Role))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Permission))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Model))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(CasbinAdapter))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Provider))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Application))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Resource))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Token))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(VerificationRecord))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Record))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Webhook))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Syncer))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Cert))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Chat))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Message))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Product))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Payment))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Ldap))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(PermissionRule))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(xormadapter.CasbinRule))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Session))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Subscription))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Plan))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Pricing))
if err != nil {
panic(err)
}
}
func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
session := adapter.Engine.Prepare()
if offset != -1 && limit != -1 {
session.Limit(limit, offset)
}
if owner != "" {
session = session.And("owner=?", owner)
}
if field != "" && value != "" {
if util.FilterField(field) {
session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
}
}
if sortField == "" || sortOrder == "" {
sortField = "created_time"
}
if sortOrder == "ascend" {
session = session.Asc(util.SnakeString(sortField))
func safeReturn(policy []string, i int) string {
if len(policy) > i {
return policy[i]
} else {
session = session.Desc(util.SnakeString(sortField))
return ""
}
return session
}
func GetSessionForUser(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
session := adapter.Engine.Prepare()
if offset != -1 && limit != -1 {
session.Limit(limit, offset)
}
if owner != "" {
if offset == -1 {
session = session.And("owner=?", owner)
} else {
session = session.And("a.owner=?", owner)
func matrixToCasbinRules(Ptype string, policies [][]string) []*xormadapter.CasbinRule {
res := []*xormadapter.CasbinRule{}
for _, policy := range policies {
line := xormadapter.CasbinRule{
Ptype: Ptype,
V0: safeReturn(policy, 0),
V1: safeReturn(policy, 1),
V2: safeReturn(policy, 2),
V3: safeReturn(policy, 3),
V4: safeReturn(policy, 4),
V5: safeReturn(policy, 5),
}
}
if field != "" && value != "" {
if util.FilterField(field) {
if offset != -1 {
field = fmt.Sprintf("a.%s", field)
}
session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
}
}
if sortField == "" || sortOrder == "" {
sortField = "created_time"
res = append(res, &line)
}
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
tableName := tableNamePrefix + "user"
if offset == -1 {
if sortOrder == "ascend" {
session = session.Asc(util.SnakeString(sortField))
} else {
session = session.Desc(util.SnakeString(sortField))
}
} else {
if sortOrder == "ascend" {
session = session.Alias("a").
Join("INNER", []string{tableName, "b"}, "a.owner = b.owner and a.name = b.name").
Select("b.*").
Asc("a." + util.SnakeString(sortField))
} else {
session = session.Alias("a").
Join("INNER", []string{tableName, "b"}, "a.owner = b.owner and a.name = b.name").
Select("b.*").
Desc("a." + util.SnakeString(sortField))
}
}
return session
return res
}
func SyncPolicies(adapter *Adapter) ([]*xormadapter.CasbinRule, error) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
if err != nil {
return nil, err
}
if modelObj == nil {
return nil, fmt.Errorf("The model: %s does not exist", util.GetId(adapter.Owner, adapter.Model))
}
enforcer, err := initEnforcer(modelObj, adapter)
if err != nil {
return nil, err
}
policies := matrixToCasbinRules("p", enforcer.GetPolicy())
if strings.Contains(modelObj.ModelText, "[role_definition]") {
policies = append(policies, matrixToCasbinRules("g", enforcer.GetGroupingPolicy())...)
}
return policies, nil
}
func UpdatePolicy(oldPolicy, newPolicy []string, adapter *Adapter) (bool, error) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, adapter)
if err != nil {
return false, err
}
affected, err := enforcer.UpdatePolicy(oldPolicy, newPolicy)
if err != nil {
return affected, err
}
return affected, nil
}
func AddPolicy(policy []string, adapter *Adapter) (bool, error) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, adapter)
if err != nil {
return false, err
}
affected, err := enforcer.AddPolicy(policy)
if err != nil {
return affected, err
}
return affected, nil
}
func RemovePolicy(policy []string, adapter *Adapter) (bool, error) {
modelObj, err := getModel(adapter.Owner, adapter.Model)
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, adapter)
if err != nil {
return false, err
}
affected, err := enforcer.RemovePolicy(policy)
if err != nil {
return affected, err
}
return affected, nil
}
func (adapter *Adapter) buildInAdapter() bool {
if adapter.Owner != "built-in" {
return false
}
return adapter.Name == "permission-adapter-built-in" || adapter.Name == "api-adapter-built-in"
}

View File

@@ -92,7 +92,7 @@ func GetOrganizationApplicationCount(owner, Organization, field, value string) (
func GetApplications(owner string) ([]*Application, error) {
applications := []*Application{}
err := adapter.Engine.Desc("created_time").Find(&applications, &Application{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&applications, &Application{Owner: owner})
if err != nil {
return applications, err
}
@@ -102,7 +102,7 @@ func GetApplications(owner string) ([]*Application, error) {
func GetOrganizationApplications(owner string, organization string) ([]*Application, error) {
applications := []*Application{}
err := adapter.Engine.Desc("created_time").Find(&applications, &Application{Organization: organization})
err := ormer.Engine.Desc("created_time").Find(&applications, &Application{Organization: organization})
if err != nil {
return applications, err
}
@@ -182,7 +182,7 @@ func getApplication(owner string, name string) (*Application, error) {
}
application := Application{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&application)
existed, err := ormer.Engine.Get(&application)
if err != nil {
return nil, err
}
@@ -206,7 +206,7 @@ func getApplication(owner string, name string) (*Application, error) {
func GetApplicationByOrganizationName(organization string) (*Application, error) {
application := Application{}
existed, err := adapter.Engine.Where("organization=?", organization).Get(&application)
existed, err := ormer.Engine.Where("organization=?", organization).Get(&application)
if err != nil {
return nil, nil
}
@@ -253,7 +253,7 @@ func GetApplicationByUserId(userId string) (application *Application, err error)
func GetApplicationByClientId(clientId string) (*Application, error) {
application := Application{}
existed, err := adapter.Engine.Where("client_id=?", clientId).Get(&application)
existed, err := ormer.Engine.Where("client_id=?", clientId).Get(&application)
if err != nil {
return nil, err
}
@@ -281,14 +281,21 @@ func GetApplication(id string) (*Application, error) {
}
func GetMaskedApplication(application *Application, userId string) *Application {
if isUserIdGlobalAdmin(userId) {
return application
}
if application == nil {
return nil
}
if userId != "" {
if isUserIdGlobalAdmin(userId) {
return application
}
user, _ := GetUser(userId)
if user != nil && user.IsApplicationAdmin(application) {
return application
}
}
if application.ClientSecret != "" {
application.ClientSecret = "***"
}
@@ -349,7 +356,7 @@ func UpdateApplication(id string, application *Application) (bool, error) {
providerItem.Provider = nil
}
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()
if application.ClientSecret == "***" {
session.Omit("client_secret")
}
@@ -388,7 +395,7 @@ func AddApplication(application *Application) (bool, error) {
providerItem.Provider = nil
}
affected, err := adapter.Engine.Insert(application)
affected, err := ormer.Engine.Insert(application)
if err != nil {
return false, nil
}
@@ -401,7 +408,7 @@ func DeleteApplication(application *Application) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{application.Owner, application.Name}).Delete(&Application{})
affected, err := ormer.Engine.ID(core.PK{application.Owner, application.Name}).Delete(&Application{})
if err != nil {
return false, err
}
@@ -477,7 +484,7 @@ func ExtendManagedAccountsWithUser(user *User) (*User, error) {
}
func applicationChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
@@ -507,7 +514,7 @@ func applicationChangeTrigger(oldName string, newName string) error {
}
var permissions []*Permission
err = adapter.Engine.Find(&permissions)
err = ormer.Engine.Find(&permissions)
if err != nil {
return err
}

View File

@@ -1,286 +0,0 @@
// 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 object
import (
"fmt"
"strings"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
"github.com/casdoor/casdoor/util"
xormadapter "github.com/casdoor/xorm-adapter/v3"
"github.com/xorm-io/core"
)
type CasbinAdapter 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"`
Type string `xorm:"varchar(100)" json:"type"`
Model string `xorm:"varchar(100)" json:"model"`
Host string `xorm:"varchar(100)" json:"host"`
Port int `json:"port"`
User string `xorm:"varchar(100)" json:"user"`
Password string `xorm:"varchar(100)" json:"password"`
DatabaseType string `xorm:"varchar(100)" json:"databaseType"`
Database string `xorm:"varchar(100)" json:"database"`
Table string `xorm:"varchar(100)" json:"table"`
IsEnabled bool `json:"isEnabled"`
Adapter *xormadapter.Adapter `xorm:"-" json:"-"`
}
func GetCasbinAdapterCount(owner, field, value string) (int64, error) {
session := GetSession(owner, -1, -1, field, value, "", "")
return session.Count(&CasbinAdapter{})
}
func GetCasbinAdapters(owner string) ([]*CasbinAdapter, error) {
adapters := []*CasbinAdapter{}
err := adapter.Engine.Desc("created_time").Find(&adapters, &CasbinAdapter{Owner: owner})
if err != nil {
return adapters, err
}
return adapters, nil
}
func GetPaginationCasbinAdapters(owner string, offset, limit int, field, value, sortField, sortOrder string) ([]*CasbinAdapter, error) {
adapters := []*CasbinAdapter{}
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
err := session.Find(&adapters)
if err != nil {
return adapters, err
}
return adapters, nil
}
func getCasbinAdapter(owner, name string) (*CasbinAdapter, error) {
if owner == "" || name == "" {
return nil, nil
}
casbinAdapter := CasbinAdapter{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&casbinAdapter)
if err != nil {
return nil, err
}
if existed {
return &casbinAdapter, nil
} else {
return nil, nil
}
}
func GetCasbinAdapter(id string) (*CasbinAdapter, error) {
owner, name := util.GetOwnerAndNameFromId(id)
return getCasbinAdapter(owner, name)
}
func UpdateCasbinAdapter(id string, casbinAdapter *CasbinAdapter) (bool, error) {
owner, name := util.GetOwnerAndNameFromId(id)
if casbinAdapter, err := getCasbinAdapter(owner, name); casbinAdapter == nil {
return false, err
}
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
if casbinAdapter.Password == "***" {
session.Omit("password")
}
affected, err := session.Update(casbinAdapter)
if err != nil {
return false, err
}
return affected != 0, nil
}
func AddCasbinAdapter(casbinAdapter *CasbinAdapter) (bool, error) {
affected, err := adapter.Engine.Insert(casbinAdapter)
if err != nil {
return false, err
}
return affected != 0, nil
}
func DeleteCasbinAdapter(casbinAdapter *CasbinAdapter) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{casbinAdapter.Owner, casbinAdapter.Name}).Delete(&CasbinAdapter{})
if err != nil {
return false, err
}
return affected != 0, nil
}
func (casbinAdapter *CasbinAdapter) GetId() string {
return fmt.Sprintf("%s/%s", casbinAdapter.Owner, casbinAdapter.Name)
}
func (casbinAdapter *CasbinAdapter) getTable() string {
if casbinAdapter.DatabaseType == "mssql" {
return fmt.Sprintf("[%s]", casbinAdapter.Table)
} else {
return casbinAdapter.Table
}
}
func initEnforcer(modelObj *Model, casbinAdapter *CasbinAdapter) (*casbin.Enforcer, error) {
// init Adapter
if casbinAdapter.Adapter == nil {
var dataSourceName string
if casbinAdapter.DatabaseType == "mssql" {
dataSourceName = fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s", casbinAdapter.User, casbinAdapter.Password, casbinAdapter.Host, casbinAdapter.Port, casbinAdapter.Database)
} else if casbinAdapter.DatabaseType == "postgres" {
dataSourceName = fmt.Sprintf("user=%s password=%s host=%s port=%d sslmode=disable dbname=%s", casbinAdapter.User, casbinAdapter.Password, casbinAdapter.Host, casbinAdapter.Port, casbinAdapter.Database)
} else {
dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%d)/", casbinAdapter.User, casbinAdapter.Password, casbinAdapter.Host, casbinAdapter.Port)
}
if !isCloudIntranet {
dataSourceName = strings.ReplaceAll(dataSourceName, "dbi.", "db.")
}
var err error
casbinAdapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(NewAdapter(casbinAdapter.DatabaseType, dataSourceName, casbinAdapter.Database).Engine, casbinAdapter.getTable(), "")
if err != nil {
return nil, err
}
}
// init Model
m, err := model.NewModelFromString(modelObj.ModelText)
if err != nil {
return nil, err
}
// init Enforcer
enforcer, err := casbin.NewEnforcer(m, casbinAdapter.Adapter)
if err != nil {
return nil, err
}
return enforcer, nil
}
func safeReturn(policy []string, i int) string {
if len(policy) > i {
return policy[i]
} else {
return ""
}
}
func matrixToCasbinRules(Ptype string, policies [][]string) []*xormadapter.CasbinRule {
res := []*xormadapter.CasbinRule{}
for _, policy := range policies {
line := xormadapter.CasbinRule{
Ptype: Ptype,
V0: safeReturn(policy, 0),
V1: safeReturn(policy, 1),
V2: safeReturn(policy, 2),
V3: safeReturn(policy, 3),
V4: safeReturn(policy, 4),
V5: safeReturn(policy, 5),
}
res = append(res, &line)
}
return res
}
func SyncPolicies(casbinAdapter *CasbinAdapter) ([]*xormadapter.CasbinRule, error) {
modelObj, err := getModel(casbinAdapter.Owner, casbinAdapter.Model)
if err != nil {
return nil, err
}
if modelObj == nil {
return nil, fmt.Errorf("The model: %s does not exist", util.GetId(casbinAdapter.Owner, casbinAdapter.Model))
}
enforcer, err := initEnforcer(modelObj, casbinAdapter)
if err != nil {
return nil, err
}
policies := matrixToCasbinRules("p", enforcer.GetPolicy())
if strings.Contains(modelObj.ModelText, "[role_definition]") {
policies = append(policies, matrixToCasbinRules("g", enforcer.GetGroupingPolicy())...)
}
return policies, nil
}
func UpdatePolicy(oldPolicy, newPolicy []string, casbinAdapter *CasbinAdapter) (bool, error) {
modelObj, err := getModel(casbinAdapter.Owner, casbinAdapter.Model)
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, casbinAdapter)
if err != nil {
return false, err
}
affected, err := enforcer.UpdatePolicy(oldPolicy, newPolicy)
if err != nil {
return affected, err
}
return affected, nil
}
func AddPolicy(policy []string, casbinAdapter *CasbinAdapter) (bool, error) {
modelObj, err := getModel(casbinAdapter.Owner, casbinAdapter.Model)
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, casbinAdapter)
if err != nil {
return false, err
}
affected, err := enforcer.AddPolicy(policy)
if err != nil {
return affected, err
}
return affected, nil
}
func RemovePolicy(policy []string, casbinAdapter *CasbinAdapter) (bool, error) {
modelObj, err := getModel(casbinAdapter.Owner, casbinAdapter.Model)
if err != nil {
return false, err
}
enforcer, err := initEnforcer(modelObj, casbinAdapter)
if err != nil {
return false, err
}
affected, err := enforcer.RemovePolicy(policy)
if err != nil {
return affected, err
}
return affected, nil
}

View File

@@ -65,7 +65,7 @@ func GetCertCount(owner, field, value string) (int64, error) {
func GetCerts(owner string) ([]*Cert, error) {
certs := []*Cert{}
err := adapter.Engine.Where("owner = ? or owner = ? ", "admin", owner).Desc("created_time").Find(&certs, &Cert{})
err := ormer.Engine.Where("owner = ? or owner = ? ", "admin", owner).Desc("created_time").Find(&certs, &Cert{})
if err != nil {
return certs, err
}
@@ -91,7 +91,7 @@ func GetGlobalCertsCount(field, value string) (int64, error) {
func GetGlobleCerts() ([]*Cert, error) {
certs := []*Cert{}
err := adapter.Engine.Desc("created_time").Find(&certs)
err := ormer.Engine.Desc("created_time").Find(&certs)
if err != nil {
return certs, err
}
@@ -116,7 +116,7 @@ func getCert(owner string, name string) (*Cert, error) {
}
cert := Cert{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&cert)
existed, err := ormer.Engine.Get(&cert)
if err != nil {
return &cert, err
}
@@ -134,7 +134,7 @@ func getCertByName(name string) (*Cert, error) {
}
cert := Cert{Name: name}
existed, err := adapter.Engine.Get(&cert)
existed, err := ormer.Engine.Get(&cert)
if err != nil {
return &cert, nil
}
@@ -165,7 +165,7 @@ func UpdateCert(id string, cert *Cert) (bool, error) {
return false, nil
}
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(cert)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(cert)
if err != nil {
return false, err
}
@@ -180,7 +180,7 @@ func AddCert(cert *Cert) (bool, error) {
cert.PrivateKey = privateKey
}
affected, err := adapter.Engine.Insert(cert)
affected, err := ormer.Engine.Insert(cert)
if err != nil {
return false, err
}
@@ -189,7 +189,7 @@ func AddCert(cert *Cert) (bool, error) {
}
func DeleteCert(cert *Cert) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{cert.Owner, cert.Name}).Delete(&Cert{})
affected, err := ormer.Engine.ID(core.PK{cert.Owner, cert.Name}).Delete(&Cert{})
if err != nil {
return false, err
}
@@ -214,7 +214,7 @@ func GetDefaultCert() (*Cert, error) {
}
func certChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()

View File

@@ -70,7 +70,7 @@ func GetChatCount(owner, field, value string) (int64, error) {
func GetChats(owner string) ([]*Chat, error) {
chats := []*Chat{}
err := adapter.Engine.Desc("created_time").Find(&chats, &Chat{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&chats, &Chat{Owner: owner})
if err != nil {
return chats, err
}
@@ -95,7 +95,7 @@ func getChat(owner string, name string) (*Chat, error) {
}
chat := Chat{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&chat)
existed, err := ormer.Engine.Get(&chat)
if err != nil {
return &chat, err
}
@@ -120,7 +120,7 @@ func UpdateChat(id string, chat *Chat) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(chat)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(chat)
if err != nil {
return false, nil
}
@@ -140,7 +140,7 @@ func AddChat(chat *Chat) (bool, error) {
}
}
affected, err := adapter.Engine.Insert(chat)
affected, err := ormer.Engine.Insert(chat)
if err != nil {
return false, nil
}
@@ -149,7 +149,7 @@ func AddChat(chat *Chat) (bool, error) {
}
func DeleteChat(chat *Chat) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{chat.Owner, chat.Name}).Delete(&Chat{})
affected, err := ormer.Engine.ID(core.PK{chat.Owner, chat.Name}).Delete(&Chat{})
if err != nil {
return false, err
}

View File

@@ -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
}

163
object/enforcer.go Normal file
View File

@@ -0,0 +1,163 @@
// 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 (
"errors"
"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 := ormer.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 := ormer.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 := ormer.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 := ormer.Engine.Insert(enforcer)
if err != nil {
return false, err
}
return affected != 0, nil
}
func DeleteEnforcer(enforcer *Enforcer) (bool, error) {
affected, err := ormer.Engine.ID(core.PK{enforcer.Owner, enforcer.Name}).Delete(&Enforcer{})
if err != nil {
return false, err
}
return affected != 0, nil
}
func (enforcer *Enforcer) InitEnforcer() (*casbin.Enforcer, error) {
if enforcer == nil {
return nil, errors.New("enforcer is nil")
}
if enforcer.Model == "" || enforcer.Adapter == "" {
return nil, errors.New("missing model or adapter")
}
var err error
var m *Model
var a *Adapter
if m, err = GetModel(enforcer.Model); err != nil {
return nil, err
} else if m == nil {
return nil, errors.New("model not found")
}
if a, err = GetAdapter(enforcer.Adapter); err != nil {
return nil, err
} else if a == nil {
return nil, errors.New("adapter not found")
}
casbinModel, err := m.initModel()
if err != nil {
return nil, err
}
adapter, err := a.initAdapter()
if err != nil {
return nil, err
}
e, err := casbin.NewEnforcer(casbinModel, adapter)
if err != nil {
return nil, err
}
return e, nil
}

View File

@@ -58,7 +58,7 @@ func GetGroupCount(owner, field, value string) (int64, error) {
func GetGroups(owner string) ([]*Group, error) {
groups := []*Group{}
err := adapter.Engine.Desc("created_time").Find(&groups, &Group{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&groups, &Group{Owner: owner})
if err != nil {
return nil, err
}
@@ -83,7 +83,7 @@ func getGroup(owner string, name string) (*Group, error) {
}
group := Group{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&group)
existed, err := ormer.Engine.Get(&group)
if err != nil {
return nil, err
}
@@ -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 {
@@ -114,7 +119,7 @@ func UpdateGroup(id string, group *Group) (bool, error) {
}
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(group)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(group)
if err != nil {
return false, err
}
@@ -123,7 +128,12 @@ func UpdateGroup(id string, group *Group) (bool, error) {
}
func AddGroup(group *Group) (bool, error) {
affected, err := adapter.Engine.Insert(group)
err := checkGroupName(group.Name)
if err != nil {
return false, err
}
affected, err := ormer.Engine.Insert(group)
if err != nil {
return false, err
}
@@ -135,7 +145,7 @@ func AddGroups(groups []*Group) (bool, error) {
if len(groups) == 0 {
return false, nil
}
affected, err := adapter.Engine.Insert(groups)
affected, err := ormer.Engine.Insert(groups)
if err != nil {
return false, err
}
@@ -143,12 +153,12 @@ func AddGroups(groups []*Group) (bool, error) {
}
func DeleteGroup(group *Group) (bool, error) {
_, err := adapter.Engine.Get(group)
_, err := ormer.Engine.Get(group)
if err != nil {
return false, err
}
if count, err := adapter.Engine.Where("parent_id = ?", group.Name).Count(&Group{}); err != nil {
if count, err := ormer.Engine.Where("parent_id = ?", group.Name).Count(&Group{}); err != nil {
return false, err
} else if count > 0 {
return false, errors.New("group has children group")
@@ -160,7 +170,7 @@ func DeleteGroup(group *Group) (bool, error) {
return false, errors.New("group has users")
}
affected, err := adapter.Engine.ID(core.PK{group.Owner, group.Name}).Delete(&Group{})
affected, err := ormer.Engine.ID(core.PK{group.Owner, group.Name}).Delete(&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 := ormer.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)
}
@@ -212,10 +233,10 @@ func RemoveUserFromGroup(owner, name, groupName string) (bool, error) {
func GetGroupUserCount(groupName string, field, value string) (int64, error) {
if field == "" && value == "" {
return adapter.Engine.Where(builder.Like{"`groups`", groupName}).
return ormer.Engine.Where(builder.Like{"`groups`", groupName}).
Count(&User{})
} else {
return adapter.Engine.Table("user").
return ormer.Engine.Table("user").
Where(builder.Like{"`groups`", groupName}).
And(fmt.Sprintf("user.%s LIKE ?", util.CamelToSnakeCase(field)), "%"+value+"%").
Count()
@@ -224,8 +245,8 @@ 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})
session := ormer.Engine.Table("user").
Where(builder.Like{"`groups`", groupName + "\""})
if offset != -1 && limit != -1 {
session.Limit(limit, offset)
@@ -254,8 +275,8 @@ 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}).
err := ormer.Engine.Table("user").
Where(builder.Like{"`groups`", groupName + "\""}).
Find(&users)
if err != nil {
return nil, err
@@ -265,7 +286,7 @@ func GetGroupUsers(groupName string) ([]*User, error) {
}
func GroupChangeTrigger(oldName, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
if err != nil {

View File

@@ -27,7 +27,6 @@ import (
func InitDb() {
existed := initBuiltInOrganization()
if !existed {
initBuiltInModel()
initBuiltInPermission()
initBuiltInProvider()
initBuiltInUser()
@@ -36,6 +35,15 @@ func InitDb() {
initBuiltInLdap()
}
existed = initBuiltInApiModel()
if !existed {
initBuildInApiAdapter()
initBuiltInApiEnforcer()
initBuiltInPermissionModel()
initBuildInPermissionAdapter()
initBuiltInPermissionEnforcer()
}
initWebAuthn()
}
@@ -295,8 +303,8 @@ func initWebAuthn() {
gob.Register(webauthn.SessionData{})
}
func initBuiltInModel() {
model, err := GetModel("built-in/model-built-in")
func initBuiltInPermissionModel() {
model, err := GetModel("built-in/permission-model-built-in")
if err != nil {
panic(err)
}
@@ -307,7 +315,7 @@ func initBuiltInModel() {
model = &Model{
Owner: "built-in",
Name: "model-built-in",
Name: "permission-model-built-in",
CreatedTime: util.GetCurrentTime(),
DisplayName: "Built-in Model",
IsEnabled: true,
@@ -329,6 +337,54 @@ m = r.sub == p.sub && r.obj == p.obj && r.act == p.act`,
}
}
func initBuiltInApiModel() bool {
model, err := GetModel("built-in/api-model-built-in")
if err != nil {
panic(err)
}
if model != nil {
return true
}
modelText := `
[request_definition]
r = subOwner, subName, method, urlPath, objOwner, objName
[policy_definition]
p = subOwner, subName, method, urlPath, objOwner, objName
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = (r.subOwner == p.subOwner || p.subOwner == "*") && \
(r.subName == p.subName || p.subName == "*" || r.subName != "anonymous" && p.subName == "!anonymous") && \
(r.method == p.method || p.method == "*") && \
(r.urlPath == p.urlPath || p.urlPath == "*") && \
(r.objOwner == p.objOwner || p.objOwner == "*") && \
(r.objName == p.objName || p.objName == "*") || \
(r.subOwner == r.objOwner && r.subName == r.objName)
`
model = &Model{
Owner: "built-in",
Name: "api-model-built-in",
CreatedTime: util.GetCurrentTime(),
DisplayName: "API Model",
IsEnabled: true,
ModelText: modelText,
}
_, err = AddModel(model)
if err != nil {
panic(err)
}
return false
}
func initBuiltInPermission() {
permission, err := GetPermission("built-in/permission-built-in")
if err != nil {
@@ -358,3 +414,109 @@ func initBuiltInPermission() {
panic(err)
}
}
func initBuildInPermissionAdapter() {
permissionAdapter, err := GetAdapter("built-in/permission-adapter-built-in")
if err != nil {
panic(err)
}
if permissionAdapter != nil {
return
}
permissionAdapter = &Adapter{
Owner: "built-in",
Name: "permission-adapter-built-in",
CreatedTime: util.GetCurrentTime(),
Type: "Database",
DatabaseType: conf.GetConfigString("driverName"),
TableNamePrefix: conf.GetConfigString("tableNamePrefix"),
Database: conf.GetConfigString("dbName"),
Table: "casbin_user_rule",
IsEnabled: true,
}
_, err = AddAdapter(permissionAdapter)
if err != nil {
panic(err)
}
}
func initBuildInApiAdapter() {
apiAdapter, err := GetAdapter("built-in/api-adapter-built-in")
if err != nil {
panic(err)
}
if apiAdapter != nil {
return
}
apiAdapter = &Adapter{
Owner: "built-in",
Name: "api-adapter-built-in",
CreatedTime: util.GetCurrentTime(),
Type: "Database",
DatabaseType: conf.GetConfigString("driverName"),
TableNamePrefix: conf.GetConfigString("tableNamePrefix"),
Database: conf.GetConfigString("dbName"),
Table: "casbin_api_rule",
IsEnabled: true,
}
_, err = AddAdapter(apiAdapter)
if err != nil {
panic(err)
}
}
func initBuiltInPermissionEnforcer() {
permissionEnforcer, err := GetEnforcer("built-in/permission-enforcer-built-in")
if err != nil {
panic(err)
}
if permissionEnforcer != nil {
return
}
permissionEnforcer = &Enforcer{
Owner: "built-in",
Name: "permission-enforcer-built-in",
CreatedTime: util.GetCurrentTime(),
DisplayName: "Permission Enforcer",
Model: "built-in/permission-model-built-in",
Adapter: "built-in/permission-adapter-built-in",
IsEnabled: true,
}
_, err = AddEnforcer(permissionEnforcer)
if err != nil {
panic(err)
}
}
func initBuiltInApiEnforcer() {
apiEnforcer, err := GetEnforcer("built-in/api-enforcer-built-in")
if err != nil {
panic(err)
}
if apiEnforcer != nil {
return
}
apiEnforcer = &Enforcer{
Owner: "built-in",
Name: "api-enforcer-built-in",
CreatedTime: util.GetCurrentTime(),
DisplayName: "API Enforcer",
Model: "built-in/api-model-built-in",
Adapter: "built-in/api-adapter-built-in",
IsEnabled: true,
}
_, err = AddEnforcer(apiEnforcer)
if err != nil {
panic(err)
}
}

View File

@@ -46,7 +46,7 @@ func AddLdap(ldap *Ldap) (bool, error) {
ldap.CreatedTime = util.GetCurrentTime()
}
affected, err := adapter.Engine.Insert(ldap)
affected, err := ormer.Engine.Insert(ldap)
if err != nil {
return false, err
}
@@ -56,7 +56,7 @@ func AddLdap(ldap *Ldap) (bool, error) {
func CheckLdapExist(ldap *Ldap) (bool, error) {
var result []*Ldap
err := adapter.Engine.Find(&result, &Ldap{
err := ormer.Engine.Find(&result, &Ldap{
Owner: ldap.Owner,
Host: ldap.Host,
Port: ldap.Port,
@@ -77,7 +77,7 @@ func CheckLdapExist(ldap *Ldap) (bool, error) {
func GetLdaps(owner string) ([]*Ldap, error) {
var ldaps []*Ldap
err := adapter.Engine.Desc("created_time").Find(&ldaps, &Ldap{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&ldaps, &Ldap{Owner: owner})
if err != nil {
return ldaps, err
}
@@ -91,7 +91,7 @@ func GetLdap(id string) (*Ldap, error) {
}
ldap := Ldap{Id: id}
existed, err := adapter.Engine.Get(&ldap)
existed, err := ormer.Engine.Get(&ldap)
if err != nil {
return &ldap, nil
}
@@ -103,14 +103,51 @@ 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 {
var l *Ldap
var err error
if l, err = GetLdap(ldap.Id); err != nil {
return false, nil
} else if l == nil {
return false, nil
}
affected, err := adapter.Engine.ID(ldap.Id).Cols("owner", "server_name", "host",
if ldap.Password == "***" {
ldap.Password = l.Password
}
affected, err := ormer.Engine.ID(ldap.Id).Cols("owner", "server_name", "host",
"port", "enable_ssl", "username", "password", "base_dn", "filter", "filter_fields", "auto_sync").Update(ldap)
if err != nil {
return false, nil
@@ -120,7 +157,7 @@ func UpdateLdap(ldap *Ldap) (bool, error) {
}
func DeleteLdap(ldap *Ldap) (bool, error) {
affected, err := adapter.Engine.ID(ldap.Id).Delete(&Ldap{})
affected, err := ormer.Engine.ID(ldap.Id).Delete(&Ldap{})
if err != nil {
return false, err
}

View File

@@ -118,7 +118,7 @@ func (l *LdapAutoSynchronizer) syncRoutine(ldap *Ldap, stopChan chan struct{}) e
// start all autosync goroutine for existing ldap servers in each organizations
func (l *LdapAutoSynchronizer) LdapAutoSynchronizerStartUpAll() error {
organizations := []*Organization{}
err := adapter.Engine.Desc("created_time").Find(&organizations)
err := ormer.Engine.Desc("created_time").Find(&organizations)
if err != nil {
logs.Info("failed to Star up LdapAutoSynchronizer; ")
}
@@ -141,7 +141,7 @@ func (l *LdapAutoSynchronizer) LdapAutoSynchronizerStartUpAll() error {
}
func UpdateLdapSyncTime(ldapId string) error {
_, err := adapter.Engine.ID(ldapId).Update(&Ldap{LastSync: util.GetCurrentTime()})
_, err := ormer.Engine.ID(ldapId).Update(&Ldap{LastSync: util.GetCurrentTime()})
if err != nil {
return err
}

View File

@@ -338,7 +338,7 @@ func SyncLdapUsers(owner string, syncUsers []LdapUser, ldapId string) (existUser
func GetExistUuids(owner string, uuids []string) ([]string, error) {
var existUuids []string
err := adapter.Engine.Table("user").Where("owner = ?", owner).Cols("ldap").
err := ormer.Engine.Table("user").Where("owner = ?", owner).Cols("ldap").
In("ldap", uuids).Select("DISTINCT ldap").Find(&existUuids)
if err != nil {
return existUuids, err
@@ -350,7 +350,7 @@ func GetExistUuids(owner string, uuids []string) ([]string, error) {
func (ldapUser *LdapUser) buildLdapUserName() (string, error) {
user := User{}
uidWithNumber := fmt.Sprintf("%s_%s", ldapUser.Uid, ldapUser.UidNumber)
has, err := adapter.Engine.Where("name = ? or name = ?", ldapUser.Uid, uidWithNumber).Get(&user)
has, err := ormer.Engine.Where("name = ? or name = ?", ldapUser.Uid, uidWithNumber).Get(&user)
if err != nil {
return "", err
}

View File

@@ -55,13 +55,13 @@ func GetMessageCount(owner, organization, field, value string) (int64, error) {
func GetMessages(owner string) ([]*Message, error) {
messages := []*Message{}
err := adapter.Engine.Desc("created_time").Find(&messages, &Message{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&messages, &Message{Owner: owner})
return messages, err
}
func GetChatMessages(chat string) ([]*Message, error) {
messages := []*Message{}
err := adapter.Engine.Asc("created_time").Find(&messages, &Message{Chat: chat})
err := ormer.Engine.Asc("created_time").Find(&messages, &Message{Chat: chat})
return messages, err
}
@@ -78,7 +78,7 @@ func getMessage(owner string, name string) (*Message, error) {
}
message := Message{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&message)
existed, err := ormer.Engine.Get(&message)
if err != nil {
return nil, err
}
@@ -103,7 +103,7 @@ func UpdateMessage(id string, message *Message) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(message)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(message)
if err != nil {
return false, err
}
@@ -112,7 +112,7 @@ func UpdateMessage(id string, message *Message) (bool, error) {
}
func AddMessage(message *Message) (bool, error) {
affected, err := adapter.Engine.Insert(message)
affected, err := ormer.Engine.Insert(message)
if err != nil {
return false, err
}
@@ -121,7 +121,7 @@ func AddMessage(message *Message) (bool, error) {
}
func DeleteMessage(message *Message) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{message.Owner, message.Name}).Delete(&Message{})
affected, err := ormer.Engine.ID(core.PK{message.Owner, message.Name}).Delete(&Message{})
if err != nil {
return false, err
}
@@ -130,7 +130,7 @@ func DeleteMessage(message *Message) (bool, error) {
}
func DeleteChatMessages(chat string) (bool, error) {
affected, err := adapter.Engine.Delete(&Message{Chat: chat})
affected, err := ormer.Engine.Delete(&Message{Chat: chat})
if err != nil {
return false, err
}

View File

@@ -43,7 +43,7 @@ func DoMigration() {
IDColumnName: "id",
}
m := migrate.New(adapter.Engine, options, migrations)
m := migrate.New(ormer.Engine, options, migrations)
err := m.Migrate()
if err != nil {
panic(err)

View File

@@ -24,9 +24,9 @@ import (
type Migrator_1_101_0_PR_1083 struct{}
func (*Migrator_1_101_0_PR_1083) IsMigrationNeeded() bool {
exist1, _ := adapter.Engine.IsTableExist("model")
exist2, _ := adapter.Engine.IsTableExist("permission")
exist3, _ := adapter.Engine.IsTableExist("permission_rule")
exist1, _ := ormer.Engine.IsTableExist("model")
exist2, _ := ormer.Engine.IsTableExist("permission")
exist3, _ := ormer.Engine.IsTableExist("permission_rule")
if exist1 && exist2 && exist3 {
return true

View File

@@ -23,7 +23,7 @@ import (
type Migrator_1_235_0_PR_1530 struct{}
func (*Migrator_1_235_0_PR_1530) IsMigrationNeeded() bool {
exist, _ := adapter.Engine.IsTableExist("casbin_rule")
exist, _ := ormer.Engine.IsTableExist("casbin_rule")
return exist
}

View File

@@ -24,8 +24,8 @@ import (
type Migrator_1_240_0_PR_1539 struct{}
func (*Migrator_1_240_0_PR_1539) IsMigrationNeeded() bool {
exist, _ := adapter.Engine.IsTableExist("session")
err := adapter.Engine.Table("session").Find(&[]*Session{})
exist, _ := ormer.Engine.IsTableExist("session")
err := ormer.Engine.Table("session").Find(&[]*Session{})
if exist && err != nil {
return true

View File

@@ -22,7 +22,7 @@ import (
type Migrator_1_314_0_PR_1841 struct{}
func (*Migrator_1_314_0_PR_1841) IsMigrationNeeded() bool {
count, err := adapter.Engine.Where("password_type=?", "").Count(&User{})
count, err := ormer.Engine.Where("password_type=?", "").Count(&User{})
if err != nil {
// table doesn't exist
return false

View File

@@ -40,7 +40,7 @@ func GetModelCount(owner, field, value string) (int64, error) {
func GetModels(owner string) ([]*Model, error) {
models := []*Model{}
err := adapter.Engine.Desc("created_time").Find(&models, &Model{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&models, &Model{Owner: owner})
if err != nil {
return models, err
}
@@ -65,7 +65,7 @@ func getModel(owner string, name string) (*Model, error) {
}
m := Model{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&m)
existed, err := ormer.Engine.Get(&m)
if err != nil {
return &m, err
}
@@ -111,7 +111,7 @@ func UpdateModel(id string, modelObj *Model) (bool, error) {
}
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(modelObj)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(modelObj)
if err != nil {
return false, err
}
@@ -120,7 +120,7 @@ func UpdateModel(id string, modelObj *Model) (bool, error) {
}
func AddModel(model *Model) (bool, error) {
affected, err := adapter.Engine.Insert(model)
affected, err := ormer.Engine.Insert(model)
if err != nil {
return false, err
}
@@ -129,7 +129,7 @@ func AddModel(model *Model) (bool, error) {
}
func DeleteModel(model *Model) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{model.Owner, model.Name}).Delete(&Model{})
affected, err := ormer.Engine.ID(core.PK{model.Owner, model.Name}).Delete(&Model{})
if err != nil {
return false, err
}
@@ -137,12 +137,12 @@ func DeleteModel(model *Model) (bool, error) {
return affected != 0, nil
}
func (model *Model) GetId() string {
return fmt.Sprintf("%s/%s", model.Owner, model.Name)
func (m *Model) GetId() string {
return fmt.Sprintf("%s/%s", m.Owner, m.Name)
}
func modelChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
@@ -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,16 @@ func modelChangeTrigger(oldName string, newName string) error {
}
func HasRoleDefinition(m model.Model) bool {
if m == nil {
return false
}
return m["g"] != nil
}
func (m *Model) initModel() (model.Model, error) {
casbinModel, err := model.NewModelFromString(m.ModelText)
if err != nil {
return nil, err
}
return casbinModel, nil
}

View File

@@ -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)

View File

@@ -80,12 +80,12 @@ func GetOrganizationCount(owner, field, value string) (int64, error) {
func GetOrganizations(owner string, name ...string) ([]*Organization, error) {
organizations := []*Organization{}
if name != nil && len(name) > 0 {
err := adapter.Engine.Desc("created_time").Where(builder.In("name", name)).Find(&organizations)
err := ormer.Engine.Desc("created_time").Where(builder.In("name", name)).Find(&organizations)
if err != nil {
return nil, err
}
} else {
err := adapter.Engine.Desc("created_time").Find(&organizations, &Organization{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&organizations, &Organization{Owner: owner})
if err != nil {
return nil, err
}
@@ -96,7 +96,7 @@ func GetOrganizations(owner string, name ...string) ([]*Organization, error) {
func GetOrganizationsByFields(owner string, fields ...string) ([]*Organization, error) {
organizations := []*Organization{}
err := adapter.Engine.Desc("created_time").Cols(fields...).Find(&organizations, &Organization{Owner: owner})
err := ormer.Engine.Desc("created_time").Cols(fields...).Find(&organizations, &Organization{Owner: owner})
if err != nil {
return nil, err
}
@@ -126,7 +126,7 @@ func getOrganization(owner string, name string) (*Organization, error) {
}
organization := Organization{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&organization)
existed, err := ormer.Engine.Get(&organization)
if err != nil {
return nil, err
}
@@ -201,7 +201,7 @@ func UpdateOrganization(id string, organization *Organization) (bool, error) {
}
}
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()
if organization.MasterPassword == "***" {
session.Omit("master_password")
}
@@ -214,7 +214,7 @@ func UpdateOrganization(id string, organization *Organization) (bool, error) {
}
func AddOrganization(organization *Organization) (bool, error) {
affected, err := adapter.Engine.Insert(organization)
affected, err := ormer.Engine.Insert(organization)
if err != nil {
return false, err
}
@@ -227,7 +227,7 @@ func DeleteOrganization(organization *Organization) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{organization.Owner, organization.Name}).Delete(&Organization{})
affected, err := ormer.Engine.ID(core.PK{organization.Owner, organization.Name}).Delete(&Organization{})
if err != nil {
return false, err
}
@@ -299,7 +299,7 @@ func GetDefaultApplication(id string) (*Application, error) {
}
applications := []*Application{}
err = adapter.Engine.Asc("created_time").Find(&applications, &Application{Organization: organization.Name})
err = ormer.Engine.Asc("created_time").Find(&applications, &Application{Organization: organization.Name})
if err != nil {
return nil, err
}
@@ -330,7 +330,7 @@ func GetDefaultApplication(id string) (*Application, error) {
}
func organizationChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
@@ -360,7 +360,7 @@ func organizationChangeTrigger(oldName string, newName string) error {
}
role := new(Role)
_, err = adapter.Engine.Where("owner=?", oldName).Get(role)
_, err = ormer.Engine.Where("owner=?", oldName).Get(role)
if err != nil {
return err
}
@@ -385,7 +385,7 @@ func organizationChangeTrigger(oldName string, newName string) error {
}
permission := new(Permission)
_, err = adapter.Engine.Where("owner=?", oldName).Get(permission)
_, err = ormer.Engine.Where("owner=?", oldName).Get(permission)
if err != nil {
return err
}
@@ -409,9 +409,9 @@ func organizationChangeTrigger(oldName string, newName string) error {
return err
}
casbinAdapter := new(CasbinAdapter)
casbinAdapter.Owner = newName
_, err = session.Where("owner=?", oldName).Update(casbinAdapter)
adapter := new(Adapter)
adapter.Owner = newName
_, err = session.Where("owner=?", oldName).Update(adapter)
if err != nil {
return err
}

379
object/ormer.go Normal file
View File

@@ -0,0 +1,379 @@
// Copyright 2021 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 (
"database/sql"
"fmt"
"runtime"
"strings"
"github.com/beego/beego"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/util"
xormadapter "github.com/casdoor/xorm-adapter/v3"
_ "github.com/denisenkom/go-mssqldb" // db = mssql
_ "github.com/go-sql-driver/mysql" // db = mysql
_ "github.com/lib/pq" // db = postgres
"github.com/xorm-io/core"
"github.com/xorm-io/xorm"
_ "modernc.org/sqlite" // db = sqlite
)
var ormer *Ormer
func InitConfig() {
err := beego.LoadAppConfig("ini", "../conf/app.conf")
if err != nil {
panic(err)
}
beego.BConfig.WebConfig.Session.SessionOn = true
InitAdapter(true)
CreateTables(true)
DoMigration()
}
func InitAdapter(createDatabase bool) {
if createDatabase {
err := createDatabaseForPostgres(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
if err != nil {
panic(err)
}
}
ormer = NewAdapter(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName(), conf.GetConfigString("dbName"))
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, tableNamePrefix)
ormer.Engine.SetTableMapper(tbMapper)
}
func CreateTables(createDatabase bool) {
if createDatabase {
err := ormer.CreateDatabase()
if err != nil {
panic(err)
}
}
ormer.createTable()
}
// Ormer represents the MySQL adapter for policy storage.
type Ormer struct {
driverName string
dataSourceName string
dbName string
Engine *xorm.Engine
}
// finalizer is the destructor for Ormer.
func finalizer(a *Ormer) {
err := a.Engine.Close()
if err != nil {
panic(err)
}
}
// NewAdapter is the constructor for Ormer.
func NewAdapter(driverName string, dataSourceName string, dbName string) *Ormer {
a := &Ormer{}
a.driverName = driverName
a.dataSourceName = dataSourceName
a.dbName = dbName
// Open the DB, create it if not existed.
a.open()
// Call the destructor when the object is released.
runtime.SetFinalizer(a, finalizer)
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 *Ormer) CreateDatabase() error {
if a.driverName == "postgres" {
return nil
}
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
if err != nil {
return err
}
defer engine.Close()
_, err = engine.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s default charset utf8mb4 COLLATE utf8mb4_general_ci", a.dbName))
return err
}
func (a *Ormer) open() {
dataSourceName := a.dataSourceName + a.dbName
if a.driverName != "mysql" {
dataSourceName = a.dataSourceName
}
engine, err := xorm.NewEngine(a.driverName, dataSourceName)
if err != nil {
panic(err)
}
a.Engine = engine
}
func (a *Ormer) close() {
_ = a.Engine.Close()
a.Engine = nil
}
func (a *Ormer) createTable() {
showSql := conf.GetConfigBool("showSql")
a.Engine.ShowSQL(showSql)
err := a.Engine.Sync2(new(Organization))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(User))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Group))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Role))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Permission))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Model))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Adapter))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Enforcer))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Provider))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Application))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Resource))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Token))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(VerificationRecord))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Record))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Webhook))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Syncer))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Cert))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Chat))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Message))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Product))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Payment))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Ldap))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(PermissionRule))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(xormadapter.CasbinRule))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Session))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Subscription))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Plan))
if err != nil {
panic(err)
}
err = a.Engine.Sync2(new(Pricing))
if err != nil {
panic(err)
}
}
func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
session := ormer.Engine.Prepare()
if offset != -1 && limit != -1 {
session.Limit(limit, offset)
}
if owner != "" {
session = session.And("owner=?", owner)
}
if field != "" && value != "" {
if util.FilterField(field) {
session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
}
}
if sortField == "" || sortOrder == "" {
sortField = "created_time"
}
if sortOrder == "ascend" {
session = session.Asc(util.SnakeString(sortField))
} else {
session = session.Desc(util.SnakeString(sortField))
}
return session
}
func GetSessionForUser(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
session := ormer.Engine.Prepare()
if offset != -1 && limit != -1 {
session.Limit(limit, offset)
}
if owner != "" {
if offset == -1 {
session = session.And("owner=?", owner)
} else {
session = session.And("a.owner=?", owner)
}
}
if field != "" && value != "" {
if util.FilterField(field) {
if offset != -1 {
field = fmt.Sprintf("a.%s", field)
}
session = session.And(fmt.Sprintf("%s like ?", util.SnakeString(field)), fmt.Sprintf("%%%s%%", value))
}
}
if sortField == "" || sortOrder == "" {
sortField = "created_time"
}
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
tableName := tableNamePrefix + "user"
if offset == -1 {
if sortOrder == "ascend" {
session = session.Asc(util.SnakeString(sortField))
} else {
session = session.Desc(util.SnakeString(sortField))
}
} else {
if sortOrder == "ascend" {
session = session.Alias("a").
Join("INNER", []string{tableName, "b"}, "a.owner = b.owner and a.name = b.name").
Select("b.*").
Asc("a." + util.SnakeString(sortField))
} else {
session = session.Alias("a").
Join("INNER", []string{tableName, "b"}, "a.owner = b.owner and a.name = b.name").
Select("b.*").
Desc("a." + util.SnakeString(sortField))
}
}
return session
}

View File

@@ -63,7 +63,7 @@ func GetPaymentCount(owner, organization, field, value string) (int64, error) {
func GetPayments(owner string) ([]*Payment, error) {
payments := []*Payment{}
err := adapter.Engine.Desc("created_time").Find(&payments, &Payment{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&payments, &Payment{Owner: owner})
if err != nil {
return nil, err
}
@@ -73,7 +73,7 @@ func GetPayments(owner string) ([]*Payment, error) {
func GetUserPayments(owner string, organization string, user string) ([]*Payment, error) {
payments := []*Payment{}
err := adapter.Engine.Desc("created_time").Find(&payments, &Payment{Owner: owner, Organization: organization, User: user})
err := ormer.Engine.Desc("created_time").Find(&payments, &Payment{Owner: owner, Organization: organization, User: user})
if err != nil {
return nil, err
}
@@ -98,7 +98,7 @@ func getPayment(owner string, name string) (*Payment, error) {
}
payment := Payment{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&payment)
existed, err := ormer.Engine.Get(&payment)
if err != nil {
return nil, err
}
@@ -123,7 +123,7 @@ func UpdatePayment(id string, payment *Payment) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(payment)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(payment)
if err != nil {
panic(err)
}
@@ -132,7 +132,7 @@ func UpdatePayment(id string, payment *Payment) (bool, error) {
}
func AddPayment(payment *Payment) (bool, error) {
affected, err := adapter.Engine.Insert(payment)
affected, err := ormer.Engine.Insert(payment)
if err != nil {
return false, err
}
@@ -141,7 +141,7 @@ func AddPayment(payment *Payment) (bool, error) {
}
func DeletePayment(payment *Payment) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{payment.Owner, payment.Name}).Delete(&Payment{})
affected, err := ormer.Engine.ID(core.PK{payment.Owner, payment.Name}).Delete(&Payment{})
if err != nil {
return false, err
}

View File

@@ -74,7 +74,7 @@ func GetPermissionCount(owner, field, value string) (int64, error) {
func GetPermissions(owner string) ([]*Permission, error) {
permissions := []*Permission{}
err := adapter.Engine.Desc("created_time").Find(&permissions, &Permission{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&permissions, &Permission{Owner: owner})
if err != nil {
return permissions, err
}
@@ -99,7 +99,7 @@ func getPermission(owner string, name string) (*Permission, error) {
}
permission := Permission{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&permission)
existed, err := ormer.Engine.Get(&permission)
if err != nil {
return &permission, err
}
@@ -112,13 +112,13 @@ func getPermission(owner string, name string) (*Permission, error) {
}
func GetPermission(id string) (*Permission, error) {
owner, name := util.GetOwnerAndNameFromId(id)
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
return getPermission(owner, name)
}
// checkPermissionValid verifies if the permission is valid
func checkPermissionValid(permission *Permission) error {
enforcer := getEnforcer(permission)
enforcer := getPermissionEnforcer(permission)
enforcer.EnableAutoSave(false)
policies := getPolicies(permission)
@@ -149,13 +149,13 @@ func UpdatePermission(id string, permission *Permission) (bool, error) {
return false, err
}
owner, name := util.GetOwnerAndNameFromId(id)
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
oldPermission, err := getPermission(owner, name)
if oldPermission == nil {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(permission)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(permission)
if err != nil {
return false, err
}
@@ -164,9 +164,9 @@ func UpdatePermission(id string, permission *Permission) (bool, error) {
removeGroupingPolicies(oldPermission)
removePolicies(oldPermission)
if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
isEmpty, _ := adapter.Engine.IsTableEmpty(oldPermission.Adapter)
isEmpty, _ := ormer.Engine.IsTableEmpty(oldPermission.Adapter)
if isEmpty {
err = adapter.Engine.DropTables(oldPermission.Adapter)
err = ormer.Engine.DropTables(oldPermission.Adapter)
if err != nil {
return false, err
}
@@ -180,7 +180,7 @@ func UpdatePermission(id string, permission *Permission) (bool, error) {
}
func AddPermission(permission *Permission) (bool, error) {
affected, err := adapter.Engine.Insert(permission)
affected, err := ormer.Engine.Insert(permission)
if err != nil {
return false, err
}
@@ -198,7 +198,7 @@ func AddPermissions(permissions []*Permission) bool {
return false
}
affected, err := adapter.Engine.Insert(permissions)
affected, err := ormer.Engine.Insert(permissions)
if err != nil {
if !strings.Contains(err.Error(), "Duplicate entry") {
panic(err)
@@ -242,7 +242,7 @@ func AddPermissionsInBatch(permissions []*Permission) bool {
}
func DeletePermission(permission *Permission) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{permission.Owner, permission.Name}).Delete(&Permission{})
affected, err := ormer.Engine.ID(core.PK{permission.Owner, permission.Name}).Delete(&Permission{})
if err != nil {
return false, err
}
@@ -251,9 +251,9 @@ func DeletePermission(permission *Permission) (bool, error) {
removeGroupingPolicies(permission)
removePolicies(permission)
if permission.Adapter != "" && permission.Adapter != "permission_rule" {
isEmpty, _ := adapter.Engine.IsTableEmpty(permission.Adapter)
isEmpty, _ := ormer.Engine.IsTableEmpty(permission.Adapter)
if isEmpty {
err = adapter.Engine.DropTables(permission.Adapter)
err = ormer.Engine.DropTables(permission.Adapter)
if err != nil {
return false, err
}
@@ -266,7 +266,7 @@ func DeletePermission(permission *Permission) (bool, error) {
func GetPermissionsAndRolesByUser(userId string) ([]*Permission, []*Role, error) {
permissions := []*Permission{}
err := adapter.Engine.Where("users like ?", "%"+userId+"\"%").Find(&permissions)
err := ormer.Engine.Where("users like ?", "%"+userId+"\"%").Find(&permissions)
if err != nil {
return nil, nil, err
}
@@ -290,7 +290,7 @@ func GetPermissionsAndRolesByUser(userId string) ([]*Permission, []*Role, error)
for _, role := range roles {
perms := []*Permission{}
err := adapter.Engine.Where("roles like ?", "%"+role.Name+"\"%").Find(&perms)
err := ormer.Engine.Where("roles like ?", "%"+role.Name+"\"%").Find(&perms)
if err != nil {
return nil, nil, err
}
@@ -310,7 +310,7 @@ func GetPermissionsAndRolesByUser(userId string) ([]*Permission, []*Role, error)
func GetPermissionsByRole(roleId string) ([]*Permission, error) {
permissions := []*Permission{}
err := adapter.Engine.Where("roles like ?", "%"+roleId+"\"%").Find(&permissions)
err := ormer.Engine.Where("roles like ?", "%"+roleId+"\"%").Find(&permissions)
if err != nil {
return permissions, err
}
@@ -320,7 +320,7 @@ func GetPermissionsByRole(roleId string) ([]*Permission, error) {
func GetPermissionsByResource(resourceId string) ([]*Permission, error) {
permissions := []*Permission{}
err := adapter.Engine.Where("resources like ?", "%"+resourceId+"\"%").Find(&permissions)
err := ormer.Engine.Where("resources like ?", "%"+resourceId+"\"%").Find(&permissions)
if err != nil {
return permissions, err
}
@@ -330,7 +330,7 @@ func GetPermissionsByResource(resourceId string) ([]*Permission, error) {
func GetPermissionsBySubmitter(owner string, submitter string) ([]*Permission, error) {
permissions := []*Permission{}
err := adapter.Engine.Desc("created_time").Find(&permissions, &Permission{Owner: owner, Submitter: submitter})
err := ormer.Engine.Desc("created_time").Find(&permissions, &Permission{Owner: owner, Submitter: submitter})
if err != nil {
return permissions, err
}
@@ -340,7 +340,7 @@ func GetPermissionsBySubmitter(owner string, submitter string) ([]*Permission, e
func GetPermissionsByModel(owner string, model string) ([]*Permission, error) {
permissions := []*Permission{}
err := adapter.Engine.Desc("created_time").Find(&permissions, &Permission{Owner: owner, Model: model})
err := ormer.Engine.Desc("created_time").Find(&permissions, &Permission{Owner: owner, Model: model})
if err != nil {
return permissions, err
}

View File

@@ -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 := getAdapter(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)
adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
if err != nil {
return err
}
enforcer.SetAdapter(adapter)
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

View File

@@ -44,7 +44,7 @@ func GetPlanCount(owner, field, value string) (int64, error) {
func GetPlans(owner string) ([]*Plan, error) {
plans := []*Plan{}
err := adapter.Engine.Desc("created_time").Find(&plans, &Plan{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&plans, &Plan{Owner: owner})
if err != nil {
return plans, err
}
@@ -67,7 +67,7 @@ func getPlan(owner, name string) (*Plan, error) {
}
plan := Plan{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&plan)
existed, err := ormer.Engine.Get(&plan)
if err != nil {
return &plan, err
}
@@ -91,7 +91,7 @@ func UpdatePlan(id string, plan *Plan) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(plan)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(plan)
if err != nil {
return false, err
}
@@ -100,7 +100,7 @@ func UpdatePlan(id string, plan *Plan) (bool, error) {
}
func AddPlan(plan *Plan) (bool, error) {
affected, err := adapter.Engine.Insert(plan)
affected, err := ormer.Engine.Insert(plan)
if err != nil {
return false, err
}
@@ -108,7 +108,7 @@ func AddPlan(plan *Plan) (bool, error) {
}
func DeletePlan(plan *Plan) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{plan.Owner, plan.Name}).Delete(plan)
affected, err := ormer.Engine.ID(core.PK{plan.Owner, plan.Name}).Delete(plan)
if err != nil {
return false, err
}

View File

@@ -48,7 +48,7 @@ func GetPricingCount(owner, field, value string) (int64, error) {
func GetPricings(owner string) ([]*Pricing, error) {
pricings := []*Pricing{}
err := adapter.Engine.Desc("created_time").Find(&pricings, &Pricing{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&pricings, &Pricing{Owner: owner})
if err != nil {
return pricings, err
}
@@ -72,7 +72,7 @@ func getPricing(owner, name string) (*Pricing, error) {
}
pricing := Pricing{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&pricing)
existed, err := ormer.Engine.Get(&pricing)
if err != nil {
return &pricing, err
}
@@ -96,7 +96,7 @@ func UpdatePricing(id string, pricing *Pricing) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(pricing)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(pricing)
if err != nil {
return false, err
}
@@ -105,7 +105,7 @@ func UpdatePricing(id string, pricing *Pricing) (bool, error) {
}
func AddPricing(pricing *Pricing) (bool, error) {
affected, err := adapter.Engine.Insert(pricing)
affected, err := ormer.Engine.Insert(pricing)
if err != nil {
return false, err
}
@@ -113,7 +113,7 @@ func AddPricing(pricing *Pricing) (bool, error) {
}
func DeletePricing(pricing *Pricing) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{pricing.Owner, pricing.Name}).Delete(pricing)
affected, err := ormer.Engine.ID(core.PK{pricing.Owner, pricing.Name}).Delete(pricing)
if err != nil {
return false, err
}

View File

@@ -50,7 +50,7 @@ func GetProductCount(owner, field, value string) (int64, error) {
func GetProducts(owner string) ([]*Product, error) {
products := []*Product{}
err := adapter.Engine.Desc("created_time").Find(&products, &Product{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&products, &Product{Owner: owner})
if err != nil {
return products, err
}
@@ -75,7 +75,7 @@ func getProduct(owner string, name string) (*Product, error) {
}
product := Product{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&product)
existed, err := ormer.Engine.Get(&product)
if err != nil {
return &product, nil
}
@@ -100,7 +100,7 @@ func UpdateProduct(id string, product *Product) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(product)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(product)
if err != nil {
return false, err
}
@@ -109,7 +109,7 @@ func UpdateProduct(id string, product *Product) (bool, error) {
}
func AddProduct(product *Product) (bool, error) {
affected, err := adapter.Engine.Insert(product)
affected, err := ormer.Engine.Insert(product)
if err != nil {
return false, err
}
@@ -118,7 +118,7 @@ func AddProduct(product *Product) (bool, error) {
}
func DeleteProduct(product *Product) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{product.Owner, product.Name}).Delete(&Product{})
affected, err := ormer.Engine.ID(core.PK{product.Owner, product.Name}).Delete(&Product{})
if err != nil {
return false, err
}
@@ -192,7 +192,7 @@ func BuyProduct(id string, providerName string, user *User, host string) (string
}
payment := Payment{
Owner: product.Owner,
Owner: "admin",
Name: paymentName,
CreatedTime: util.GetCurrentTime(),
DisplayName: paymentName,

View File

@@ -119,7 +119,7 @@ func GetGlobalProviderCount(field, value string) (int64, error) {
func GetProviders(owner string) ([]*Provider, error) {
providers := []*Provider{}
err := adapter.Engine.Where("owner = ? or owner = ? ", "admin", owner).Desc("created_time").Find(&providers, &Provider{})
err := ormer.Engine.Where("owner = ? or owner = ? ", "admin", owner).Desc("created_time").Find(&providers, &Provider{})
if err != nil {
return providers, err
}
@@ -129,7 +129,7 @@ func GetProviders(owner string) ([]*Provider, error) {
func GetGlobalProviders() ([]*Provider, error) {
providers := []*Provider{}
err := adapter.Engine.Desc("created_time").Find(&providers)
err := ormer.Engine.Desc("created_time").Find(&providers)
if err != nil {
return providers, err
}
@@ -165,7 +165,7 @@ func getProvider(owner string, name string) (*Provider, error) {
}
provider := Provider{Name: name}
existed, err := adapter.Engine.Get(&provider)
existed, err := ormer.Engine.Get(&provider)
if err != nil {
return &provider, err
}
@@ -184,7 +184,7 @@ func GetProvider(id string) (*Provider, error) {
func getDefaultAiProvider() (*Provider, error) {
provider := Provider{Owner: "admin", Category: "AI"}
existed, err := adapter.Engine.Get(&provider)
existed, err := ormer.Engine.Get(&provider)
if err != nil {
return &provider, err
}
@@ -221,7 +221,7 @@ func UpdateProvider(id string, provider *Provider) (bool, error) {
}
}
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()
if provider.ClientSecret == "***" {
session = session.Omit("client_secret")
}
@@ -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,12 +243,12 @@ 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)
}
affected, err := adapter.Engine.Insert(provider)
affected, err := ormer.Engine.Insert(provider)
if err != nil {
return false, err
}
@@ -257,7 +257,7 @@ func AddProvider(provider *Provider) (bool, error) {
}
func DeleteProvider(provider *Provider) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{provider.Owner, provider.Name}).Delete(&Provider{})
affected, err := ormer.Engine.ID(core.PK{provider.Owner, provider.Name}).Delete(&Provider{})
if err != nil {
return false, err
}
@@ -297,7 +297,7 @@ func (p *Provider) GetId() string {
func GetCaptchaProviderByOwnerName(applicationId, lang string) (*Provider, error) {
owner, name := util.GetOwnerAndNameFromId(applicationId)
provider := Provider{Owner: owner, Name: name, Category: "Captcha"}
existed, err := adapter.Engine.Get(&provider)
existed, err := ormer.Engine.Get(&provider)
if err != nil {
return nil, err
}
@@ -333,7 +333,7 @@ func GetCaptchaProviderByApplication(applicationId, isCurrentProvider, lang stri
}
func providerChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
@@ -342,7 +342,7 @@ func providerChangeTrigger(oldName string, newName string) error {
}
var applications []*Application
err = adapter.Engine.Find(&applications)
err = ormer.Engine.Find(&applications)
if err != nil {
return err
}

View File

@@ -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 {

View File

@@ -96,7 +96,7 @@ func AddRecord(record *Record) bool {
fmt.Println(errWebhook)
}
affected, err := adapter.Engine.Insert(record)
affected, err := ormer.Engine.Insert(record)
if err != nil {
panic(err)
}
@@ -111,7 +111,7 @@ func GetRecordCount(field, value string, filterRecord *Record) (int64, error) {
func GetRecords() ([]*Record, error) {
records := []*Record{}
err := adapter.Engine.Desc("id").Find(&records)
err := ormer.Engine.Desc("id").Find(&records)
if err != nil {
return records, err
}
@@ -132,7 +132,7 @@ func GetPaginationRecords(offset, limit int, field, value, sortField, sortOrder
func GetRecordsByField(record *Record) ([]*Record, error) {
records := []*Record{}
err := adapter.Engine.Find(&records, record)
err := ormer.Engine.Find(&records, record)
if err != nil {
return records, err
}
@@ -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
}

View File

@@ -16,6 +16,7 @@ package object
import (
"fmt"
"strings"
"github.com/casdoor/casdoor/util"
"github.com/xorm-io/core"
@@ -51,7 +52,7 @@ func GetResources(owner string, user string) ([]*Resource, error) {
}
resources := []*Resource{}
err := adapter.Engine.Desc("created_time").Find(&resources, &Resource{Owner: owner, User: user})
err := ormer.Engine.Desc("created_time").Find(&resources, &Resource{Owner: owner, User: user})
if err != nil {
return resources, err
}
@@ -76,8 +77,12 @@ 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)
existed, err := ormer.Engine.Get(&resource)
if err != nil {
return &resource, err
}
@@ -102,7 +107,7 @@ func UpdateResource(id string, resource *Resource) (bool, error) {
return false, nil
}
_, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(resource)
_, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(resource)
if err != nil {
return false, err
}
@@ -112,7 +117,7 @@ func UpdateResource(id string, resource *Resource) (bool, error) {
}
func AddResource(resource *Resource) (bool, error) {
affected, err := adapter.Engine.Insert(resource)
affected, err := ormer.Engine.Insert(resource)
if err != nil {
return false, err
}
@@ -121,7 +126,7 @@ func AddResource(resource *Resource) (bool, error) {
}
func DeleteResource(resource *Resource) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{resource.Owner, resource.Name}).Delete(&Resource{})
affected, err := ormer.Engine.ID(core.PK{resource.Owner, resource.Name}).Delete(&Resource{})
if err != nil {
return false, err
}

View File

@@ -44,7 +44,7 @@ func GetRoleCount(owner, field, value string) (int64, error) {
func GetRoles(owner string) ([]*Role, error) {
roles := []*Role{}
err := adapter.Engine.Desc("created_time").Find(&roles, &Role{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&roles, &Role{Owner: owner})
if err != nil {
return roles, err
}
@@ -69,7 +69,7 @@ func getRole(owner string, name string) (*Role, error) {
}
role := Role{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&role)
existed, err := ormer.Engine.Get(&role)
if err != nil {
return &role, err
}
@@ -82,12 +82,12 @@ func getRole(owner string, name string) (*Role, error) {
}
func GetRole(id string) (*Role, error) {
owner, name := util.GetOwnerAndNameFromId(id)
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
return getRole(owner, name)
}
func UpdateRole(id string, role *Role) (bool, error) {
owner, name := util.GetOwnerAndNameFromId(id)
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
oldRole, err := getRole(owner, name)
if err != nil {
return false, err
@@ -137,7 +137,7 @@ func UpdateRole(id string, role *Role) (bool, error) {
}
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(role)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(role)
if err != nil {
return false, err
}
@@ -178,7 +178,7 @@ func UpdateRole(id string, role *Role) (bool, error) {
}
func AddRole(role *Role) (bool, error) {
affected, err := adapter.Engine.Insert(role)
affected, err := ormer.Engine.Insert(role)
if err != nil {
return false, err
}
@@ -190,7 +190,7 @@ func AddRoles(roles []*Role) bool {
if len(roles) == 0 {
return false
}
affected, err := adapter.Engine.Insert(roles)
affected, err := ormer.Engine.Insert(roles)
if err != nil {
if !strings.Contains(err.Error(), "Duplicate entry") {
panic(err)
@@ -240,7 +240,7 @@ func DeleteRole(role *Role) (bool, error) {
}
}
affected, err := adapter.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
affected, err := ormer.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
if err != nil {
return false, err
}
@@ -254,7 +254,7 @@ func (role *Role) GetId() string {
func GetRolesByUser(userId string) ([]*Role, error) {
roles := []*Role{}
err := adapter.Engine.Where("users like ?", "%"+userId+"\"%").Find(&roles)
err := ormer.Engine.Where("users like ?", "%"+userId+"\"%").Find(&roles)
if err != nil {
return roles, err
}
@@ -278,7 +278,7 @@ func GetRolesByUser(userId string) ([]*Role, error) {
}
func roleChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
@@ -287,7 +287,7 @@ func roleChangeTrigger(oldName string, newName string) error {
}
var roles []*Role
err = adapter.Engine.Find(&roles)
err = ormer.Engine.Find(&roles)
if err != nil {
return err
}
@@ -306,7 +306,7 @@ func roleChangeTrigger(oldName string, newName string) error {
}
var permissions []*Permission
err = adapter.Engine.Find(&permissions)
err = ormer.Engine.Find(&permissions)
if err != nil {
return err
}
@@ -338,7 +338,7 @@ func GetMaskedRoles(roles []*Role) []*Role {
func GetRolesByNamePrefix(owner string, prefix string) ([]*Role, error) {
roles := []*Role{}
err := adapter.Engine.Where("owner=? and name like ?", owner, prefix+"%").Find(&roles)
err := ormer.Engine.Where("owner=? and name like ?", owner, prefix+"%").Find(&roles)
if err != nil {
return roles, err
}
@@ -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

View File

@@ -40,9 +40,9 @@ func GetSessions(owner string) ([]*Session, error) {
sessions := []*Session{}
var err error
if owner != "" {
err = adapter.Engine.Desc("created_time").Where("owner = ?", owner).Find(&sessions)
err = ormer.Engine.Desc("created_time").Where("owner = ?", owner).Find(&sessions)
} else {
err = adapter.Engine.Desc("created_time").Find(&sessions)
err = ormer.Engine.Desc("created_time").Find(&sessions)
}
if err != nil {
return sessions, err
@@ -70,7 +70,7 @@ func GetSessionCount(owner, field, value string) (int64, error) {
func GetSingleSession(id string) (*Session, error) {
owner, name, application := util.GetOwnerAndNameAndOtherFromId(id)
session := Session{Owner: owner, Name: name, Application: application}
get, err := adapter.Engine.Get(&session)
get, err := ormer.Engine.Get(&session)
if err != nil {
return &session, err
}
@@ -91,7 +91,7 @@ func UpdateSession(id string, session *Session) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name, application}).Update(session)
affected, err := ormer.Engine.ID(core.PK{owner, name, application}).Update(session)
if err != nil {
return false, err
}
@@ -114,7 +114,7 @@ func AddSession(session *Session) (bool, error) {
if dbSession == nil {
session.CreatedTime = util.GetCurrentTime()
affected, err := adapter.Engine.Insert(session)
affected, err := ormer.Engine.Insert(session)
if err != nil {
return false, err
}
@@ -150,7 +150,7 @@ func DeleteSession(id string) (bool, error) {
}
}
affected, err := adapter.Engine.ID(core.PK{owner, name, application}).Delete(&Session{})
affected, err := ormer.Engine.ID(core.PK{owner, name, application}).Delete(&Session{})
if err != nil {
return false, err
}

View File

@@ -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")
}

View File

@@ -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)

View File

@@ -69,7 +69,7 @@ func GetSubscriptionCount(owner, field, value string) (int64, error) {
func GetSubscriptions(owner string) ([]*Subscription, error) {
subscriptions := []*Subscription{}
err := adapter.Engine.Desc("created_time").Find(&subscriptions, &Subscription{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&subscriptions, &Subscription{Owner: owner})
if err != nil {
return subscriptions, err
}
@@ -94,7 +94,7 @@ func getSubscription(owner string, name string) (*Subscription, error) {
}
subscription := Subscription{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&subscription)
existed, err := ormer.Engine.Get(&subscription)
if err != nil {
return nil, err
}
@@ -119,7 +119,7 @@ func UpdateSubscription(id string, subscription *Subscription) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(subscription)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(subscription)
if err != nil {
return false, err
}
@@ -128,7 +128,7 @@ func UpdateSubscription(id string, subscription *Subscription) (bool, error) {
}
func AddSubscription(subscription *Subscription) (bool, error) {
affected, err := adapter.Engine.Insert(subscription)
affected, err := ormer.Engine.Insert(subscription)
if err != nil {
return false, err
}
@@ -137,7 +137,7 @@ func AddSubscription(subscription *Subscription) (bool, error) {
}
func DeleteSubscription(subscription *Subscription) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{subscription.Owner, subscription.Name}).Delete(&Subscription{})
affected, err := ormer.Engine.ID(core.PK{subscription.Owner, subscription.Name}).Delete(&Subscription{})
if err != nil {
return false, err
}

View File

@@ -53,7 +53,7 @@ type Syncer struct {
IsReadOnly bool `json:"isReadOnly"`
IsEnabled bool `json:"isEnabled"`
Adapter *Adapter `xorm:"-" json:"-"`
Ormer *Ormer `xorm:"-" json:"-"`
}
func GetSyncerCount(owner, organization, field, value string) (int64, error) {
@@ -63,7 +63,7 @@ func GetSyncerCount(owner, organization, field, value string) (int64, error) {
func GetSyncers(owner string) ([]*Syncer, error) {
syncers := []*Syncer{}
err := adapter.Engine.Desc("created_time").Find(&syncers, &Syncer{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&syncers, &Syncer{Owner: owner})
if err != nil {
return syncers, err
}
@@ -73,7 +73,7 @@ func GetSyncers(owner string) ([]*Syncer, error) {
func GetOrganizationSyncers(owner, organization string) ([]*Syncer, error) {
syncers := []*Syncer{}
err := adapter.Engine.Desc("created_time").Find(&syncers, &Syncer{Owner: owner, Organization: organization})
err := ormer.Engine.Desc("created_time").Find(&syncers, &Syncer{Owner: owner, Organization: organization})
if err != nil {
return syncers, err
}
@@ -98,7 +98,7 @@ func getSyncer(owner string, name string) (*Syncer, error) {
}
syncer := Syncer{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&syncer)
existed, err := ormer.Engine.Get(&syncer)
if err != nil {
return &syncer, err
}
@@ -141,7 +141,7 @@ func UpdateSyncer(id string, syncer *Syncer) (bool, error) {
return false, nil
}
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
session := ormer.Engine.ID(core.PK{owner, name}).AllCols()
if syncer.Password == "***" {
session.Omit("password")
}
@@ -172,7 +172,7 @@ func updateSyncerErrorText(syncer *Syncer, line string) (bool, error) {
s.ErrorText = s.ErrorText + line
affected, err := adapter.Engine.ID(core.PK{s.Owner, s.Name}).Cols("error_text").Update(s)
affected, err := ormer.Engine.ID(core.PK{s.Owner, s.Name}).Cols("error_text").Update(s)
if err != nil {
return false, err
}
@@ -181,7 +181,7 @@ func updateSyncerErrorText(syncer *Syncer, line string) (bool, error) {
}
func AddSyncer(syncer *Syncer) (bool, error) {
affected, err := adapter.Engine.Insert(syncer)
affected, err := ormer.Engine.Insert(syncer)
if err != nil {
return false, err
}
@@ -197,7 +197,7 @@ func AddSyncer(syncer *Syncer) (bool, error) {
}
func DeleteSyncer(syncer *Syncer) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{syncer.Owner, syncer.Name}).Delete(&Syncer{})
affected, err := ormer.Engine.ID(core.PK{syncer.Owner, syncer.Name}).Delete(&Syncer{})
if err != nil {
return false, err
}

View File

@@ -21,7 +21,7 @@ type Affiliation struct {
func (syncer *Syncer) getAffiliations() ([]*Affiliation, error) {
affiliations := []*Affiliation{}
err := syncer.Adapter.Engine.Table(syncer.AffiliationTable).Asc("id").Find(&affiliations)
err := syncer.Ormer.Engine.Table(syncer.AffiliationTable).Asc("id").Find(&affiliations)
if err != nil {
return nil, err
}

View File

@@ -32,7 +32,7 @@ type Credential struct {
func (syncer *Syncer) getOriginalUsers() ([]*OriginalUser, error) {
sql := fmt.Sprintf("select * from %s", syncer.getTable())
results, err := syncer.Adapter.Engine.QueryString(sql)
results, err := syncer.Ormer.Engine.QueryString(sql)
if err != nil {
return nil, err
}
@@ -67,7 +67,7 @@ func (syncer *Syncer) addUser(user *OriginalUser) (bool, error) {
keyString, valueString := syncer.getSqlKeyValueStringFromMap(m)
sql := fmt.Sprintf("insert into %s (%s) values (%s)", syncer.getTable(), keyString, valueString)
res, err := syncer.Adapter.Engine.Exec(sql)
res, err := syncer.Ormer.Engine.Exec(sql)
if err != nil {
return false, err
}
@@ -108,7 +108,7 @@ func (syncer *Syncer) updateUser(user *OriginalUser) (bool, error) {
setString := syncer.getSqlSetStringFromMap(m)
sql := fmt.Sprintf("update %s set %s where %s = %s", syncer.getTable(), setString, syncer.TablePrimaryKey, pkValue)
res, err := syncer.Adapter.Engine.Exec(sql)
res, err := syncer.Ormer.Engine.Exec(sql)
if err != nil {
return false, err
}
@@ -138,7 +138,7 @@ func (syncer *Syncer) updateUserForOriginalFields(user *User) (bool, error) {
columns := syncer.getCasdoorColumns()
columns = append(columns, "affiliation", "hash", "pre_hash")
affected, err := adapter.Engine.ID(core.PK{oldUser.Owner, oldUser.Name}).Cols(columns...).Update(user)
affected, err := ormer.Engine.ID(core.PK{oldUser.Owner, oldUser.Name}).Cols(columns...).Update(user)
if err != nil {
return false, err
}
@@ -160,7 +160,7 @@ func (syncer *Syncer) calculateHash(user *OriginalUser) string {
}
func (syncer *Syncer) initAdapter() {
if syncer.Adapter == nil {
if syncer.Ormer == nil {
var dataSourceName string
if syncer.DatabaseType == "mssql" {
dataSourceName = fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s", syncer.User, syncer.Password, syncer.Host, syncer.Port, syncer.Database)
@@ -174,7 +174,7 @@ func (syncer *Syncer) initAdapter() {
dataSourceName = strings.ReplaceAll(dataSourceName, "dbi.", "db.")
}
syncer.Adapter = NewAdapter(syncer.DatabaseType, dataSourceName, syncer.Database)
syncer.Ormer = NewAdapter(syncer.DatabaseType, dataSourceName, syncer.Database)
}
}

View File

@@ -196,7 +196,7 @@ func (syncer *Syncer) getOriginalUsersFromMap(results []map[string]string) []*Or
if syncer.Type == "Keycloak" {
// query and set password and password salt from credential table
sql := fmt.Sprintf("select * from credential where type = 'password' and user_id = '%s'", originalUser.Id)
credentialResult, _ := syncer.Adapter.Engine.QueryString(sql)
credentialResult, _ := syncer.Ormer.Engine.QueryString(sql)
if len(credentialResult) > 0 {
credential := Credential{}
_ = json.Unmarshal([]byte(credentialResult[0]["SECRET_DATA"]), &credential)
@@ -206,7 +206,7 @@ func (syncer *Syncer) getOriginalUsersFromMap(results []map[string]string) []*Or
// query and set signup application from user group table
sql = fmt.Sprintf("select name from keycloak_group where id = "+
"(select group_id as gid from user_group_membership where user_id = '%s')", originalUser.Id)
groupResult, _ := syncer.Adapter.Engine.QueryString(sql)
groupResult, _ := syncer.Ormer.Engine.QueryString(sql)
if len(groupResult) > 0 {
originalUser.SignupApplication = groupResult[0]["name"]
}

View File

@@ -98,7 +98,7 @@ func GetTokenCount(owner, organization, field, value string) (int64, error) {
func GetTokens(owner string, organization string) ([]*Token, error) {
tokens := []*Token{}
err := adapter.Engine.Desc("created_time").Find(&tokens, &Token{Owner: owner, Organization: organization})
err := ormer.Engine.Desc("created_time").Find(&tokens, &Token{Owner: owner, Organization: organization})
return tokens, err
}
@@ -115,7 +115,7 @@ func getToken(owner string, name string) (*Token, error) {
}
token := Token{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&token)
existed, err := ormer.Engine.Get(&token)
if err != nil {
return nil, err
}
@@ -129,7 +129,7 @@ func getToken(owner string, name string) (*Token, error) {
func getTokenByCode(code string) (*Token, error) {
token := Token{Code: code}
existed, err := adapter.Engine.Get(&token)
existed, err := ormer.Engine.Get(&token)
if err != nil {
return nil, err
}
@@ -142,7 +142,7 @@ func getTokenByCode(code string) (*Token, error) {
}
func updateUsedByCode(token *Token) bool {
affected, err := adapter.Engine.Where("code=?", token.Code).Cols("code_is_used").Update(token)
affected, err := ormer.Engine.Where("code=?", token.Code).Cols("code_is_used").Update(token)
if err != nil {
panic(err)
}
@@ -167,7 +167,7 @@ func UpdateToken(id string, token *Token) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(token)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(token)
if err != nil {
return false, err
}
@@ -176,7 +176,7 @@ func UpdateToken(id string, token *Token) (bool, error) {
}
func AddToken(token *Token) (bool, error) {
affected, err := adapter.Engine.Insert(token)
affected, err := ormer.Engine.Insert(token)
if err != nil {
return false, err
}
@@ -185,7 +185,7 @@ func AddToken(token *Token) (bool, error) {
}
func DeleteToken(token *Token) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{token.Owner, token.Name}).Delete(&Token{})
affected, err := ormer.Engine.ID(core.PK{token.Owner, token.Name}).Delete(&Token{})
if err != nil {
return false, err
}
@@ -195,7 +195,7 @@ func DeleteToken(token *Token) (bool, error) {
func ExpireTokenByAccessToken(accessToken string) (bool, *Application, *Token, error) {
token := Token{AccessToken: accessToken}
existed, err := adapter.Engine.Get(&token)
existed, err := ormer.Engine.Get(&token)
if err != nil {
return false, nil, nil, err
}
@@ -205,7 +205,7 @@ func ExpireTokenByAccessToken(accessToken string) (bool, *Application, *Token, e
}
token.ExpiresIn = 0
affected, err := adapter.Engine.ID(core.PK{token.Owner, token.Name}).Cols("expires_in").Update(&token)
affected, err := ormer.Engine.ID(core.PK{token.Owner, token.Name}).Cols("expires_in").Update(&token)
if err != nil {
return false, nil, nil, err
}
@@ -221,7 +221,7 @@ func ExpireTokenByAccessToken(accessToken string) (bool, *Application, *Token, e
func GetTokenByAccessToken(accessToken string) (*Token, error) {
// Check if the accessToken is in the database
token := Token{AccessToken: accessToken}
existed, err := adapter.Engine.Get(&token)
existed, err := ormer.Engine.Get(&token)
if err != nil {
return nil, err
}
@@ -235,7 +235,7 @@ func GetTokenByAccessToken(accessToken string) (*Token, error) {
func GetTokenByTokenAndApplication(token string, application string) (*Token, error) {
tokenResult := Token{}
existed, err := adapter.Engine.Where("(refresh_token = ? or access_token = ? ) and application = ?", token, token, application).Get(&tokenResult)
existed, err := ormer.Engine.Where("(refresh_token = ? or access_token = ? ) and application = ?", token, token, application).Get(&tokenResult)
if err != nil {
return nil, err
}
@@ -440,7 +440,7 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
}
// check whether the refresh token is valid, and has not expired.
token := Token{RefreshToken: refreshToken}
existed, err := adapter.Engine.Get(&token)
existed, err := ormer.Engine.Get(&token)
if err != nil || !existed {
return &TokenError{
Error: InvalidGrant,

View File

@@ -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{

View File

@@ -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 {

View File

@@ -156,6 +156,7 @@ 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"`
@@ -206,7 +207,7 @@ func GetGlobalUserCount(field, value string) (int64, error) {
func GetGlobalUsers() ([]*User, error) {
users := []*User{}
err := adapter.Engine.Desc("created_time").Find(&users)
err := ormer.Engine.Desc("created_time").Find(&users)
if err != nil {
return nil, err
}
@@ -236,12 +237,12 @@ func GetUserCount(owner, field, value string, groupName string) (int64, error) {
}
func GetOnlineUserCount(owner string, isOnline int) (int64, error) {
return adapter.Engine.Where("is_online = ?", isOnline).Count(&User{Owner: owner})
return ormer.Engine.Where("is_online = ?", isOnline).Count(&User{Owner: owner})
}
func GetUsers(owner string) ([]*User, error) {
users := []*User{}
err := adapter.Engine.Desc("created_time").Find(&users, &User{Owner: owner})
err := ormer.Engine.Desc("created_time").Find(&users, &User{Owner: owner})
if err != nil {
return nil, err
}
@@ -251,7 +252,7 @@ func GetUsers(owner string) ([]*User, error) {
func GetUsersByTag(owner string, tag string) ([]*User, error) {
users := []*User{}
err := adapter.Engine.Desc("created_time").Find(&users, &User{Owner: owner, Tag: tag})
err := ormer.Engine.Desc("created_time").Find(&users, &User{Owner: owner, Tag: tag})
if err != nil {
return nil, err
}
@@ -261,7 +262,7 @@ func GetUsersByTag(owner string, tag string) ([]*User, error) {
func GetSortedUsers(owner string, sorter string, limit int) ([]*User, error) {
users := []*User{}
err := adapter.Engine.Desc(sorter).Limit(limit, 0).Find(&users, &User{Owner: owner})
err := ormer.Engine.Desc(sorter).Limit(limit, 0).Find(&users, &User{Owner: owner})
if err != nil {
return nil, err
}
@@ -290,7 +291,7 @@ func getUser(owner string, name string) (*User, error) {
}
user := User{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&user)
existed, err := ormer.Engine.Get(&user)
if err != nil {
return nil, err
}
@@ -308,7 +309,7 @@ func getUserById(owner string, id string) (*User, error) {
}
user := User{Owner: owner, Id: id}
existed, err := adapter.Engine.Get(&user)
existed, err := ormer.Engine.Get(&user)
if err != nil {
return nil, err
}
@@ -325,7 +326,7 @@ func getUserByWechatId(owner string, wechatOpenId string, wechatUnionId string)
wechatUnionId = wechatOpenId
}
user := &User{}
existed, err := adapter.Engine.Where("owner = ?", owner).Where("wechat = ? OR wechat = ?", wechatOpenId, wechatUnionId).Get(user)
existed, err := ormer.Engine.Where("owner = ?", owner).Where("wechat = ? OR wechat = ?", wechatOpenId, wechatUnionId).Get(user)
if err != nil {
return nil, err
}
@@ -343,7 +344,7 @@ func GetUserByEmail(owner string, email string) (*User, error) {
}
user := User{Owner: owner, Email: email}
existed, err := adapter.Engine.Get(&user)
existed, err := ormer.Engine.Get(&user)
if err != nil {
return nil, err
}
@@ -361,7 +362,7 @@ func GetUserByPhone(owner string, phone string) (*User, error) {
}
user := User{Owner: owner, Phone: phone}
existed, err := adapter.Engine.Get(&user)
existed, err := ormer.Engine.Get(&user)
if err != nil {
return nil, err
}
@@ -379,7 +380,7 @@ func GetUserByUserId(owner string, userId string) (*User, error) {
}
user := User{Owner: owner, Id: userId}
existed, err := adapter.Engine.Get(&user)
existed, err := ormer.Engine.Get(&user)
if err != nil {
return nil, err
}
@@ -396,7 +397,7 @@ func GetUserByAccessKey(accessKey string) (*User, error) {
return nil, nil
}
user := User{AccessKey: accessKey}
existed, err := adapter.Engine.Get(&user)
existed, err := ormer.Engine.Get(&user)
if err != nil {
return nil, err
}
@@ -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
}
@@ -466,7 +471,7 @@ func GetMaskedUsers(users []*User, errs ...error) ([]*User, error) {
func GetLastUser(owner string) (*User, error) {
user := User{Owner: owner}
existed, err := adapter.Engine.Desc("created_time", "id").Get(&user)
existed, err := ormer.Engine.Desc("created_time", "id").Get(&user)
if err != nil {
return nil, err
}
@@ -541,7 +546,7 @@ func updateUser(id string, user *User, columns []string) (int64, error) {
return 0, err
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).Cols(columns...).Update(user)
affected, err := ormer.Engine.ID(core.PK{owner, name}).Cols(columns...).Update(user)
if err != nil {
return 0, err
}
@@ -579,7 +584,7 @@ func UpdateUserForAllFields(id string, user *User) (bool, error) {
}
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(user)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(user)
if err != nil {
return false, err
}
@@ -633,7 +638,7 @@ func AddUser(user *User) (bool, error) {
}
user.Ranking = int(count + 1)
affected, err := adapter.Engine.Insert(user)
affected, err := ormer.Engine.Insert(user)
if err != nil {
return false, err
}
@@ -665,7 +670,7 @@ func AddUsers(users []*User) (bool, error) {
}
}
affected, err := adapter.Engine.Insert(users)
affected, err := ormer.Engine.Insert(users)
if err != nil {
if !strings.Contains(err.Error(), "Duplicate entry") {
return false, err
@@ -710,7 +715,7 @@ func DeleteUser(user *User) (bool, error) {
return false, err
}
affected, err := adapter.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
affected, err := ormer.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
if err != nil {
return false, err
}
@@ -774,7 +779,7 @@ func ExtendUserWithRolesAndPermissions(user *User) (err error) {
}
func userChangeTrigger(oldName string, newName string) error {
session := adapter.Engine.NewSession()
session := ormer.Engine.NewSession()
defer session.Close()
err := session.Begin()
@@ -783,7 +788,7 @@ func userChangeTrigger(oldName string, newName string) error {
}
var roles []*Role
err = adapter.Engine.Find(&roles)
err = ormer.Engine.Find(&roles)
if err != nil {
return err
}
@@ -803,7 +808,7 @@ func userChangeTrigger(oldName string, newName string) error {
}
var permissions []*Permission
err = adapter.Engine.Find(&permissions)
err = ormer.Engine.Find(&permissions)
if err != nil {
return err
}
@@ -855,3 +860,11 @@ func AddUserkeys(user *User, isAdmin bool) (bool, error) {
return UpdateUser(user.GetId(), user, []string{}, isAdmin)
}
func (user *User) IsApplicationAdmin(application *Application) bool {
if user == nil {
return false
}
return (user.Owner == application.Organization && user.IsAdmin) || user.IsGlobalAdmin
}

View File

@@ -25,7 +25,7 @@ import (
)
func updateUserColumn(column string, user *User) bool {
affected, err := adapter.Engine.ID(core.PK{user.Owner, user.Name}).Cols(column).Update(user)
affected, err := ormer.Engine.ID(core.PK{user.Owner, user.Name}).Cols(column).Update(user)
if err != nil {
panic(err)
}

View File

@@ -30,7 +30,7 @@ func GetUserByField(organizationName string, field string, value string) (*User,
}
user := User{Owner: organizationName}
existed, err := adapter.Engine.Where(fmt.Sprintf("%s=?", strings.ToLower(field)), value).Get(&user)
existed, err := ormer.Engine.Where(fmt.Sprintf("%s=?", strings.ToLower(field)), value).Get(&user)
if err != nil {
return nil, err
}
@@ -95,7 +95,7 @@ func SetUserField(user *User, field string, value string) (bool, error) {
bean[strings.ToLower(field)] = value
}
affected, err := adapter.Engine.Table(user).ID(core.PK{user.Owner, user.Name}).Update(bean)
affected, err := ormer.Engine.Table(user).ID(core.PK{user.Owner, user.Name}).Update(bean)
if err != nil {
return false, err
}
@@ -110,7 +110,7 @@ func SetUserField(user *User, field string, value string) (bool, error) {
return false, err
}
_, err = adapter.Engine.ID(core.PK{user.Owner, user.Name}).Cols("hash").Update(user)
_, err = ormer.Engine.ID(core.PK{user.Owner, user.Name}).Cols("hash").Update(user)
if err != nil {
return false, err
}
@@ -191,7 +191,7 @@ func ClearUserOAuthProperties(user *User, providerType string) (bool, error) {
}
}
affected, err := adapter.Engine.ID(core.PK{user.Owner, user.Name}).Cols("properties").Update(user)
affected, err := ormer.Engine.ID(core.PK{user.Owner, user.Name}).Cols("properties").Update(user)
if err != nil {
return false, err
}
@@ -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)

View File

@@ -66,7 +66,7 @@ func IsAllowSend(user *User, remoteAddr, recordType string) error {
if user != nil {
record.User = user.GetId()
}
has, err := adapter.Engine.Desc("created_time").Get(&record)
has, err := ormer.Engine.Desc("created_time").Get(&record)
if err != nil {
return err
}
@@ -143,7 +143,7 @@ func AddToVerificationRecord(user *User, provider *Provider, remoteAddr, recordT
record.Time = time.Now().Unix()
record.IsUsed = false
_, err := adapter.Engine.Insert(record)
_, err := ormer.Engine.Insert(record)
if err != nil {
return err
}
@@ -154,7 +154,7 @@ func AddToVerificationRecord(user *User, provider *Provider, remoteAddr, recordT
func getVerificationRecord(dest string) (*VerificationRecord, error) {
var record VerificationRecord
record.Receiver = dest
has, err := adapter.Engine.Desc("time").Where("is_used = false").Get(&record)
has, err := ormer.Engine.Desc("time").Where("is_used = false").Get(&record)
if err != nil {
return nil, err
}
@@ -198,7 +198,7 @@ func DisableVerificationCode(dest string) (err error) {
}
record.IsUsed = true
_, err = adapter.Engine.ID(core.PK{record.Owner, record.Name}).AllCols().Update(record)
_, err = ormer.Engine.ID(core.PK{record.Owner, record.Name}).AllCols().Update(record)
return
}

View File

@@ -49,7 +49,7 @@ func GetWebhookCount(owner, organization, field, value string) (int64, error) {
func GetWebhooks(owner string, organization string) ([]*Webhook, error) {
webhooks := []*Webhook{}
err := adapter.Engine.Desc("created_time").Find(&webhooks, &Webhook{Owner: owner, Organization: organization})
err := ormer.Engine.Desc("created_time").Find(&webhooks, &Webhook{Owner: owner, Organization: organization})
if err != nil {
return webhooks, err
}
@@ -70,7 +70,7 @@ func GetPaginationWebhooks(owner, organization string, offset, limit int, field,
func getWebhooksByOrganization(organization string) ([]*Webhook, error) {
webhooks := []*Webhook{}
err := adapter.Engine.Desc("created_time").Find(&webhooks, &Webhook{Organization: organization})
err := ormer.Engine.Desc("created_time").Find(&webhooks, &Webhook{Organization: organization})
if err != nil {
return webhooks, err
}
@@ -84,7 +84,7 @@ func getWebhook(owner string, name string) (*Webhook, error) {
}
webhook := Webhook{Owner: owner, Name: name}
existed, err := adapter.Engine.Get(&webhook)
existed, err := ormer.Engine.Get(&webhook)
if err != nil {
return &webhook, err
}
@@ -109,7 +109,7 @@ func UpdateWebhook(id string, webhook *Webhook) (bool, error) {
return false, nil
}
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(webhook)
affected, err := ormer.Engine.ID(core.PK{owner, name}).AllCols().Update(webhook)
if err != nil {
return false, err
}
@@ -118,7 +118,7 @@ func UpdateWebhook(id string, webhook *Webhook) (bool, error) {
}
func AddWebhook(webhook *Webhook) (bool, error) {
affected, err := adapter.Engine.Insert(webhook)
affected, err := ormer.Engine.Insert(webhook)
if err != nil {
return false, err
}
@@ -127,7 +127,7 @@ func AddWebhook(webhook *Webhook) (bool, error) {
}
func DeleteWebhook(webhook *Webhook) (bool, error) {
affected, err := adapter.Engine.ID(core.PK{webhook.Owner, webhook.Name}).Delete(&Webhook{})
affected, err := ormer.Engine.ID(core.PK{webhook.Owner, webhook.Name}).Delete(&Webhook{})
if err != nil {
return false, err
}

View File

@@ -69,7 +69,7 @@ func getObject(ctx *context.Context) (string, string) {
// query == "?id=built-in/admin"
id := ctx.Input.Query("id")
if id != "" {
return util.GetOwnerAndNameFromId(id)
return util.GetOwnerAndNameFromIdNoCheck(id)
}
owner := ctx.Input.Query("owner")
@@ -150,13 +150,13 @@ func getUrlPath(urlPath string) string {
return urlPath
}
func AuthzFilter(ctx *context.Context) {
func ApiFilter(ctx *context.Context) {
subOwner, subName := getSubject(ctx)
method := ctx.Request.Method
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)
}

View File

@@ -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 {

View File

@@ -13,10 +13,14 @@
// limitations under the License.
// Package routers
// @APIVersion 1.0.0
// @Title Casdoor API
// @Description Documentation of Casdoor API
// @Contact admin@casbin.org
// @APIVersion 1.376.1
// @Title Casdoor RESTful API
// @Description Swagger Docs of Casdoor Backend API
// @Contact casbin@googlegroups.com
// @SecurityDefinition AccessToken apiKey Authorization header
// @Schemes https,http
// @ExternalDocs Find out more about Casdoor
// @ExternalDocsUrl https://casdoor.org/
package routers
import (
@@ -113,16 +117,22 @@ func initAPI() {
beego.Router("/api/add-model", &controllers.ApiController{}, "POST:AddModel")
beego.Router("/api/delete-model", &controllers.ApiController{}, "POST:DeleteModel")
beego.Router("/api/get-adapters", &controllers.ApiController{}, "GET:GetCasbinAdapters")
beego.Router("/api/get-adapter", &controllers.ApiController{}, "GET:GetCasbinAdapter")
beego.Router("/api/update-adapter", &controllers.ApiController{}, "POST:UpdateCasbinAdapter")
beego.Router("/api/add-adapter", &controllers.ApiController{}, "POST:AddCasbinAdapter")
beego.Router("/api/delete-adapter", &controllers.ApiController{}, "POST:DeleteCasbinAdapter")
beego.Router("/api/get-adapters", &controllers.ApiController{}, "GET:GetAdapters")
beego.Router("/api/get-adapter", &controllers.ApiController{}, "GET:GetAdapter")
beego.Router("/api/update-adapter", &controllers.ApiController{}, "POST:UpdateAdapter")
beego.Router("/api/add-adapter", &controllers.ApiController{}, "POST:AddAdapter")
beego.Router("/api/delete-adapter", &controllers.ApiController{}, "POST:DeleteAdapter")
beego.Router("/api/sync-policies", &controllers.ApiController{}, "GET:SyncPolicies")
beego.Router("/api/update-policy", &controllers.ApiController{}, "POST:UpdatePolicy")
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")
@@ -251,18 +261,6 @@ func initAPI() {
beego.Router("/api/send-email", &controllers.ApiController{}, "POST:SendEmail")
beego.Router("/api/send-sms", &controllers.ApiController{}, "POST:SendSms")
beego.Router("/.well-known/openid-configuration", &controllers.RootController{}, "GET:GetOidcDiscovery")
beego.Router("/.well-known/jwks", &controllers.RootController{}, "*:GetJwks")
beego.Router("/cas/:organization/:application/serviceValidate", &controllers.RootController{}, "GET:CasServiceValidate")
beego.Router("/cas/:organization/:application/proxyValidate", &controllers.RootController{}, "GET:CasProxyValidate")
beego.Router("/cas/:organization/:application/proxy", &controllers.RootController{}, "GET:CasProxy")
beego.Router("/cas/:organization/:application/validate", &controllers.RootController{}, "GET:CasValidate")
beego.Router("/cas/:organization/:application/p3/serviceValidate", &controllers.RootController{}, "GET:CasP3ServiceAndProxyValidate")
beego.Router("/cas/:organization/:application/p3/proxyValidate", &controllers.RootController{}, "GET:CasP3ServiceAndProxyValidate")
beego.Router("/cas/:organization/:application/samlValidate", &controllers.RootController{}, "POST:SamlValidate")
beego.Router("/api/webauthn/signup/begin", &controllers.ApiController{}, "Get:WebAuthnSignupBegin")
beego.Router("/api/webauthn/signup/finish", &controllers.ApiController{}, "Post:WebAuthnSignupFinish")
beego.Router("/api/webauthn/signin/begin", &controllers.ApiController{}, "Get:WebAuthnSigninBegin")
@@ -280,4 +278,16 @@ func initAPI() {
beego.Router("/api/get-prometheus-info", &controllers.ApiController{}, "GET:GetPrometheusInfo")
beego.Handler("/api/metrics", promhttp.Handler())
beego.Router("/.well-known/openid-configuration", &controllers.RootController{}, "GET:GetOidcDiscovery")
beego.Router("/.well-known/jwks", &controllers.RootController{}, "*:GetJwks")
beego.Router("/cas/:organization/:application/serviceValidate", &controllers.RootController{}, "GET:CasServiceValidate")
beego.Router("/cas/:organization/:application/proxyValidate", &controllers.RootController{}, "GET:CasProxyValidate")
beego.Router("/cas/:organization/:application/proxy", &controllers.RootController{}, "GET:CasProxy")
beego.Router("/cas/:organization/:application/validate", &controllers.RootController{}, "GET:CasValidate")
beego.Router("/cas/:organization/:application/p3/serviceValidate", &controllers.RootController{}, "GET:CasP3ServiceAndProxyValidate")
beego.Router("/cas/:organization/:application/p3/proxyValidate", &controllers.RootController{}, "GET:CasP3ServiceAndProxyValidate")
beego.Router("/cas/:organization/:application/samlValidate", &controllers.RootController{}, "POST:SamlValidate")
}

View File

@@ -68,11 +68,11 @@ func StaticFilter(ctx *context.Context) {
if oldStaticBaseUrl == newStaticBaseUrl {
makeGzipResponse(ctx.ResponseWriter, ctx.Request, path)
} else {
serveFileWithReplace(ctx.ResponseWriter, ctx.Request, path, oldStaticBaseUrl, newStaticBaseUrl)
serveFileWithReplace(ctx.ResponseWriter, ctx.Request, path)
}
}
func serveFileWithReplace(w http.ResponseWriter, r *http.Request, name string, old string, new string) {
func serveFileWithReplace(w http.ResponseWriter, r *http.Request, name string) {
f, err := os.Open(filepath.Clean(name))
if err != nil {
panic(err)
@@ -85,13 +85,9 @@ func serveFileWithReplace(w http.ResponseWriter, r *http.Request, name string, o
}
oldContent := util.ReadStringFromPath(name)
newContent := strings.ReplaceAll(oldContent, old, new)
newContent := strings.ReplaceAll(oldContent, oldStaticBaseUrl, newStaticBaseUrl)
http.ServeContent(w, r, d.Name(), d.ModTime(), strings.NewReader(newContent))
_, err = w.Write([]byte(newContent))
if err != nil {
panic(err)
}
}
type gzipResponseWriter struct {
@@ -105,12 +101,12 @@ func (w gzipResponseWriter) Write(b []byte) (int, error) {
func makeGzipResponse(w http.ResponseWriter, r *http.Request, path string) {
if !enableGzip || !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
http.ServeFile(w, r, path)
serveFileWithReplace(w, r, path)
return
}
w.Header().Set("Content-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
gzw := gzipResponseWriter{Writer: gz, ResponseWriter: w}
http.ServeFile(gzw, r, path)
serveFileWithReplace(gzw, r, path)
}

View File

@@ -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":

View File

@@ -1,14 +1,18 @@
{
"swagger": "2.0",
"info": {
"title": "Casdoor API",
"description": "Documentation of Casdoor API",
"version": "1.0.0",
"title": "Casdoor RESTful API",
"description": "Swagger Docs of Casdoor Backend API",
"version": "1.376.1",
"contact": {
"email": "admin@casbin.org"
"email": "casbin@googlegroups.com"
}
},
"basePath": "/",
"schemes": [
"https",
"http"
],
"paths": {
"/.well-known/jwks": {
"get": {
@@ -49,7 +53,7 @@
"Adapter API"
],
"description": "add adapter",
"operationId": "ApiController.AddCasbinAdapter",
"operationId": "ApiController.AddAdapter",
"parameters": [
{
"in": "body",
@@ -155,6 +159,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 +220,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": {
@@ -947,7 +999,7 @@
"Adapter API"
],
"description": "delete adapter",
"operationId": "ApiController.DeleteCasbinAdapter",
"operationId": "ApiController.DeleteAdapter",
"parameters": [
{
"in": "body",
@@ -1053,6 +1105,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": [
@@ -1086,7 +1166,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": {
@@ -1651,7 +1751,7 @@
"Adapter API"
],
"description": "get adapter",
"operationId": "ApiController.GetCasbinAdapter",
"operationId": "ApiController.GetAdapter",
"parameters": [
{
"in": "query",
@@ -1677,7 +1777,7 @@
"Adapter API"
],
"description": "get adapters",
"operationId": "ApiController.GetCasbinAdapters",
"operationId": "ApiController.GetAdapters",
"parameters": [
{
"in": "query",
@@ -1978,6 +2078,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": [
@@ -2098,7 +2253,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": {
@@ -2106,7 +2279,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": {
@@ -2114,7 +2296,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": {
@@ -3484,7 +3686,8 @@
"name": "id",
"description": "The id ( owner/name ) of the webhook",
"required": true,
"type": "string"
"type": "string",
"default": "built-in/admin"
}
],
"responses": {
@@ -3510,7 +3713,8 @@
"name": "owner",
"description": "The owner of webhooks",
"required": true,
"type": "string"
"type": "string",
"default": "built-in/admin"
}
],
"responses": {
@@ -3523,7 +3727,12 @@
}
}
}
}
},
"security": [
{
"test_apiKey": []
}
]
}
},
"/api/health": {
@@ -4139,7 +4348,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": {
@@ -4155,7 +4382,7 @@
"Adapter API"
],
"description": "update adapter",
"operationId": "ApiController.UpdateCasbinAdapter",
"operationId": "ApiController.UpdateAdapter",
"parameters": [
{
"in": "query",
@@ -4289,6 +4516,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": [
@@ -4329,7 +4591,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": {
@@ -4899,7 +5181,8 @@
"name": "id",
"description": "The id ( owner/name ) of the webhook",
"required": true,
"type": "string"
"type": "string",
"default": "built-in/admin"
},
{
"in": "body",
@@ -5152,10 +5435,22 @@
"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"
@@ -5529,6 +5824,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",
@@ -5681,6 +6013,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",
@@ -7137,6 +7522,9 @@
"meetup": {
"type": "string"
},
"metamask": {
"type": "string"
},
"mfaEmailEnabled": {
"type": "boolean"
},
@@ -7484,5 +7872,16 @@
"title": "Engine",
"type": "object"
}
},
"securityDefinitions": {
"AccessToken": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
}
},
"externalDocs": {
"description": "Find out more about Casdoor",
"url": "https://casdoor.org/"
}
}

View File

@@ -1,11 +1,14 @@
swagger: "2.0"
info:
title: Casdoor API
description: Documentation of Casdoor API
version: 1.0.0
title: Casdoor RESTful API
description: Swagger Docs of Casdoor Backend API
version: 1.376.1
contact:
email: admin@casbin.org
email: casbin@googlegroups.com
basePath: /
schemes:
- https
- http
paths:
/.well-known/jwks:
get:
@@ -33,7 +36,7 @@ paths:
tags:
- Adapter API
description: add adapter
operationId: ApiController.AddCasbinAdapter
operationId: ApiController.AddAdapter
parameters:
- in: body
name: body
@@ -100,6 +103,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 +143,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:
@@ -613,7 +647,7 @@ paths:
tags:
- Adapter API
description: delete adapter
operationId: ApiController.DeleteCasbinAdapter
operationId: ApiController.DeleteAdapter
parameters:
- in: body
name: body
@@ -680,6 +714,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:
@@ -702,7 +754,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:
@@ -1066,7 +1131,7 @@ paths:
tags:
- Adapter API
description: get adapter
operationId: ApiController.GetCasbinAdapter
operationId: ApiController.GetAdapter
parameters:
- in: query
name: id
@@ -1083,7 +1148,7 @@ paths:
tags:
- Adapter API
description: get adapters
operationId: ApiController.GetCasbinAdapters
operationId: ApiController.GetAdapters
parameters:
- in: query
name: owner
@@ -1281,6 +1346,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:
@@ -1360,17 +1461,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:
@@ -2272,6 +2404,7 @@ paths:
description: The id ( owner/name ) of the webhook
required: true
type: string
default: built-in/admin
responses:
"200":
description: The Response object
@@ -2289,6 +2422,7 @@ paths:
description: The owner of webhooks
required: true
type: string
default: built-in/admin
responses:
"200":
description: The Response object
@@ -2296,6 +2430,8 @@ paths:
type: array
items:
$ref: '#/definitions/object.Webhook'
security:
- test_apiKey: []
/api/health:
get:
tags:
@@ -2703,7 +2839,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:
@@ -2713,7 +2861,7 @@ paths:
tags:
- Adapter API
description: update adapter
operationId: ApiController.UpdateCasbinAdapter
operationId: ApiController.UpdateAdapter
parameters:
- in: query
name: id
@@ -2800,6 +2948,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:
@@ -2827,7 +2998,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:
@@ -3204,6 +3388,7 @@ paths:
description: The id ( owner/name ) of the webhook
required: true
type: string
default: built-in/admin
- in: body
name: body
description: The details of the webhook
@@ -3367,9 +3552,18 @@ definitions:
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
@@ -3622,6 +3816,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
@@ -3725,6 +3944,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
@@ -4704,6 +4959,8 @@ definitions:
$ref: '#/definitions/object.ManagedAccount'
meetup:
type: string
metamask:
type: string
mfaEmailEnabled:
type: boolean
mfaPhoneEnabled:
@@ -4938,3 +5195,11 @@ definitions:
xorm.Engine:
title: Engine
type: object
securityDefinitions:
AccessToken:
type: apiKey
name: Authorization
in: header
externalDocs:
description: Find out more about Casdoor
url: https://casdoor.org/

View File

@@ -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;
},
}
};

View File

@@ -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"

View File

@@ -13,7 +13,7 @@
// limitations under the License.
import React from "react";
import {Button, Card, Col, Input, InputNumber, Row, Select, Switch} from "antd";
import {Button, Card, Col, Input, Row, Select, Switch} from "antd";
import * as AdapterBackend from "./backend/AdapterBackend";
import * as OrganizationBackend from "./backend/OrganizationBackend";
import * as Setting from "./Setting";
@@ -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,16 +80,17 @@ class AdapterEditPage extends React.Component {
Setting.showMessage("error", res.msg);
return;
}
this.setState({
models: res,
models: res.data,
});
});
}
parseAdapterField(key, value) {
if (["port"].includes(key)) {
value = Setting.myParseInt(value);
}
// if ([].includes(key)) {
// value = Setting.myParseInt(value);
// }
return value;
}
@@ -103,6 +104,73 @@ class AdapterEditPage extends React.Component {
});
}
renderDataSourceNameConfig() {
if (Setting.builtInObject(this.state.adapter)) {
return null;
}
return (
<React.Fragment>{
this.state.adapter.databaseType === "sqlite3" ?
(
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("syncer:File"), i18next.t("provider:File - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.host} onChange={e => {
this.updateAdapterField("file", e.target.value);
}} />
</Col>
</Row>
) : (
<React.Fragment>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.host} onChange={e => {
this.updateAdapterField("host", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("provider:Port"), i18next.t("provider:Port - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.port} onChange={e => {
this.updateAdapterField("port", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:User"), i18next.t("general:User - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.user} onChange={e => {
this.updateAdapterField("user", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Password"), i18next.t("general:Password - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.password} onChange={e => {
this.updateAdapterField("password", e.target.value);
}} />
</Col>
</Row>
</React.Fragment>
)
}
</React.Fragment>
);
}
renderAdapter() {
return (
<Card size="small" title={
@@ -118,7 +186,7 @@ class AdapterEditPage extends React.Component {
{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.adapter.owner} onChange={(value => {
<Select virtual={false} style={{width: "100%"}} disabled={!Setting.isAdminUser(this.props.account) || Setting.builtInObject(this.state.adapter)} value={this.state.adapter.owner} onChange={(value => {
this.getModels(value);
this.updateAdapterField("owner", value);
})}>
@@ -133,7 +201,7 @@ class AdapterEditPage extends React.Component {
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.name} onChange={e => {
<Input disabled={Setting.builtInObject(this.state.adapter)} value={this.state.adapter.name} onChange={e => {
this.updateAdapterField("name", e.target.value);
}} />
</Col>
@@ -143,7 +211,7 @@ class AdapterEditPage extends React.Component {
{Setting.getLabel(i18next.t("provider:Type"), i18next.t("provider:Type - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.adapter.type} onChange={(value => {
<Select virtual={false} disabled={Setting.builtInObject(this.state.adapter)} style={{width: "100%"}} value={this.state.adapter.type} onChange={(value => {
this.updateAdapterField("type", value);
const adapter = this.state.adapter;
// adapter["tableColumns"] = Setting.getAdapterTableColumns(this.state.adapter);
@@ -158,52 +226,12 @@ class AdapterEditPage extends React.Component {
</Select>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.host} onChange={e => {
this.updateAdapterField("host", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("provider:Port"), i18next.t("provider:Port - Tooltip"))} :
</Col>
<Col span={22} >
<InputNumber value={this.state.adapter.port} onChange={value => {
this.updateAdapterField("port", value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:User"), i18next.t("general:User - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.user} onChange={e => {
this.updateAdapterField("user", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Password"), i18next.t("general:Password - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.password} onChange={e => {
this.updateAdapterField("password", e.target.value);
}} />
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("syncer:Database type"), i18next.t("syncer:Database type - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.adapter.databaseType} onChange={(value => {this.updateAdapterField("databaseType", value);})}>
<Select virtual={false} disabled={Setting.builtInObject(this.state.adapter)} style={{width: "100%"}} value={this.state.adapter.databaseType} onChange={(value => {this.updateAdapterField("databaseType", value);})}>
{
[
{id: "mysql", name: "MySQL"},
@@ -216,12 +244,13 @@ class AdapterEditPage extends React.Component {
</Select>
</Col>
</Row>
{this.state.adapter.type === "Database" ? this.renderDataSourceNameConfig() : null}
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("syncer:Database"), i18next.t("syncer:Database - Tooltip"))} :
</Col>
<Col span={22} >
<Input value={this.state.adapter.database} onChange={e => {
<Input disabled={Setting.builtInObject(this.state.adapter)} value={this.state.adapter.database} onChange={e => {
this.updateAdapterField("database", e.target.value);
}} />
</Col>
@@ -232,7 +261,7 @@ class AdapterEditPage extends React.Component {
</Col>
<Col span={22} >
<Input value={this.state.adapter.table}
disabled={this.state.adapter.type === "Keycloak"} onChange={e => {
disabled={Setting.builtInObject(this.state.adapter)} onChange={e => {
this.updateAdapterField("table", e.target.value);
}} />
</Col>

View File

@@ -32,7 +32,7 @@ class AdapterListPage extends BaseListPage {
createdTime: moment().format(),
type: "Database",
host: "localhost",
port: 3306,
port: "3306",
user: "root",
password: "123456",
databaseType: "mysql",
@@ -206,6 +206,7 @@ class AdapterListPage extends BaseListPage {
<div>
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/adapters/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
<PopconfirmModal
disabled={Setting.builtInObject(record)}
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
onConfirm={() => this.deleteAdapter(index)}
>

View File

@@ -15,10 +15,6 @@
import React, {Component} from "react";
import "./App.less";
import {Helmet} from "react-helmet";
import EnableMfaNotification from "./common/notifaction/EnableMfaNotification";
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";
@@ -33,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";
@@ -86,9 +87,12 @@ import OdicDiscoveryPage from "./auth/OidcDiscoveryPage";
import SamlCallback from "./auth/SamlCallback";
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 OrganizationSelect from "./common/select/OrganizationSelect";
import {clearWeb3AuthToken} from "./auth/Web3Auth";
import AccountAvatar from "./account/AccountAvatar";
const {Header, Footer, Content} = Layout;
@@ -162,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")) {
@@ -312,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 !== "") {
@@ -348,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>
);
@@ -478,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)) {
@@ -596,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} />)} />
@@ -628,7 +641,7 @@ class App extends Component {
<Route exact path="/subscriptions/:organizationName/:subscriptionName" render={(props) => this.renderLoginIfNotLoggedIn(<SubscriptionEditPage account={this.state.account} {...props} />)} />
<Route exact path="/products" render={(props) => this.renderLoginIfNotLoggedIn(<ProductListPage account={this.state.account} {...props} />)} />
<Route exact path="/products/:organizationName/:productName" render={(props) => this.renderLoginIfNotLoggedIn(<ProductEditPage account={this.state.account} {...props} />)} />
<Route exact path="/products/:productName/buy" render={(props) => this.renderLoginIfNotLoggedIn(<ProductBuyPage account={this.state.account} {...props} />)} />
<Route exact path="/products/:organizationName/:productName/buy" render={(props) => this.renderLoginIfNotLoggedIn(<ProductBuyPage account={this.state.account} {...props} />)} />
<Route exact path="/payments" render={(props) => this.renderLoginIfNotLoggedIn(<PaymentListPage account={this.state.account} {...props} />)} />
<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} />)} />

View File

@@ -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,
});
});
}

View File

@@ -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>

Some files were not shown because too many files have changed in this diff Show More