mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-14 16:13:24 +08:00
Compare commits
128 Commits
Author | SHA1 | Date | |
---|---|---|---|
05b2f00057 | |||
8073dfa88c | |||
1eeeb64a0c | |||
f5e0461cae | |||
a0c5eb241f | |||
4d8edcc446 | |||
2b23c04f49 | |||
e60ee52d91 | |||
c54b54ca19 | |||
f0e097e138 | |||
25ec1bdfa8 | |||
ea7718d7b7 | |||
463fa8b636 | |||
11895902f4 | |||
15269d3315 | |||
4468859795 | |||
914128a78a | |||
e5a189e0f4 | |||
a07216d0e1 | |||
fec54944dd | |||
a2db61cc1a | |||
134541acde | |||
59fca0342e | |||
abfc464155 | |||
a41f6880a2 | |||
d12117324c | |||
1a6c9fbf69 | |||
dd60d79af9 | |||
73d314c7fe | |||
27959e0f6f | |||
47f40c5b24 | |||
2ff9020884 | |||
abaf4ca8d9 | |||
8ff0cfd6ec | |||
7a2a40edcc | |||
b7a001ea39 | |||
891e8e21d8 | |||
80b0d26813 | |||
db4ac60bb6 | |||
33a922f026 | |||
9f65053d04 | |||
be969e5efa | |||
9156bd426b | |||
fe4a4328aa | |||
9899022bcd | |||
1a9d02be46 | |||
eafaa135b4 | |||
6746551447 | |||
3cb46c3628 | |||
558bcf95d6 | |||
bb937c30c1 | |||
8dfdf7f767 | |||
62b2082e82 | |||
a1806439f8 | |||
01e58158b7 | |||
15427ad9d6 | |||
d058f78dc6 | |||
fd9dbf8251 | |||
3220a04fa9 | |||
f06a4990bd | |||
9df7de5f27 | |||
56c808c091 | |||
9fd2421564 | |||
689d45c7fa | |||
c24343bd53 | |||
979f43638d | |||
685a4514cd | |||
a05ca3af24 | |||
c6f301ff9e | |||
d7b2bcf288 | |||
67ac3d6d21 | |||
912d5c6a7f | |||
32fbb5b534 | |||
21004f3009 | |||
463bacd53b | |||
78dc660041 | |||
2fb9674171 | |||
55c522d3b7 | |||
f879170663 | |||
12e5d9b583 | |||
eefa1e6df4 | |||
026fb207b3 | |||
ea10f8e615 | |||
74b058aa3f | |||
6c628d7893 | |||
a38896e4d8 | |||
5f054c4989 | |||
fb16d8cee6 | |||
5e4ba4f338 | |||
ca47af2ee1 | |||
59da104463 | |||
c5bb916651 | |||
e98264f957 | |||
6a952952a8 | |||
ba8a0f36be | |||
b5e9084e5d | |||
55d5ae10f2 | |||
6986dad295 | |||
949feb18af | |||
d1f88ca9b8 | |||
bfe8e5f3e7 | |||
702ee6acd0 | |||
0a9587901a | |||
577bd6ce58 | |||
3c4112dd44 | |||
b7a37126ad | |||
8669d5bb0d | |||
aee3ea4981 | |||
516f4b7569 | |||
7d7ca10481 | |||
a9d4978a0f | |||
09f40bb5ce | |||
a6f803aff1 | |||
fc9528be43 | |||
58e8f9f90b | |||
e850e33f37 | |||
d7110ff8bf | |||
f923a8f0d7 | |||
7bfb74ba18 | |||
38f031bc86 | |||
5c441d195c | |||
0639564d27 | |||
6c647818ca | |||
8bc73d17aa | |||
1f37c80177 | |||
7924fca403 | |||
bd06996bab | |||
19ab168b12 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -110,7 +110,7 @@ jobs:
|
||||
with:
|
||||
start: yarn start
|
||||
wait-on: 'http://localhost:7001'
|
||||
wait-on-timeout: 180
|
||||
wait-on-timeout: 210
|
||||
working-directory: ./web
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
|
10
README.md
10
README.md
@ -11,7 +11,7 @@
|
||||
<img alt="GitHub Workflow Status (branch)" src="https://github.com/casdoor/casdoor/workflows/Build/badge.svg?style=flat-square">
|
||||
</a>
|
||||
<a href="https://github.com/casdoor/casdoor/releases/latest">
|
||||
<img alt="GitHub Release" src="https://img.shields.io/github/v/release/casbin/casdoor.svg">
|
||||
<img alt="GitHub Release" src="https://img.shields.io/github/v/release/casdoor/casdoor.svg">
|
||||
</a>
|
||||
<a href="https://hub.docker.com/repository/docker/casbin/casdoor">
|
||||
<img alt="Docker Image Version (latest semver)" src="https://img.shields.io/badge/Docker%20Hub-latest-brightgreen">
|
||||
@ -23,16 +23,16 @@
|
||||
<img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/casdoor/casdoor?style=flat-square">
|
||||
</a>
|
||||
<a href="https://github.com/casdoor/casdoor/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/casbin/casdoor?style=flat-square" alt="license">
|
||||
<img src="https://img.shields.io/github/license/casdoor/casdoor?style=flat-square" alt="license">
|
||||
</a>
|
||||
<a href="https://github.com/casdoor/casdoor/issues">
|
||||
<img alt="GitHub issues" src="https://img.shields.io/github/issues/casbin/casdoor?style=flat-square">
|
||||
<img alt="GitHub issues" src="https://img.shields.io/github/issues/casdoor/casdoor?style=flat-square">
|
||||
</a>
|
||||
<a href="#">
|
||||
<img alt="GitHub stars" src="https://img.shields.io/github/stars/casbin/casdoor?style=flat-square">
|
||||
<img alt="GitHub stars" src="https://img.shields.io/github/stars/casdoor/casdoor?style=flat-square">
|
||||
</a>
|
||||
<a href="https://github.com/casdoor/casdoor/network">
|
||||
<img alt="GitHub forks" src="https://img.shields.io/github/forks/casbin/casdoor?style=flat-square">
|
||||
<img alt="GitHub forks" src="https://img.shields.io/github/forks/casdoor/casdoor?style=flat-square">
|
||||
</a>
|
||||
<a href="https://crowdin.com/project/casdoor-site">
|
||||
<img alt="Crowdin" src="https://badges.crowdin.net/casdoor-site/localized.svg">
|
||||
|
141
ai/ai.go
141
ai/ai.go
@ -1,141 +0,0 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ai
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sashabaranov/go-openai"
|
||||
)
|
||||
|
||||
func queryAnswer(authToken string, question string, timeout int) (string, error) {
|
||||
// fmt.Printf("Question: %s\n", question)
|
||||
|
||||
client := getProxyClientFromToken(authToken)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(2+timeout*2)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
resp, err := client.CreateChatCompletion(
|
||||
ctx,
|
||||
openai.ChatCompletionRequest{
|
||||
Model: openai.GPT3Dot5Turbo,
|
||||
Messages: []openai.ChatCompletionMessage{
|
||||
{
|
||||
Role: openai.ChatMessageRoleUser,
|
||||
Content: question,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
res := resp.Choices[0].Message.Content
|
||||
res = strings.Trim(res, "\n")
|
||||
// fmt.Printf("Answer: %s\n\n", res)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func QueryAnswerSafe(authToken string, question string) string {
|
||||
var res string
|
||||
var err error
|
||||
for i := 0; i < 10; i++ {
|
||||
res, err = queryAnswer(authToken, question, i)
|
||||
if err != nil {
|
||||
if i > 0 {
|
||||
fmt.Printf("\tFailed (%d): %s\n", i+1, err.Error())
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func QueryAnswerStream(authToken string, question string, writer io.Writer, builder *strings.Builder) error {
|
||||
client := getProxyClientFromToken(authToken)
|
||||
|
||||
ctx := context.Background()
|
||||
flusher, ok := writer.(http.Flusher)
|
||||
if !ok {
|
||||
return fmt.Errorf("writer does not implement http.Flusher")
|
||||
}
|
||||
// https://platform.openai.com/tokenizer
|
||||
// https://github.com/pkoukk/tiktoken-go#available-encodings
|
||||
promptTokens, err := getTokenSize(openai.GPT3TextDavinci003, question)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// https://platform.openai.com/docs/models/gpt-3-5
|
||||
maxTokens := 4097 - promptTokens
|
||||
|
||||
respStream, err := client.CreateCompletionStream(
|
||||
ctx,
|
||||
openai.CompletionRequest{
|
||||
Model: openai.GPT3TextDavinci003,
|
||||
Prompt: question,
|
||||
MaxTokens: maxTokens,
|
||||
Stream: true,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer respStream.Close()
|
||||
|
||||
isLeadingReturn := true
|
||||
for {
|
||||
completion, streamErr := respStream.Recv()
|
||||
if streamErr != nil {
|
||||
if streamErr == io.EOF {
|
||||
break
|
||||
}
|
||||
return streamErr
|
||||
}
|
||||
|
||||
data := completion.Choices[0].Text
|
||||
if isLeadingReturn && len(data) != 0 {
|
||||
if strings.Count(data, "\n") == len(data) {
|
||||
continue
|
||||
} else {
|
||||
isLeadingReturn = false
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("%s", data)
|
||||
|
||||
// Write the streamed data as Server-Sent Events
|
||||
if _, err = fmt.Fprintf(writer, "event: message\ndata: %s\n\n", data); err != nil {
|
||||
return err
|
||||
}
|
||||
flusher.Flush()
|
||||
// Append the response to the strings.Builder
|
||||
builder.WriteString(data)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -18,60 +18,21 @@ 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() {
|
||||
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)
|
||||
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)
|
||||
func InitApi() {
|
||||
e, err := object.GetInitializedEnforcer(util.GetId("built-in", "api-enforcer-built-in"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Enforcer = e.Enforcer
|
||||
Enforcer.ClearPolicy()
|
||||
|
||||
// if len(Enforcer.GetPolicy()) == 0 {
|
||||
@ -126,6 +87,7 @@ p, *, *, GET, /api/get-prometheus-info, *, *
|
||||
p, *, *, *, /api/metrics, *, *
|
||||
p, *, *, GET, /api/get-pricing, *, *
|
||||
p, *, *, GET, /api/get-plan, *, *
|
||||
p, *, *, GET, /api/get-subscription, *, *
|
||||
p, *, *, GET, /api/get-organization-names, *, *
|
||||
`
|
||||
|
||||
|
28
conf/conf.go
28
conf/conf.go
@ -15,7 +15,7 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@ -24,15 +24,6 @@ import (
|
||||
"github.com/beego/beego"
|
||||
)
|
||||
|
||||
type Quota struct {
|
||||
Organization int `json:"organization"`
|
||||
User int `json:"user"`
|
||||
Application int `json:"application"`
|
||||
Provider int `json:"provider"`
|
||||
}
|
||||
|
||||
var quota = &Quota{-1, -1, -1, -1}
|
||||
|
||||
func init() {
|
||||
// this array contains the beego configuration items that may be modified via env
|
||||
presetConfigItems := []string{"httpport", "appname"}
|
||||
@ -44,17 +35,6 @@ func init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
initQuota()
|
||||
}
|
||||
|
||||
func initQuota() {
|
||||
res := beego.AppConfig.String("quota")
|
||||
if res != "" {
|
||||
err := json.Unmarshal([]byte(res), quota)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetConfigString(key string) string {
|
||||
@ -67,7 +47,7 @@ func GetConfigString(key string) string {
|
||||
if key == "staticBaseUrl" {
|
||||
res = "https://cdn.casbin.org"
|
||||
} else if key == "logConfig" {
|
||||
res = "{\"filename\": \"logs/casdoor.log\", \"maxdays\":99999, \"perm\":\"0770\"}"
|
||||
res = fmt.Sprintf("{\"filename\": \"logs/%s.log\", \"maxdays\":99999, \"perm\":\"0770\"}", beego.AppConfig.String("appname"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,10 +109,6 @@ func GetConfigBatchSize() int {
|
||||
return res
|
||||
}
|
||||
|
||||
func GetConfigQuota() *Quota {
|
||||
return quota
|
||||
}
|
||||
|
||||
func GetConfigRealDataSourceName(driverName string) string {
|
||||
var dataSourceName string
|
||||
if driverName != "mysql" {
|
||||
|
48
conf/conf_quota.go
Normal file
48
conf/conf_quota.go
Normal file
@ -0,0 +1,48 @@
|
||||
// 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 conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego"
|
||||
)
|
||||
|
||||
type Quota struct {
|
||||
Organization int `json:"organization"`
|
||||
User int `json:"user"`
|
||||
Application int `json:"application"`
|
||||
Provider int `json:"provider"`
|
||||
}
|
||||
|
||||
var quota = &Quota{-1, -1, -1, -1}
|
||||
|
||||
func init() {
|
||||
initQuota()
|
||||
}
|
||||
|
||||
func initQuota() {
|
||||
res := beego.AppConfig.String("quota")
|
||||
if res != "" {
|
||||
err := json.Unmarshal([]byte(res), quota)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetConfigQuota() *Quota {
|
||||
return quota
|
||||
}
|
@ -153,12 +153,22 @@ func (c *ApiController) Signup() {
|
||||
return
|
||||
}
|
||||
|
||||
userType := "normal-user"
|
||||
if authForm.Plan != "" && authForm.Pricing != "" {
|
||||
err = object.CheckPricingAndPlan(authForm.Organization, authForm.Pricing, authForm.Plan)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
userType = "paid-user"
|
||||
}
|
||||
|
||||
user := &object.User{
|
||||
Owner: authForm.Organization,
|
||||
Name: username,
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
Id: id,
|
||||
Type: "normal-user",
|
||||
Type: userType,
|
||||
Password: authForm.Password,
|
||||
DisplayName: authForm.Name,
|
||||
Avatar: organization.DefaultAvatar,
|
||||
@ -171,7 +181,6 @@ func (c *ApiController) Signup() {
|
||||
Region: authForm.Region,
|
||||
Score: initScore,
|
||||
IsAdmin: false,
|
||||
IsGlobalAdmin: false,
|
||||
IsForbidden: false,
|
||||
IsDeleted: false,
|
||||
SignupApplication: application.Name,
|
||||
@ -211,7 +220,7 @@ func (c *ApiController) Signup() {
|
||||
return
|
||||
}
|
||||
|
||||
if application.HasPromptPage() {
|
||||
if application.HasPromptPage() && user.Type == "normal-user" {
|
||||
// The prompt page needs the user to be signed in
|
||||
c.SetSessionUsername(user.GetId())
|
||||
}
|
||||
@ -228,15 +237,6 @@ func (c *ApiController) Signup() {
|
||||
return
|
||||
}
|
||||
|
||||
isSignupFromPricing := authForm.Plan != "" && authForm.Pricing != ""
|
||||
if isSignupFromPricing {
|
||||
_, err = object.Subscribe(organization.Name, user.Name, authForm.Plan, authForm.Pricing)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
record := object.NewRecord(c.Ctx)
|
||||
record.Organization = application.Organization
|
||||
record.User = user.Name
|
||||
@ -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
|
||||
|
145
controllers/adapter.go
Normal file
145
controllers/adapter.go
Normal file
@ -0,0 +1,145 @@
|
||||
// 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/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// 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) GetAdapters() {
|
||||
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")
|
||||
|
||||
if limit == "" || page == "" {
|
||||
adapters, err := object.GetAdapters(owner)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(adapters)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
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.GetPaginationAdapters(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(adapters, paginator.Nums())
|
||||
}
|
||||
}
|
||||
|
||||
// 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) GetAdapter() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
adapter, err := object.GetAdapter(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(adapter)
|
||||
}
|
||||
|
||||
// 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) UpdateAdapter() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
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.UpdateAdapter(id, &adapter))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// 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) 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.AddAdapter(&adapter))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// 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) 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.DeleteAdapter(&adapter))
|
||||
c.ServeJSON()
|
||||
}
|
@ -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)
|
||||
|
||||
|
@ -70,7 +70,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
}
|
||||
|
||||
// check user's tag
|
||||
if !user.IsGlobalAdmin && !user.IsAdmin && len(application.Tags) > 0 {
|
||||
if !user.IsGlobalAdmin() && !user.IsAdmin && len(application.Tags) > 0 {
|
||||
// only users with the tag that is listed in the application tags can login
|
||||
if !util.InSlice(application.Tags, user.Tag) {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:User's tag: %s is not listed in the application's tags"), user.Tag))
|
||||
@ -78,6 +78,46 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
}
|
||||
}
|
||||
|
||||
// check whether paid-user have active subscription
|
||||
if user.Type == "paid-user" {
|
||||
subscriptions, err := object.GetSubscriptionsByUser(user.Owner, user.Name)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
existActiveSubscription := false
|
||||
for _, subscription := range subscriptions {
|
||||
if subscription.State == object.SubStateActive {
|
||||
existActiveSubscription = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !existActiveSubscription {
|
||||
// check pending subscription
|
||||
for _, sub := range subscriptions {
|
||||
if sub.State == object.SubStatePending {
|
||||
c.ResponseOk("BuyPlanResult", sub)
|
||||
return
|
||||
}
|
||||
}
|
||||
// paid-user does not have active or pending subscription, find the default pricing of application
|
||||
pricing, err := object.GetApplicationDefaultPricing(application.Organization, application.Name)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if pricing == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:paid-user %s does not have active or pending subscription and the application: %s does not have default pricing"), user.Name, application.Name))
|
||||
return
|
||||
} else {
|
||||
// let the paid-user select plan
|
||||
c.ResponseOk("SelectPlan", pricing)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if form.Type == ResponseTypeLogin {
|
||||
c.SetSessionUsername(userId)
|
||||
util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
|
||||
@ -187,11 +227,34 @@ func (c *ApiController) GetApplicationLogin() {
|
||||
redirectUri := c.Input().Get("redirectUri")
|
||||
scope := c.Input().Get("scope")
|
||||
state := c.Input().Get("state")
|
||||
id := c.Input().Get("id")
|
||||
loginType := c.Input().Get("type")
|
||||
|
||||
msg, application, err := object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
var application *object.Application
|
||||
var msg string
|
||||
var err error
|
||||
if loginType == "code" {
|
||||
msg, application, err = object.CheckOAuthLogin(clientId, responseType, redirectUri, scope, state, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else if loginType == "cas" {
|
||||
application, err = object.GetApplication(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), id))
|
||||
return
|
||||
}
|
||||
|
||||
err = object.CheckCasLogin(application, c.GetAcceptLanguage(), redirectUri)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
application = object.GetMaskedApplication(application, "")
|
||||
@ -422,7 +485,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)
|
||||
@ -465,7 +528,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())
|
||||
@ -486,7 +549,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 != "" {
|
||||
@ -566,7 +629,6 @@ func (c *ApiController) Login() {
|
||||
Region: userInfo.CountryCode,
|
||||
Score: initScore,
|
||||
IsAdmin: false,
|
||||
IsGlobalAdmin: false,
|
||||
IsForbidden: false,
|
||||
IsDeleted: false,
|
||||
SignupApplication: application.Name,
|
||||
|
@ -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/") {
|
||||
@ -67,7 +79,7 @@ func (c *ApiController) isGlobalAdmin() (bool, *object.User) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return user.Owner == "built-in" || user.IsGlobalAdmin, user
|
||||
return user.IsGlobalAdmin(), user
|
||||
}
|
||||
|
||||
func (c *ApiController) getCurrentUser() *object.User {
|
||||
|
@ -1,235 +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 controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||
)
|
||||
|
||||
// GetCasbinAdapters
|
||||
// @Title GetCasbinAdapters
|
||||
// @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() {
|
||||
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")
|
||||
|
||||
if limit == "" || page == "" {
|
||||
adapters, err := object.GetCasbinAdapters(owner)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(adapters)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetCasbinAdapterCount(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)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(adapters, paginator.Nums())
|
||||
}
|
||||
}
|
||||
|
||||
// GetCasbinAdapter
|
||||
// @Title GetCasbinAdapter
|
||||
// @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() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
adapter, err := object.GetCasbinAdapter(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(adapter)
|
||||
}
|
||||
|
||||
// UpdateCasbinAdapter
|
||||
// @Title UpdateCasbinAdapter
|
||||
// @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() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var casbinAdapter object.CasbinAdapter
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &casbinAdapter)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateCasbinAdapter(id, &casbinAdapter))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddCasbinAdapter
|
||||
// @Title AddCasbinAdapter
|
||||
// @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)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddCasbinAdapter(&casbinAdapter))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteCasbinAdapter
|
||||
// @Title DeleteCasbinAdapter
|
||||
// @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)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteCasbinAdapter(&casbinAdapter))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) SyncPolicies() {
|
||||
id := c.Input().Get("id")
|
||||
adapter, err := object.GetCasbinAdapter(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
policies, err := object.SyncPolicies(adapter)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(policies)
|
||||
}
|
||||
|
||||
func (c *ApiController) UpdatePolicy() {
|
||||
id := c.Input().Get("id")
|
||||
adapter, err := object.GetCasbinAdapter(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var policies []xormadapter.CasbinRule
|
||||
err = json.Unmarshal(c.Ctx.Input.RequestBody, &policies)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.UpdatePolicy(util.CasbinToSlice(policies[0]), util.CasbinToSlice(policies[1]), adapter)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) AddPolicy() {
|
||||
id := c.Input().Get("id")
|
||||
adapter, err := object.GetCasbinAdapter(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var policy xormadapter.CasbinRule
|
||||
err = json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.AddPolicy(util.CasbinToSlice(policy), adapter)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) RemovePolicy() {
|
||||
id := c.Input().Get("id")
|
||||
adapter, err := object.GetCasbinAdapter(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var policy xormadapter.CasbinRule
|
||||
err = json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.RemovePolicy(util.CasbinToSlice(policy), adapter)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
262
controllers/casbin_api.go
Normal file
262
controllers/casbin_api.go
Normal file
@ -0,0 +1,262 @@
|
||||
// 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")
|
||||
enforcerId := c.Input().Get("enforcerId")
|
||||
|
||||
var request object.CasbinRequest
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &request)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if enforcerId != "" {
|
||||
enforcer, err := object.GetInitializedEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := enforcer.Enforce(request...)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
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")
|
||||
enforcerId := c.Input().Get("enforcerId")
|
||||
|
||||
var requests []object.CasbinRequest
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &requests)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if enforcerId != "" {
|
||||
enforcer, err := object.GetInitializedEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res, err := enforcer.BatchEnforce(requests)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
return
|
||||
}
|
||||
|
||||
if permissionId != "" {
|
||||
permission, err := object.GetPermission(permissionId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res := [][]bool{}
|
||||
|
||||
if permission == nil {
|
||||
l := len(requests)
|
||||
resRequest := make([]bool, l)
|
||||
for i := 0; i < l; i++ {
|
||||
resRequest[i] = false
|
||||
}
|
||||
|
||||
res = append(res, resRequest)
|
||||
} else {
|
||||
enforceResult, err := object.BatchEnforce(permission, &requests)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
return
|
||||
}
|
||||
|
||||
permissions := []*object.Permission{}
|
||||
if modelId != "" {
|
||||
owner, modelName := util.GetOwnerAndNameFromId(modelId)
|
||||
permissions, err = object.GetPermissionsByModel(owner, modelName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
res := [][]bool{}
|
||||
|
||||
listPermissionIdMap := object.GroupPermissionsByModelAdapter(permissions)
|
||||
for _, permissionIds := range listPermissionIdMap {
|
||||
firstPermission, err := object.GetPermission(permissionIds[0])
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
enforceResult, err := object.BatchEnforce(firstPermission, &requests, permissionIds...)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
res = append(res, enforceResult)
|
||||
}
|
||||
|
||||
c.ResponseOk(res)
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllObjects() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllObjects(userId))
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllActions() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllActions(userId))
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllRoles() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllRoles(userId))
|
||||
}
|
@ -45,8 +45,7 @@ func (c *ApiController) GetCerts() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedCerts
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedCerts)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetCertCount(owner, field, value)
|
||||
@ -87,8 +86,7 @@ func (c *ApiController) GetGlobleCerts() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedCerts
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedCerts)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetGlobalCertsCount(field, value)
|
||||
@ -123,8 +121,7 @@ func (c *ApiController) GetCert() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedCert(cert)
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(object.GetMaskedCert(cert))
|
||||
}
|
||||
|
||||
// UpdateCert
|
||||
|
@ -1,147 +0,0 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// GetChats
|
||||
// @Title GetChats
|
||||
// @Tag Chat API
|
||||
// @Description get chats
|
||||
// @Param owner query string true "The owner of chats"
|
||||
// @Success 200 {array} object.Chat The Response object
|
||||
// @router /get-chats [get]
|
||||
func (c *ApiController) GetChats() {
|
||||
owner := "admin"
|
||||
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")
|
||||
|
||||
if limit == "" || page == "" {
|
||||
maskedChats, err := object.GetMaskedChats(object.GetChats(owner))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedChats
|
||||
c.ServeJSON()
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetChatCount(owner, field, value)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, count)
|
||||
chats, err := object.GetMaskedChats(object.GetPaginationChats(owner, paginator.Offset(), limit, field, value, sortField, sortOrder))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(chats, paginator.Nums())
|
||||
}
|
||||
}
|
||||
|
||||
// GetChat
|
||||
// @Title GetChat
|
||||
// @Tag Chat API
|
||||
// @Description get chat
|
||||
// @Param id query string true "The id ( owner/name ) of the chat"
|
||||
// @Success 200 {object} object.Chat The Response object
|
||||
// @router /get-chat [get]
|
||||
func (c *ApiController) GetChat() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
maskedChat, err := object.GetMaskedChat(object.GetChat(id))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedChat
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateChat
|
||||
// @Title UpdateChat
|
||||
// @Tag Chat API
|
||||
// @Description update chat
|
||||
// @Param id query string true "The id ( owner/name ) of the chat"
|
||||
// @Param body body object.Chat true "The details of the chat"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /update-chat [post]
|
||||
func (c *ApiController) UpdateChat() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var chat object.Chat
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &chat)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateChat(id, &chat))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddChat
|
||||
// @Title AddChat
|
||||
// @Tag Chat API
|
||||
// @Description add chat
|
||||
// @Param body body object.Chat true "The details of the chat"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /add-chat [post]
|
||||
func (c *ApiController) AddChat() {
|
||||
var chat object.Chat
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &chat)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddChat(&chat))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteChat
|
||||
// @Title DeleteChat
|
||||
// @Tag Chat API
|
||||
// @Description delete chat
|
||||
// @Param body body object.Chat true "The details of the chat"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /delete-chat [post]
|
||||
func (c *ApiController) DeleteChat() {
|
||||
var chat object.Chat
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &chat)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteChat(&chat))
|
||||
c.ServeJSON()
|
||||
}
|
@ -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,223 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||
)
|
||||
|
||||
// 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")
|
||||
loadModelCfg := c.Input().Get("loadModelCfg")
|
||||
|
||||
enforcer, err := object.GetEnforcer(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if permissionId != "" {
|
||||
permission, err := object.GetPermission(permissionId)
|
||||
if loadModelCfg == "true" {
|
||||
err := enforcer.LoadModelCfg()
|
||||
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)
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateEnforcer(id, &enforcer))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// 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.Data["json"] = wrapActionResponse(object.AddEnforcer(&enforcer))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// 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.Data["json"] = wrapActionResponse(object.DeleteEnforcer(&enforcer))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) GetPolicies() {
|
||||
id := c.Input().Get("id")
|
||||
adapterId := c.Input().Get("adapterId")
|
||||
|
||||
if adapterId != "" {
|
||||
adapter, err := object.GetAdapter(adapterId)
|
||||
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)
|
||||
err = adapter.InitAdapter()
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
c.ResponseOk()
|
||||
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"))
|
||||
policies, err := object.GetPolicies(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllObjects(userId))
|
||||
c.ResponseOk(policies)
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllActions() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
func (c *ApiController) UpdatePolicy() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var policies []xormadapter.CasbinRule
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &policies)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllActions(userId))
|
||||
affected, err := object.UpdatePolicy(id, util.CasbinToSlice(policies[0]), util.CasbinToSlice(policies[1]))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllRoles() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
func (c *ApiController) AddPolicy() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var policy xormadapter.CasbinRule
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(object.GetAllRoles(userId))
|
||||
affected, err := object.AddPolicy(id, util.CasbinToSlice(policy))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) RemovePolicy() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var policy xormadapter.CasbinRule
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &policy)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.RemovePolicy(id, util.CasbinToSlice(policy))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
35
controllers/get-dashboard.go
Normal file
35
controllers/get-dashboard.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllers
|
||||
|
||||
import "github.com/casdoor/casdoor/object"
|
||||
|
||||
// GetDashboard
|
||||
// @Title GetDashboard
|
||||
// @Tag GetDashboard API
|
||||
// @Description get information of dashboard
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /get-dashboard [get]
|
||||
func (c *ApiController) GetDashboard() {
|
||||
owner := c.Input().Get("owner")
|
||||
|
||||
data, err := object.GetDashboard(owner)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(data)
|
||||
}
|
@ -82,9 +82,9 @@ func (c *ApiController) GetGroup() {
|
||||
group, err := object.GetGroup(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
} else {
|
||||
c.ResponseOk(group)
|
||||
return
|
||||
}
|
||||
c.ResponseOk(group)
|
||||
}
|
||||
|
||||
// UpdateGroup
|
||||
|
@ -38,8 +38,11 @@ type LdapSyncResp struct {
|
||||
}
|
||||
|
||||
// GetLdapUsers
|
||||
// @Tag Account API
|
||||
// @Title GetLdapser
|
||||
// @Tag Account API
|
||||
// @Description get ldap users
|
||||
// Param id string true "id"
|
||||
// @Success 200 {object} LdapResp The Response object
|
||||
// @router /get-ldap-users [get]
|
||||
func (c *ApiController) GetLdapUsers() {
|
||||
id := c.Input().Get("id")
|
||||
@ -94,8 +97,11 @@ 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")
|
||||
@ -104,8 +110,11 @@ func (c *ApiController) GetLdaps() {
|
||||
}
|
||||
|
||||
// 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.GetMaskedLdap(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,8 +245,11 @@ 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() {
|
||||
id := c.Input().Get("id")
|
||||
|
@ -45,13 +45,13 @@ func (c *ApiController) Unlink() {
|
||||
// the user will be unlinked from the provider
|
||||
unlinkedUser := form.User
|
||||
|
||||
if user.Id != unlinkedUser.Id && !user.IsGlobalAdmin {
|
||||
if user.Id != unlinkedUser.Id && !user.IsGlobalAdmin() {
|
||||
// if the user is not the same as the one we are unlinking, we need to make sure the user is the global admin.
|
||||
c.ResponseError(c.T("link:You are not the global admin, you can't unlink other users"))
|
||||
return
|
||||
}
|
||||
|
||||
if user.Id == unlinkedUser.Id && !user.IsGlobalAdmin {
|
||||
if user.Id == unlinkedUser.Id && !user.IsGlobalAdmin() {
|
||||
// if the user is unlinking themselves, should check the provider can be unlinked, if not, we should return an error.
|
||||
application, err := object.GetApplicationByUser(user)
|
||||
if err != nil {
|
||||
|
@ -1,315 +0,0 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/ai"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// GetMessages
|
||||
// @Title GetMessages
|
||||
// @Tag Message API
|
||||
// @Description get messages
|
||||
// @Param owner query string true "The owner of messages"
|
||||
// @Success 200 {array} object.Message The Response object
|
||||
// @router /get-messages [get]
|
||||
func (c *ApiController) GetMessages() {
|
||||
owner := c.Input().Get("owner")
|
||||
organization := c.Input().Get("organization")
|
||||
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")
|
||||
chat := c.Input().Get("chat")
|
||||
|
||||
if limit == "" || page == "" {
|
||||
var messages []*object.Message
|
||||
var err error
|
||||
if chat == "" {
|
||||
messages, err = object.GetMessages(owner)
|
||||
} else {
|
||||
messages, err = object.GetChatMessages(chat)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedMessages(messages)
|
||||
c.ServeJSON()
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetMessageCount(owner, organization, field, value)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, count)
|
||||
paginationMessages, err := object.GetPaginationMessages(owner, organization, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
messages := object.GetMaskedMessages(paginationMessages)
|
||||
c.ResponseOk(messages, paginator.Nums())
|
||||
}
|
||||
}
|
||||
|
||||
// GetMessage
|
||||
// @Title GetMessage
|
||||
// @Tag Message API
|
||||
// @Description get message
|
||||
// @Param id query string true "The id ( owner/name ) of the message"
|
||||
// @Success 200 {object} object.Message The Response object
|
||||
// @router /get-message [get]
|
||||
func (c *ApiController) GetMessage() {
|
||||
id := c.Input().Get("id")
|
||||
message, err := object.GetMessage(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedMessage(message)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) ResponseErrorStream(errorText string) {
|
||||
event := fmt.Sprintf("event: myerror\ndata: %s\n\n", errorText)
|
||||
_, err := c.Ctx.ResponseWriter.Write([]byte(event))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetMessageAnswer
|
||||
// @Title GetMessageAnswer
|
||||
// @Tag Message API
|
||||
// @Description get message answer
|
||||
// @Param id query string true "The id ( owner/name ) of the message"
|
||||
// @Success 200 {object} object.Message The Response object
|
||||
// @router /get-message-answer [get]
|
||||
func (c *ApiController) GetMessageAnswer() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
|
||||
c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
|
||||
c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
|
||||
|
||||
message, err := object.GetMessage(id)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if message == nil {
|
||||
c.ResponseErrorStream(fmt.Sprintf(c.T("chat:The message: %s is not found"), id))
|
||||
return
|
||||
}
|
||||
|
||||
if message.Author != "AI" || message.ReplyTo == "" || message.Text != "" {
|
||||
c.ResponseErrorStream(c.T("chat:The message is invalid"))
|
||||
return
|
||||
}
|
||||
|
||||
chatId := util.GetId("admin", message.Chat)
|
||||
chat, err := object.GetChat(chatId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if chat == nil || chat.Organization != message.Organization {
|
||||
c.ResponseErrorStream(fmt.Sprintf(c.T("chat:The chat: %s is not found"), chatId))
|
||||
return
|
||||
}
|
||||
|
||||
if chat.Type != "AI" {
|
||||
c.ResponseErrorStream(c.T("chat:The chat type must be \"AI\""))
|
||||
return
|
||||
}
|
||||
|
||||
questionMessage, err := object.GetMessage(message.ReplyTo)
|
||||
if questionMessage == nil {
|
||||
c.ResponseErrorStream(fmt.Sprintf(c.T("chat:The message: %s is not found"), id))
|
||||
return
|
||||
}
|
||||
|
||||
providerId := util.GetId(chat.Owner, chat.User2)
|
||||
provider, err := object.GetProvider(providerId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if provider == nil {
|
||||
c.ResponseErrorStream(fmt.Sprintf(c.T("chat:The provider: %s is not found"), providerId))
|
||||
return
|
||||
}
|
||||
|
||||
if provider.Category != "AI" || provider.ClientSecret == "" {
|
||||
c.ResponseErrorStream(fmt.Sprintf(c.T("chat:The provider: %s is invalid"), providerId))
|
||||
return
|
||||
}
|
||||
|
||||
c.Ctx.ResponseWriter.Header().Set("Content-Type", "text/event-stream")
|
||||
c.Ctx.ResponseWriter.Header().Set("Cache-Control", "no-cache")
|
||||
c.Ctx.ResponseWriter.Header().Set("Connection", "keep-alive")
|
||||
|
||||
authToken := provider.ClientSecret
|
||||
question := questionMessage.Text
|
||||
var stringBuilder strings.Builder
|
||||
|
||||
fmt.Printf("Question: [%s]\n", questionMessage.Text)
|
||||
fmt.Printf("Answer: [")
|
||||
|
||||
err = ai.QueryAnswerStream(authToken, question, c.Ctx.ResponseWriter, &stringBuilder)
|
||||
if err != nil {
|
||||
c.ResponseErrorStream(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("]\n")
|
||||
|
||||
event := fmt.Sprintf("event: end\ndata: %s\n\n", "end")
|
||||
_, err = c.Ctx.ResponseWriter.Write([]byte(event))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
answer := stringBuilder.String()
|
||||
|
||||
message.Text = answer
|
||||
_, err = object.UpdateMessage(message.GetId(), message)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateMessage
|
||||
// @Title UpdateMessage
|
||||
// @Tag Message API
|
||||
// @Description update message
|
||||
// @Param id query string true "The id ( owner/name ) of the message"
|
||||
// @Param body body object.Message true "The details of the message"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /update-message [post]
|
||||
func (c *ApiController) UpdateMessage() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
var message object.Message
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &message)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateMessage(id, &message))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddMessage
|
||||
// @Title AddMessage
|
||||
// @Tag Message API
|
||||
// @Description add message
|
||||
// @Param body body object.Message true "The details of the message"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /add-message [post]
|
||||
func (c *ApiController) AddMessage() {
|
||||
var message object.Message
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &message)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var chat *object.Chat
|
||||
if message.Chat != "" {
|
||||
chatId := util.GetId("admin", message.Chat)
|
||||
chat, err = object.GetChat(chatId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if chat == nil || chat.Organization != message.Organization {
|
||||
c.ResponseError(fmt.Sprintf(c.T("chat:The chat: %s is not found"), chatId))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
affected, err := object.AddMessage(&message)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if affected {
|
||||
if chat != nil && chat.Type == "AI" {
|
||||
answerMessage := &object.Message{
|
||||
Owner: message.Owner,
|
||||
Name: fmt.Sprintf("message_%s", util.GetRandomName()),
|
||||
CreatedTime: util.GetCurrentTimeEx(message.CreatedTime),
|
||||
Organization: message.Organization,
|
||||
Chat: message.Chat,
|
||||
ReplyTo: message.GetId(),
|
||||
Author: "AI",
|
||||
Text: "",
|
||||
}
|
||||
_, err = object.AddMessage(answerMessage)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteMessage
|
||||
// @Title DeleteMessage
|
||||
// @Tag Message API
|
||||
// @Description delete message
|
||||
// @Param body body object.Message true "The details of the message"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /delete-message [post]
|
||||
func (c *ApiController) DeleteMessage() {
|
||||
var message object.Message
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &message)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteMessage(&message))
|
||||
c.ServeJSON()
|
||||
}
|
@ -45,8 +45,7 @@ func (c *ApiController) GetModels() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = models
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(models)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetModelCount(owner, field, value)
|
||||
@ -82,8 +81,7 @@ func (c *ApiController) GetModel() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = model
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(model)
|
||||
}
|
||||
|
||||
// UpdateModel
|
||||
|
@ -55,8 +55,7 @@ func (c *ApiController) GetOrganizations() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedOrganizations
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedOrganizations)
|
||||
} else {
|
||||
if !isGlobalAdmin {
|
||||
maskedOrganizations, err := object.GetMaskedOrganizations(object.GetOrganizations(owner, c.getCurrentUser().Owner))
|
||||
|
@ -31,7 +31,6 @@ import (
|
||||
// @router /get-payments [get]
|
||||
func (c *ApiController) GetPayments() {
|
||||
owner := c.Input().Get("owner")
|
||||
organization := c.Input().Get("organization")
|
||||
limit := c.Input().Get("pageSize")
|
||||
page := c.Input().Get("p")
|
||||
field := c.Input().Get("field")
|
||||
@ -46,18 +45,17 @@ 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)
|
||||
count, err := object.GetPaymentCount(owner, field, value)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, count)
|
||||
payments, err := object.GetPaginationPayments(owner, organization, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||
payments, err := object.GetPaginationPayments(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
@ -78,10 +76,9 @@ func (c *ApiController) GetPayments() {
|
||||
// @router /get-user-payments [get]
|
||||
func (c *ApiController) GetUserPayments() {
|
||||
owner := c.Input().Get("owner")
|
||||
organization := c.Input().Get("organization")
|
||||
user := c.Input().Get("user")
|
||||
|
||||
payments, err := object.GetUserPayments(owner, organization, user)
|
||||
payments, err := object.GetUserPayments(owner, user)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
@ -106,8 +103,7 @@ func (c *ApiController) GetPayment() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = payment
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(payment)
|
||||
}
|
||||
|
||||
// UpdatePayment
|
||||
@ -179,24 +175,18 @@ func (c *ApiController) DeletePayment() {
|
||||
// @router /notify-payment [post]
|
||||
func (c *ApiController) NotifyPayment() {
|
||||
owner := c.Ctx.Input.Param(":owner")
|
||||
providerName := c.Ctx.Input.Param(":provider")
|
||||
productName := c.Ctx.Input.Param(":product")
|
||||
paymentName := c.Ctx.Input.Param(":payment")
|
||||
orderId := c.Ctx.Input.Param("order")
|
||||
|
||||
body := c.Ctx.Input.RequestBody
|
||||
|
||||
err, errorResponse := object.NotifyPayment(c.Ctx.Request, body, owner, providerName, productName, paymentName, orderId)
|
||||
|
||||
_, err2 := c.Ctx.ResponseWriter.Write([]byte(errorResponse))
|
||||
if err2 != nil {
|
||||
panic(err2)
|
||||
}
|
||||
|
||||
payment, err := object.NotifyPayment(c.Ctx.Request, body, owner, paymentName, orderId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(payment)
|
||||
}
|
||||
|
||||
// InvoicePayment
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@ -32,16 +33,15 @@ func (c *ApiController) UploadPermissions() {
|
||||
}
|
||||
|
||||
fileId := fmt.Sprintf("%s_%s_%s", owner, user, util.RemoveExt(header.Filename))
|
||||
|
||||
path := util.GetUploadXlsxPath(fileId)
|
||||
util.EnsureFileFolderExists(path)
|
||||
defer os.Remove(path)
|
||||
err = saveFile(path, &file)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.UploadPermissions(owner, fileId)
|
||||
affected, err := object.UploadPermissions(owner, path)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@ -45,8 +46,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)
|
||||
@ -83,7 +83,10 @@ func (c *ApiController) GetPlan() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if plan == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("plan:The plan: %s does not exist"), id))
|
||||
return
|
||||
}
|
||||
if includeOption {
|
||||
options, err := object.GetPermissionsByRole(plan.Role)
|
||||
if err != nil {
|
||||
@ -95,11 +98,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
|
||||
@ -119,7 +121,20 @@ func (c *ApiController) UpdatePlan() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if plan.Product != "" {
|
||||
planId := util.GetId(plan.Owner, plan.Product)
|
||||
product, err := object.GetProduct(planId)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
object.UpdateProductForPlan(&plan, product)
|
||||
_, err = object.UpdateProduct(planId, product)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(object.UpdatePlan(id, &plan))
|
||||
c.ServeJSON()
|
||||
}
|
||||
@ -138,7 +153,14 @@ func (c *ApiController) AddPlan() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// Create a related product for plan
|
||||
product := object.CreateProductForPlan(&plan)
|
||||
_, err = object.AddProduct(product)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
plan.Product = product.Name
|
||||
c.Data["json"] = wrapActionResponse(object.AddPlan(&plan))
|
||||
c.ServeJSON()
|
||||
}
|
||||
@ -157,7 +179,13 @@ func (c *ApiController) DeletePlan() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if plan.Product != "" {
|
||||
_, err = object.DeleteProduct(&object.Product{Owner: plan.Owner, Name: plan.Product})
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(object.DeletePlan(&plan))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@ -45,8 +46,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)
|
||||
@ -81,9 +81,11 @@ func (c *ApiController) GetPricing() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = pricing
|
||||
c.ServeJSON()
|
||||
if pricing == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("pricing:The pricing: %s does not exist"), id))
|
||||
return
|
||||
}
|
||||
c.ResponseOk(pricing)
|
||||
}
|
||||
|
||||
// UpdatePricing
|
||||
|
@ -46,8 +46,7 @@ func (c *ApiController) GetProducts() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = products
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(products)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetProductCount(owner, field, value)
|
||||
@ -89,8 +88,7 @@ func (c *ApiController) GetProduct() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = product
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(product)
|
||||
}
|
||||
|
||||
// UpdateProduct
|
||||
@ -163,10 +161,17 @@ func (c *ApiController) DeleteProduct() {
|
||||
// @router /buy-product [post]
|
||||
func (c *ApiController) BuyProduct() {
|
||||
id := c.Input().Get("id")
|
||||
providerName := c.Input().Get("providerName")
|
||||
host := c.Ctx.Request.Host
|
||||
|
||||
userId := c.GetSessionUsername()
|
||||
providerName := c.Input().Get("providerName")
|
||||
// buy `pricingName/planName` for `paidUserName`
|
||||
pricingName := c.Input().Get("pricingName")
|
||||
planName := c.Input().Get("planName")
|
||||
paidUserName := c.Input().Get("userName")
|
||||
owner, _ := util.GetOwnerAndNameFromId(id)
|
||||
userId := util.GetId(owner, paidUserName)
|
||||
if paidUserName == "" {
|
||||
userId = c.GetSessionUsername()
|
||||
}
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
@ -177,13 +182,12 @@ func (c *ApiController) BuyProduct() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), userId))
|
||||
return
|
||||
}
|
||||
|
||||
payUrl, orderId, err := object.BuyProduct(id, providerName, user, host)
|
||||
payUrl, orderId, err := object.BuyProduct(id, user, providerName, pricingName, planName, host)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
@ -1,123 +0,0 @@
|
||||
// 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 controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// GetRecords
|
||||
// @Title GetRecords
|
||||
// @Tag Record API
|
||||
// @Description get all records
|
||||
// @Param pageSize query string true "The size of each page"
|
||||
// @Param p query string true "The number of the page"
|
||||
// @Success 200 {object} object.Record The Response object
|
||||
// @router /get-records [get]
|
||||
func (c *ApiController) GetRecords() {
|
||||
organization, ok := c.RequireAdmin()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
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")
|
||||
organizationName := c.Input().Get("organizationName")
|
||||
|
||||
if limit == "" || page == "" {
|
||||
records, err := object.GetRecords()
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = records
|
||||
c.ServeJSON()
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
if c.IsGlobalAdmin() && organizationName != "" {
|
||||
organization = organizationName
|
||||
}
|
||||
filterRecord := &object.Record{Organization: organization}
|
||||
count, err := object.GetRecordCount(field, value, filterRecord)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, count)
|
||||
records, err := object.GetPaginationRecords(paginator.Offset(), limit, field, value, sortField, sortOrder, filterRecord)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(records, paginator.Nums())
|
||||
}
|
||||
}
|
||||
|
||||
// GetRecordsByFilter
|
||||
// @Tag Record API
|
||||
// @Title GetRecordsByFilter
|
||||
// @Description get records by filter
|
||||
// @Param filter body string true "filter Record message"
|
||||
// @Success 200 {object} object.Record The Response object
|
||||
// @router /get-records-filter [post]
|
||||
func (c *ApiController) GetRecordsByFilter() {
|
||||
body := string(c.Ctx.Input.RequestBody)
|
||||
|
||||
record := &object.Record{}
|
||||
err := util.JsonToStruct(body, record)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
records, err := object.GetRecordsByField(record)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = records
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddRecord
|
||||
// @Title AddRecord
|
||||
// @Tag Record API
|
||||
// @Description add a record
|
||||
// @Param body body object.Record true "The details of the record"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /add-record [post]
|
||||
func (c *ApiController) AddRecord() {
|
||||
var record object.Record
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &record)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddRecord(&record))
|
||||
c.ServeJSON()
|
||||
}
|
@ -52,23 +52,29 @@ 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 sortField == "Direct" {
|
||||
provider, err := c.GetProviderFromContext("Storage")
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if limit == "" || page == "" {
|
||||
prefix := sortOrder
|
||||
resources, err := object.GetDirectResources(owner, user, provider, prefix, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(resources)
|
||||
} else if limit == "" || page == "" {
|
||||
resources, err := object.GetResources(owner, user)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
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 +110,7 @@ func (c *ApiController) GetResource() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = resource
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(resource)
|
||||
}
|
||||
|
||||
// UpdateResource
|
||||
@ -162,11 +167,16 @@ func (c *ApiController) DeleteResource() {
|
||||
return
|
||||
}
|
||||
|
||||
if resource.Provider != "" {
|
||||
c.Input().Set("provider", resource.Provider)
|
||||
}
|
||||
c.Input().Set("fullFilePath", resource.Name)
|
||||
provider, err := c.GetProviderFromContext("Storage")
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
_, resource.Name = refineFullFilePath(resource.Name)
|
||||
|
||||
err = object.DeleteFile(provider, resource.Name, c.GetAcceptLanguage())
|
||||
if err != nil {
|
||||
@ -226,6 +236,7 @@ func (c *ApiController) UploadResource() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
_, fullFilePath = refineFullFilePath(fullFilePath)
|
||||
|
||||
fileType := "unknown"
|
||||
contentType := header.Header.Get("Content-Type")
|
||||
@ -350,6 +361,9 @@ func (c *ApiController) UploadResource() {
|
||||
return
|
||||
}
|
||||
|
||||
if user.Properties == nil {
|
||||
user.Properties = map[string]string{}
|
||||
}
|
||||
user.Properties[tag] = fileUrl
|
||||
user.Properties["isIdCardVerified"] = "false"
|
||||
_, err = object.UpdateUser(user.GetId(), user, []string{"properties"}, false)
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@ -32,16 +33,15 @@ func (c *ApiController) UploadRoles() {
|
||||
}
|
||||
|
||||
fileId := fmt.Sprintf("%s_%s_%s", owner, user, util.RemoveExt(header.Filename))
|
||||
|
||||
path := util.GetUploadXlsxPath(fileId)
|
||||
util.EnsureFileFolderExists(path)
|
||||
defer os.Remove(path)
|
||||
err = saveFile(path, &file)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.UploadRoles(owner, fileId)
|
||||
affected, err := object.UploadRoles(owner, path)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
}
|
||||
|
@ -40,6 +40,10 @@ type SmsForm struct {
|
||||
OrgId string `json:"organizationId"` // e.g. "admin/built-in"
|
||||
}
|
||||
|
||||
type NotificationForm struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// SendEmail
|
||||
// @Title SendEmail
|
||||
// @Tag Service API
|
||||
@ -140,10 +144,12 @@ func (c *ApiController) SendSms() {
|
||||
return
|
||||
}
|
||||
|
||||
invalidReceivers := getInvalidSmsReceivers(smsForm)
|
||||
if len(invalidReceivers) != 0 {
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), strings.Join(invalidReceivers, ", ")))
|
||||
return
|
||||
if provider.Type != "Custom HTTP SMS" {
|
||||
invalidReceivers := getInvalidSmsReceivers(smsForm)
|
||||
if len(invalidReceivers) != 0 {
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), strings.Join(invalidReceivers, ", ")))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = object.SendSms(provider, smsForm.Content, smsForm.Receivers...)
|
||||
@ -154,3 +160,33 @@ func (c *ApiController) SendSms() {
|
||||
|
||||
c.ResponseOk()
|
||||
}
|
||||
|
||||
// SendNotification
|
||||
// @Title SendNotification
|
||||
// @Tag Service API
|
||||
// @Description This API is not for Casdoor frontend to call, it is for Casdoor SDKs.
|
||||
// @Param from body controllers.NotificationForm true "Details of the notification request"
|
||||
// @Success 200 {object} Response object
|
||||
// @router /api/send-notification [post]
|
||||
func (c *ApiController) SendNotification() {
|
||||
provider, err := c.GetProviderFromContext("Notification")
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var notificationForm NotificationForm
|
||||
err = json.Unmarshal(c.Ctx.Input.RequestBody, ¬ificationForm)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
err = object.SendNotification(provider, notificationForm.Content)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk()
|
||||
}
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetSessions() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = sessions
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(sessions)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetSessionCount(owner, field, value)
|
||||
@ -81,8 +80,7 @@ func (c *ApiController) GetSingleSession() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = session
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(session)
|
||||
}
|
||||
|
||||
// UpdateSession
|
||||
@ -161,7 +159,5 @@ func (c *ApiController) IsSessionDuplicated() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = &Response{Status: "ok", Msg: "", Data: isUserSessionDuplicated}
|
||||
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(isUserSessionDuplicated)
|
||||
}
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetSubscriptions() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = subscriptions
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(subscriptions)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetSubscriptionCount(owner, field, value)
|
||||
@ -82,8 +81,7 @@ func (c *ApiController) GetSubscription() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = subscription
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(subscription)
|
||||
}
|
||||
|
||||
// UpdateSubscription
|
||||
|
@ -46,8 +46,7 @@ func (c *ApiController) GetSyncers() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = organizationSyncers
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(organizationSyncers)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetSyncerCount(owner, organization, field, value)
|
||||
@ -83,8 +82,7 @@ func (c *ApiController) GetSyncer() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = syncer
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(syncer)
|
||||
}
|
||||
|
||||
// UpdateSyncer
|
||||
|
@ -47,7 +47,10 @@ func (c *ApiController) GetSystemInfo() {
|
||||
// @router /get-version-info [get]
|
||||
func (c *ApiController) GetVersionInfo() {
|
||||
versionInfo, err := util.GetVersionInfo()
|
||||
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
if versionInfo.Version == "" {
|
||||
versionInfo, err = util.GetVersionInfoFromFile()
|
||||
|
||||
|
@ -47,8 +47,7 @@ func (c *ApiController) GetTokens() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = token
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(token)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetTokenCount(owner, organization, field, value)
|
||||
@ -83,8 +82,7 @@ func (c *ApiController) GetToken() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = token
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(token)
|
||||
}
|
||||
|
||||
// UpdateToken
|
||||
|
@ -45,8 +45,7 @@ func (c *ApiController) GetGlobalUsers() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = maskedUsers
|
||||
c.ServeJSON()
|
||||
c.ResponseOk(maskedUsers)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
count, err := object.GetGlobalUserCount(field, value)
|
||||
@ -91,7 +90,7 @@ func (c *ApiController) GetUsers() {
|
||||
|
||||
if limit == "" || page == "" {
|
||||
if groupName != "" {
|
||||
maskedUsers, err := object.GetMaskedUsers(object.GetGroupUsers(groupName))
|
||||
maskedUsers, err := object.GetMaskedUsers(object.GetGroupUsers(util.GetId(owner, groupName)))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
@ -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
|
||||
@ -568,6 +567,22 @@ func (c *ApiController) RemoveUserFromGroup() {
|
||||
name := c.Ctx.Request.Form.Get("name")
|
||||
groupName := c.Ctx.Request.Form.Get("groupName")
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.RemoveUserFromGroup(owner, name, groupName))
|
||||
c.ServeJSON()
|
||||
organization, err := object.GetOrganization(util.GetId("admin", owner))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
item := object.GetAccountItemByName("Groups", organization)
|
||||
res, msg := object.CheckAccountItemModifyRule(item, c.IsAdmin(), c.GetAcceptLanguage())
|
||||
if !res {
|
||||
c.ResponseError(msg)
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.DeleteGroupForUser(util.GetId(owner, name), groupName)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.ResponseOk(affected)
|
||||
}
|
||||
|
@ -48,17 +48,17 @@ func (c *ApiController) UploadUsers() {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
fileId := fmt.Sprintf("%s_%s_%s", owner, user, util.RemoveExt(header.Filename))
|
||||
|
||||
fileId := fmt.Sprintf("%s_%s_%s", owner, user, util.RemoveExt(header.Filename))
|
||||
path := util.GetUploadXlsxPath(fileId)
|
||||
util.EnsureFileFolderExists(path)
|
||||
defer os.Remove(path)
|
||||
err = saveFile(path, &file)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
affected, err := object.UploadUsers(owner, fileId)
|
||||
affected, err := object.UploadUsers(owner, path)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
|
@ -16,6 +16,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/i18n"
|
||||
@ -143,8 +144,30 @@ func (c *ApiController) IsMaskedEnabled() (bool, bool) {
|
||||
return true, isMaskEnabled
|
||||
}
|
||||
|
||||
func refineFullFilePath(fullFilePath string) (string, string) {
|
||||
tokens := strings.Split(fullFilePath, "/")
|
||||
if len(tokens) >= 2 && tokens[0] == "Direct" && tokens[1] != "" {
|
||||
providerName := tokens[1]
|
||||
res := strings.Join(tokens[2:], "/")
|
||||
return providerName, "/" + res
|
||||
} else {
|
||||
return "", fullFilePath
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ApiController) GetProviderFromContext(category string) (*object.Provider, error) {
|
||||
providerName := c.Input().Get("provider")
|
||||
if providerName == "" {
|
||||
field := c.Input().Get("field")
|
||||
value := c.Input().Get("value")
|
||||
if field == "provider" && value != "" {
|
||||
providerName = value
|
||||
} else {
|
||||
fullFilePath := c.Input().Get("fullFilePath")
|
||||
providerName, _ = refineFullFilePath(fullFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
if providerName != "" {
|
||||
provider, err := object.GetProvider(util.GetId("admin", providerName))
|
||||
if err != nil {
|
||||
|
@ -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]
|
||||
|
23
form/auth.go
23
form/auth.go
@ -17,17 +17,18 @@ package form
|
||||
type AuthForm struct {
|
||||
Type string `json:"type"`
|
||||
|
||||
Organization string `json:"organization"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Name string `json:"name"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Affiliation string `json:"affiliation"`
|
||||
IdCard string `json:"idCard"`
|
||||
Region string `json:"region"`
|
||||
Organization string `json:"organization"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Name string `json:"name"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Affiliation string `json:"affiliation"`
|
||||
IdCard string `json:"idCard"`
|
||||
Region string `json:"region"`
|
||||
InvitationCode string `json:"invitationCode"`
|
||||
|
||||
Application string `json:"application"`
|
||||
ClientId string `json:"clientId"`
|
||||
|
32
go.mod
32
go.mod
@ -12,13 +12,13 @@ require (
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/casbin/casbin v1.9.1 // indirect
|
||||
github.com/casbin/casbin/v2 v2.30.1
|
||||
github.com/casdoor/go-sms-sender v0.6.1
|
||||
github.com/casdoor/go-sms-sender v0.12.0
|
||||
github.com/casdoor/gomail/v2 v2.0.1
|
||||
github.com/casdoor/oss v1.2.0
|
||||
github.com/casdoor/oss v1.3.0
|
||||
github.com/casdoor/xorm-adapter/v3 v3.0.4
|
||||
github.com/casvisor/casvisor-go-sdk v1.0.3
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
github.com/denisenkom/go-mssqldb v0.9.0
|
||||
github.com/dlclark/regexp2 v1.9.0 // indirect
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.1 // indirect
|
||||
github.com/fogleman/gg v1.3.0
|
||||
github.com/forestmgy/ldapserver v1.1.0
|
||||
@ -27,36 +27,32 @@ require (
|
||||
github.com/go-mysql-org/go-mysql v1.7.0
|
||||
github.com/go-pay/gopay v1.5.72
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||
github.com/go-webauthn/webauthn v0.6.0
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/mux v1.7.3 // indirect
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/lestrrat-go/jwx v1.2.21
|
||||
github.com/lib/pq v1.10.2
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3
|
||||
github.com/markbates/goth v1.75.2
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/nikoksr/notify v0.41.0
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
|
||||
github.com/nyaruka/phonenumbers v1.1.5
|
||||
github.com/pkoukk/tiktoken-go v0.1.1
|
||||
github.com/pquerna/otp v1.4.0
|
||||
github.com/prometheus/client_golang v1.11.1
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/prometheus/client_model v0.3.0
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/russellhaering/gosaml2 v0.9.0
|
||||
github.com/russellhaering/goxmldsig v1.2.0
|
||||
github.com/sashabaranov/go-openai v1.12.0
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/stripe/stripe-go/v74 v74.29.0
|
||||
github.com/tealeg/xlsx v1.0.5
|
||||
github.com/thanhpk/randstr v1.0.4
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
@ -64,12 +60,10 @@ require (
|
||||
github.com/xorm-io/core v0.7.4
|
||||
github.com/xorm-io/xorm v1.1.6
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.6.0
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
|
||||
golang.org/x/net v0.7.0
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
||||
golang.org/x/crypto v0.11.0
|
||||
golang.org/x/net v0.13.0
|
||||
golang.org/x/oauth2 v0.10.0
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84
|
||||
modernc.org/sqlite v1.18.2
|
||||
)
|
||||
|
@ -33,6 +33,12 @@ func TestGenerateI18nFrontend(t *testing.T) {
|
||||
applyToOtherLanguage("frontend", "ru", data)
|
||||
applyToOtherLanguage("frontend", "vi", data)
|
||||
applyToOtherLanguage("frontend", "pt", data)
|
||||
applyToOtherLanguage("frontend", "it", data)
|
||||
applyToOtherLanguage("frontend", "ms", data)
|
||||
applyToOtherLanguage("frontend", "tr", data)
|
||||
applyToOtherLanguage("frontend", "ar", data)
|
||||
applyToOtherLanguage("frontend", "he", data)
|
||||
applyToOtherLanguage("frontend", "fi", data)
|
||||
}
|
||||
|
||||
func TestGenerateI18nBackend(t *testing.T) {
|
||||
@ -49,4 +55,10 @@ func TestGenerateI18nBackend(t *testing.T) {
|
||||
applyToOtherLanguage("backend", "ru", data)
|
||||
applyToOtherLanguage("backend", "vi", data)
|
||||
applyToOtherLanguage("backend", "pt", data)
|
||||
applyToOtherLanguage("backend", "it", data)
|
||||
applyToOtherLanguage("backend", "ms", data)
|
||||
applyToOtherLanguage("backend", "tr", data)
|
||||
applyToOtherLanguage("backend", "ar", data)
|
||||
applyToOtherLanguage("backend", "he", data)
|
||||
applyToOtherLanguage("backend", "fi", data)
|
||||
}
|
||||
|
142
i18n/locales/ar/data.json
Normal file
142
i18n/locales/ar/data.json
Normal file
@ -0,0 +1,142 @@
|
||||
{
|
||||
"account": {
|
||||
"Failed to add user": "Failed to add user",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Please sign out first": "Please sign out first",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"Challenge method should be S256": "Challenge method should be S256",
|
||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||
"Failed to login in: %s": "Failed to login in: %s",
|
||||
"Invalid token": "Invalid token",
|
||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||
"The application: %s does not exist": "The application: %s does not exist",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s",
|
||||
"User's tag: %s is not listed in the application's tags": "User's tag: %s is not listed in the application's tags"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
"DisplayName is not valid real name": "DisplayName is not valid real name",
|
||||
"Email already exists": "Email already exists",
|
||||
"Email cannot be empty": "Email cannot be empty",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Empty username.": "Empty username.",
|
||||
"FirstName cannot be blank": "FirstName cannot be blank",
|
||||
"LDAP user name or password incorrect": "LDAP user name or password incorrect",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Password must have at least 6 characters": "Password must have at least 6 characters",
|
||||
"Phone already exists": "Phone already exists",
|
||||
"Phone cannot be empty": "Phone cannot be empty",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"Session outdated, please login again": "Session outdated, please login again",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"The user: %s doesn't exist in LDAP server": "The user: %s doesn't exist in LDAP server",
|
||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||
"Username already exists": "Username already exists",
|
||||
"Username cannot be an email address": "Username cannot be an email address",
|
||||
"Username cannot contain white spaces": "Username cannot contain white spaces",
|
||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
|
||||
"password or code is incorrect": "password or code is incorrect",
|
||||
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||
"unsupported password type: %s": "unsupported password type: %s"
|
||||
},
|
||||
"general": {
|
||||
"Missing parameter": "Missing parameter",
|
||||
"Please login first": "Please login first",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "Please link first",
|
||||
"This application has no providers": "This application has no providers",
|
||||
"This application has no providers of type": "This application has no providers of type",
|
||||
"This provider can't be unlinked": "This provider can't be unlinked",
|
||||
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
|
||||
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "Only admin can modify the %s.",
|
||||
"The %s is immutable.": "The %s is immutable.",
|
||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "Invalid application id",
|
||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "User is nil for tag: avatar",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "Application %s not found"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "provider %s's category is not SAML"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
|
||||
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
|
||||
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||
},
|
||||
"token": {
|
||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||
"Invalid client_id": "Invalid client_id",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Display name cannot be empty",
|
||||
"New password cannot contain blank space.": "New password cannot contain blank space."
|
||||
},
|
||||
"user_upload": {
|
||||
"Failed to import users": "Failed to import users"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
"Unknown type": "Unknown type",
|
||||
"Wrong verification code!": "Wrong verification code!",
|
||||
"You should verify your code in %d min!": "You should verify your code in %d min!",
|
||||
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "Found no credentials for this user",
|
||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||
}
|
||||
}
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s und %s stimmen nicht überein"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Zugehörigkeit darf nicht leer sein",
|
||||
"DisplayName cannot be blank": "Anzeigename kann nicht leer sein",
|
||||
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Los servicios %s y %s no coinciden"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Afiliación no puede estar en blanco",
|
||||
"DisplayName cannot be blank": "El nombre de visualización no puede estar en blanco",
|
||||
|
142
i18n/locales/fi/data.json
Normal file
142
i18n/locales/fi/data.json
Normal file
@ -0,0 +1,142 @@
|
||||
{
|
||||
"account": {
|
||||
"Failed to add user": "Failed to add user",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Please sign out first": "Please sign out first",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"Challenge method should be S256": "Challenge method should be S256",
|
||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||
"Failed to login in: %s": "Failed to login in: %s",
|
||||
"Invalid token": "Invalid token",
|
||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||
"The application: %s does not exist": "The application: %s does not exist",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s",
|
||||
"User's tag: %s is not listed in the application's tags": "User's tag: %s is not listed in the application's tags"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
"DisplayName is not valid real name": "DisplayName is not valid real name",
|
||||
"Email already exists": "Email already exists",
|
||||
"Email cannot be empty": "Email cannot be empty",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Empty username.": "Empty username.",
|
||||
"FirstName cannot be blank": "FirstName cannot be blank",
|
||||
"LDAP user name or password incorrect": "LDAP user name or password incorrect",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Password must have at least 6 characters": "Password must have at least 6 characters",
|
||||
"Phone already exists": "Phone already exists",
|
||||
"Phone cannot be empty": "Phone cannot be empty",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"Session outdated, please login again": "Session outdated, please login again",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"The user: %s doesn't exist in LDAP server": "The user: %s doesn't exist in LDAP server",
|
||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||
"Username already exists": "Username already exists",
|
||||
"Username cannot be an email address": "Username cannot be an email address",
|
||||
"Username cannot contain white spaces": "Username cannot contain white spaces",
|
||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
|
||||
"password or code is incorrect": "password or code is incorrect",
|
||||
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||
"unsupported password type: %s": "unsupported password type: %s"
|
||||
},
|
||||
"general": {
|
||||
"Missing parameter": "Missing parameter",
|
||||
"Please login first": "Please login first",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "Please link first",
|
||||
"This application has no providers": "This application has no providers",
|
||||
"This application has no providers of type": "This application has no providers of type",
|
||||
"This provider can't be unlinked": "This provider can't be unlinked",
|
||||
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
|
||||
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "Only admin can modify the %s.",
|
||||
"The %s is immutable.": "The %s is immutable.",
|
||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "Invalid application id",
|
||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "User is nil for tag: avatar",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "Application %s not found"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "provider %s's category is not SAML"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
|
||||
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
|
||||
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||
},
|
||||
"token": {
|
||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||
"Invalid client_id": "Invalid client_id",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Display name cannot be empty",
|
||||
"New password cannot contain blank space.": "New password cannot contain blank space."
|
||||
},
|
||||
"user_upload": {
|
||||
"Failed to import users": "Failed to import users"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
"Unknown type": "Unknown type",
|
||||
"Wrong verification code!": "Wrong verification code!",
|
||||
"You should verify your code in %d min!": "You should verify your code in %d min!",
|
||||
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "Found no credentials for this user",
|
||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||
}
|
||||
}
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Les services %s et %s ne correspondent pas"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation ne peut pas être vide",
|
||||
"DisplayName cannot be blank": "Le nom d'affichage ne peut pas être vide",
|
||||
|
142
i18n/locales/he/data.json
Normal file
142
i18n/locales/he/data.json
Normal file
@ -0,0 +1,142 @@
|
||||
{
|
||||
"account": {
|
||||
"Failed to add user": "Failed to add user",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Please sign out first": "Please sign out first",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"Challenge method should be S256": "Challenge method should be S256",
|
||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||
"Failed to login in: %s": "Failed to login in: %s",
|
||||
"Invalid token": "Invalid token",
|
||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||
"The application: %s does not exist": "The application: %s does not exist",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s",
|
||||
"User's tag: %s is not listed in the application's tags": "User's tag: %s is not listed in the application's tags"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
"DisplayName is not valid real name": "DisplayName is not valid real name",
|
||||
"Email already exists": "Email already exists",
|
||||
"Email cannot be empty": "Email cannot be empty",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Empty username.": "Empty username.",
|
||||
"FirstName cannot be blank": "FirstName cannot be blank",
|
||||
"LDAP user name or password incorrect": "LDAP user name or password incorrect",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Password must have at least 6 characters": "Password must have at least 6 characters",
|
||||
"Phone already exists": "Phone already exists",
|
||||
"Phone cannot be empty": "Phone cannot be empty",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"Session outdated, please login again": "Session outdated, please login again",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"The user: %s doesn't exist in LDAP server": "The user: %s doesn't exist in LDAP server",
|
||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||
"Username already exists": "Username already exists",
|
||||
"Username cannot be an email address": "Username cannot be an email address",
|
||||
"Username cannot contain white spaces": "Username cannot contain white spaces",
|
||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
|
||||
"password or code is incorrect": "password or code is incorrect",
|
||||
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||
"unsupported password type: %s": "unsupported password type: %s"
|
||||
},
|
||||
"general": {
|
||||
"Missing parameter": "Missing parameter",
|
||||
"Please login first": "Please login first",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "Please link first",
|
||||
"This application has no providers": "This application has no providers",
|
||||
"This application has no providers of type": "This application has no providers of type",
|
||||
"This provider can't be unlinked": "This provider can't be unlinked",
|
||||
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
|
||||
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "Only admin can modify the %s.",
|
||||
"The %s is immutable.": "The %s is immutable.",
|
||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "Invalid application id",
|
||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "User is nil for tag: avatar",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "Application %s not found"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "provider %s's category is not SAML"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
|
||||
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
|
||||
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||
},
|
||||
"token": {
|
||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||
"Invalid client_id": "Invalid client_id",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Display name cannot be empty",
|
||||
"New password cannot contain blank space.": "New password cannot contain blank space."
|
||||
},
|
||||
"user_upload": {
|
||||
"Failed to import users": "Failed to import users"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
"Unknown type": "Unknown type",
|
||||
"Wrong verification code!": "Wrong verification code!",
|
||||
"You should verify your code in %d min!": "You should verify your code in %d min!",
|
||||
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "Found no credentials for this user",
|
||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||
}
|
||||
}
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Layanan %s dan %s tidak cocok"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Keterkaitan tidak boleh kosong",
|
||||
"DisplayName cannot be blank": "Nama Pengguna tidak boleh kosong",
|
||||
|
150
i18n/locales/it/data.json
Normal file
150
i18n/locales/it/data.json
Normal file
@ -0,0 +1,150 @@
|
||||
{
|
||||
"account": {
|
||||
"Failed to add user": "Failed to add user",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Please sign out first": "Please sign out first",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"Challenge method should be S256": "Challenge method should be S256",
|
||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||
"Failed to login in: %s": "Failed to login in: %s",
|
||||
"Invalid token": "Invalid token",
|
||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||
"The application: %s does not exist": "The application: %s does not exist",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s",
|
||||
"User's tag: %s is not listed in the application's tags": "User's tag: %s is not listed in the application's tags"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
"DisplayName is not valid real name": "DisplayName is not valid real name",
|
||||
"Email already exists": "Email already exists",
|
||||
"Email cannot be empty": "Email cannot be empty",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Empty username.": "Empty username.",
|
||||
"FirstName cannot be blank": "FirstName cannot be blank",
|
||||
"LDAP user name or password incorrect": "LDAP user name or password incorrect",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Password must have at least 6 characters": "Password must have at least 6 characters",
|
||||
"Phone already exists": "Phone already exists",
|
||||
"Phone cannot be empty": "Phone cannot be empty",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"Session outdated, please login again": "Session outdated, please login again",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"The user: %s doesn't exist in LDAP server": "The user: %s doesn't exist in LDAP server",
|
||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||
"Username already exists": "Username already exists",
|
||||
"Username cannot be an email address": "Username cannot be an email address",
|
||||
"Username cannot contain white spaces": "Username cannot contain white spaces",
|
||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
|
||||
"password or code is incorrect": "password or code is incorrect",
|
||||
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||
"unsupported password type: %s": "unsupported password type: %s"
|
||||
},
|
||||
"general": {
|
||||
"Missing parameter": "Missing parameter",
|
||||
"Please login first": "Please login first",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "Please link first",
|
||||
"This application has no providers": "This application has no providers",
|
||||
"This application has no providers of type": "This application has no providers of type",
|
||||
"This provider can't be unlinked": "This provider can't be unlinked",
|
||||
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
|
||||
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "Only admin can modify the %s.",
|
||||
"The %s is immutable.": "The %s is immutable.",
|
||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "Invalid application id",
|
||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "User is nil for tag: avatar",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "Application %s not found"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "provider %s's category is not SAML"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
|
||||
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
|
||||
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||
},
|
||||
"token": {
|
||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||
"Invalid client_id": "Invalid client_id",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Display name cannot be empty",
|
||||
"New password cannot contain blank space.": "New password cannot contain blank space."
|
||||
},
|
||||
"user_upload": {
|
||||
"Failed to import users": "Failed to import users"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
"Unknown type": "Unknown type",
|
||||
"Wrong verification code!": "Wrong verification code!",
|
||||
"You should verify your code in %d min!": "You should verify your code in %d min!",
|
||||
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "Found no credentials for this user",
|
||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||
}
|
||||
}
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "サービス%sと%sは一致しません"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "所属は空白にできません",
|
||||
"DisplayName cannot be blank": "表示名は空白にできません",
|
||||
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "서비스 %s와 %s는 일치하지 않습니다"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "소속은 비워 둘 수 없습니다",
|
||||
"DisplayName cannot be blank": "DisplayName는 비어 있을 수 없습니다",
|
||||
|
150
i18n/locales/ms/data.json
Normal file
150
i18n/locales/ms/data.json
Normal file
@ -0,0 +1,150 @@
|
||||
{
|
||||
"account": {
|
||||
"Failed to add user": "Failed to add user",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Please sign out first": "Please sign out first",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"Challenge method should be S256": "Challenge method should be S256",
|
||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||
"Failed to login in: %s": "Failed to login in: %s",
|
||||
"Invalid token": "Invalid token",
|
||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||
"The application: %s does not exist": "The application: %s does not exist",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s",
|
||||
"User's tag: %s is not listed in the application's tags": "User's tag: %s is not listed in the application's tags"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
"DisplayName is not valid real name": "DisplayName is not valid real name",
|
||||
"Email already exists": "Email already exists",
|
||||
"Email cannot be empty": "Email cannot be empty",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Empty username.": "Empty username.",
|
||||
"FirstName cannot be blank": "FirstName cannot be blank",
|
||||
"LDAP user name or password incorrect": "LDAP user name or password incorrect",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Password must have at least 6 characters": "Password must have at least 6 characters",
|
||||
"Phone already exists": "Phone already exists",
|
||||
"Phone cannot be empty": "Phone cannot be empty",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"Session outdated, please login again": "Session outdated, please login again",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"The user: %s doesn't exist in LDAP server": "The user: %s doesn't exist in LDAP server",
|
||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||
"Username already exists": "Username already exists",
|
||||
"Username cannot be an email address": "Username cannot be an email address",
|
||||
"Username cannot contain white spaces": "Username cannot contain white spaces",
|
||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
|
||||
"password or code is incorrect": "password or code is incorrect",
|
||||
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||
"unsupported password type: %s": "unsupported password type: %s"
|
||||
},
|
||||
"general": {
|
||||
"Missing parameter": "Missing parameter",
|
||||
"Please login first": "Please login first",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "Please link first",
|
||||
"This application has no providers": "This application has no providers",
|
||||
"This application has no providers of type": "This application has no providers of type",
|
||||
"This provider can't be unlinked": "This provider can't be unlinked",
|
||||
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
|
||||
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "Only admin can modify the %s.",
|
||||
"The %s is immutable.": "The %s is immutable.",
|
||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "Invalid application id",
|
||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "User is nil for tag: avatar",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "Application %s not found"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "provider %s's category is not SAML"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
|
||||
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
|
||||
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||
},
|
||||
"token": {
|
||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||
"Invalid client_id": "Invalid client_id",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Display name cannot be empty",
|
||||
"New password cannot contain blank space.": "New password cannot contain blank space."
|
||||
},
|
||||
"user_upload": {
|
||||
"Failed to import users": "Failed to import users"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
"Unknown type": "Unknown type",
|
||||
"Wrong verification code!": "Wrong verification code!",
|
||||
"You should verify your code in %d min!": "You should verify your code in %d min!",
|
||||
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "Found no credentials for this user",
|
||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||
}
|
||||
}
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Сервисы %s и %s не совпадают"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Принадлежность не может быть пустым значением",
|
||||
"DisplayName cannot be blank": "Имя отображения не может быть пустым",
|
||||
|
150
i18n/locales/tr/data.json
Normal file
150
i18n/locales/tr/data.json
Normal file
@ -0,0 +1,150 @@
|
||||
{
|
||||
"account": {
|
||||
"Failed to add user": "Failed to add user",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Please sign out first": "Please sign out first",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"Challenge method should be S256": "Challenge method should be S256",
|
||||
"Failed to create user, user information is invalid: %s": "Failed to create user, user information is invalid: %s",
|
||||
"Failed to login in: %s": "Failed to login in: %s",
|
||||
"Invalid token": "Invalid token",
|
||||
"State expected: %s, but got: %s": "State expected: %s, but got: %s",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account via %%s, please use another way to sign up",
|
||||
"The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support": "The account for provider: %s and username: %s (%s) does not exist and is not allowed to sign up as new account, please contact your IT support",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)",
|
||||
"The application: %s does not exist": "The application: %s does not exist",
|
||||
"The login method: login with password is not enabled for the application": "The login method: login with password is not enabled for the application",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s",
|
||||
"User's tag: %s is not listed in the application's tags": "User's tag: %s is not listed in the application's tags"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Service %s and %s do not match"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Affiliation cannot be blank",
|
||||
"DisplayName cannot be blank": "DisplayName cannot be blank",
|
||||
"DisplayName is not valid real name": "DisplayName is not valid real name",
|
||||
"Email already exists": "Email already exists",
|
||||
"Email cannot be empty": "Email cannot be empty",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Empty username.": "Empty username.",
|
||||
"FirstName cannot be blank": "FirstName cannot be blank",
|
||||
"LDAP user name or password incorrect": "LDAP user name or password incorrect",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Multiple accounts with same uid, please check your ldap server": "Multiple accounts with same uid, please check your ldap server",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Password must have at least 6 characters": "Password must have at least 6 characters",
|
||||
"Phone already exists": "Phone already exists",
|
||||
"Phone cannot be empty": "Phone cannot be empty",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"Session outdated, please login again": "Session outdated, please login again",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"The user: %s doesn't exist in LDAP server": "The user: %s doesn't exist in LDAP server",
|
||||
"The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.": "The username may only contain alphanumeric characters, underlines or hyphens, cannot have consecutive hyphens or underlines, and cannot begin or end with a hyphen or underline.",
|
||||
"Username already exists": "Username already exists",
|
||||
"Username cannot be an email address": "Username cannot be an email address",
|
||||
"Username cannot contain white spaces": "Username cannot contain white spaces",
|
||||
"Username cannot start with a digit": "Username cannot start with a digit",
|
||||
"Username is too long (maximum is 39 characters).": "Username is too long (maximum is 39 characters).",
|
||||
"Username must have at least 2 characters": "Username must have at least 2 characters",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "You have entered the wrong password or code too many times, please wait for %d minutes and try again",
|
||||
"Your region is not allow to signup by phone": "Your region is not allow to signup by phone",
|
||||
"password or code is incorrect": "password or code is incorrect",
|
||||
"password or code is incorrect, you have %d remaining chances": "password or code is incorrect, you have %d remaining chances",
|
||||
"unsupported password type: %s": "unsupported password type: %s"
|
||||
},
|
||||
"general": {
|
||||
"Missing parameter": "Missing parameter",
|
||||
"Please login first": "Please login first",
|
||||
"The user: %s doesn't exist": "The user: %s doesn't exist",
|
||||
"don't support captchaProvider: ": "don't support captchaProvider: ",
|
||||
"this operation is not allowed in demo mode": "this operation is not allowed in demo mode"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "Ldap server exist"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "Please link first",
|
||||
"This application has no providers": "This application has no providers",
|
||||
"This application has no providers of type": "This application has no providers of type",
|
||||
"This provider can't be unlinked": "This provider can't be unlinked",
|
||||
"You are not the global admin, you can't unlink other users": "You are not the global admin, you can't unlink other users",
|
||||
"You can't unlink yourself, you are not a member of any application": "You can't unlink yourself, you are not a member of any application"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "Only admin can modify the %s.",
|
||||
"The %s is immutable.": "The %s is immutable.",
|
||||
"Unknown modify rule %s.": "Unknown modify rule %s."
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "Invalid application id",
|
||||
"the provider: %s does not exist": "the provider: %s does not exist"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "User is nil for tag: avatar",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "Username or fullFilePath is empty: username = %s, fullFilePath = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "Application %s not found"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "provider %s's category is not SAML"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "Empty parameters for emailForm: %v",
|
||||
"Invalid Email receivers: %s": "Invalid Email receivers: %s",
|
||||
"Invalid phone receivers: %s": "Invalid phone receivers: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "The objectKey: %s is not allowed",
|
||||
"The provider type: %s is not supported": "The provider type: %s is not supported"
|
||||
},
|
||||
"token": {
|
||||
"Empty clientId or clientSecret": "Empty clientId or clientSecret",
|
||||
"Grant_type: %s is not supported in this application": "Grant_type: %s is not supported in this application",
|
||||
"Invalid application or wrong clientSecret": "Invalid application or wrong clientSecret",
|
||||
"Invalid client_id": "Invalid client_id",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "Redirect URI: %s doesn't exist in the allowed Redirect URI list",
|
||||
"Token not found, invalid accessToken": "Token not found, invalid accessToken"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "Display name cannot be empty",
|
||||
"New password cannot contain blank space.": "New password cannot contain blank space."
|
||||
},
|
||||
"user_upload": {
|
||||
"Failed to import users": "Failed to import users"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "No application is found for userId: %s",
|
||||
"No provider for category: %s is found for application: %s": "No provider for category: %s is found for application: %s",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "Code has not been sent yet!",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Phone number is invalid in your region %s": "Phone number is invalid in your region %s",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unable to get the email modify rule.": "Unable to get the email modify rule.",
|
||||
"Unable to get the phone modify rule.": "Unable to get the phone modify rule.",
|
||||
"Unknown type": "Unknown type",
|
||||
"Wrong verification code!": "Wrong verification code!",
|
||||
"You should verify your code in %d min!": "You should verify your code in %d min!",
|
||||
"the user does not exist, please sign up first": "the user does not exist, please sign up first"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "Found no credentials for this user",
|
||||
"Please call WebAuthnSigninBegin first": "Please call WebAuthnSigninBegin first"
|
||||
}
|
||||
}
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "Dịch sang tiếng Việt: Dịch vụ %s và %s không khớp"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "Tình trạng liên kết không thể để trống",
|
||||
"DisplayName cannot be blank": "Tên hiển thị không thể để trống",
|
||||
|
@ -24,14 +24,6 @@
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "服务%s与%s不匹配"
|
||||
},
|
||||
"chat": {
|
||||
"The chat type must be \\\"AI\\\"": "The chat type must be \\\"AI\\\"",
|
||||
"The chat: %s is not found": "The chat: %s is not found",
|
||||
"The message is invalid": "The message is invalid",
|
||||
"The message: %s is not found": "The message: %s is not found",
|
||||
"The provider: %s is invalid": "The provider: %s is invalid",
|
||||
"The provider: %s is not found": "The provider: %s is not found"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "工作单位不可为空",
|
||||
"DisplayName cannot be blank": "显示名称不可为空",
|
||||
|
@ -132,7 +132,7 @@ func (idp *GiteeIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
"type": "User",
|
||||
"blog": null,
|
||||
"weibo": null,
|
||||
"bio": "个人博客:https://gitee.com/xxx/xxx/pages",
|
||||
"bio": "bio",
|
||||
"public_repos": 2,
|
||||
"public_gists": 0,
|
||||
"followers": 0,
|
||||
|
@ -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 {
|
||||
|
70
idp/metamask.go
Normal file
70
idp/metamask.go
Normal file
@ -0,0 +1,70 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
type MetaMaskIdProvider struct {
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
func NewMetaMaskIdProvider() *MetaMaskIdProvider {
|
||||
idp := &MetaMaskIdProvider{}
|
||||
return idp
|
||||
}
|
||||
|
||||
func (idp *MetaMaskIdProvider) SetHttpClient(client *http.Client) {
|
||||
idp.Client = client
|
||||
}
|
||||
|
||||
func (idp *MetaMaskIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
web3AuthToken := Web3AuthToken{}
|
||||
if err := json.Unmarshal([]byte(code), &web3AuthToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token := &oauth2.Token{
|
||||
AccessToken: web3AuthToken.Signature,
|
||||
TokenType: "Bearer",
|
||||
Expiry: time.Now().AddDate(0, 1, 0),
|
||||
}
|
||||
|
||||
token = token.WithExtra(map[string]interface{}{
|
||||
Web3AuthTokenKey: web3AuthToken,
|
||||
})
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (idp *MetaMaskIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
// TODO use "github.com/ethereum/go-ethereum" to check address's eth balance or transaction
|
||||
web3AuthToken, ok := token.Extra(Web3AuthTokenKey).(Web3AuthToken)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid web3AuthToken")
|
||||
}
|
||||
userInfo := &UserInfo{
|
||||
Id: web3AuthToken.Address,
|
||||
Username: web3AuthToken.Address,
|
||||
DisplayName: web3AuthToken.Address,
|
||||
AvatarUrl: fmt.Sprintf("metamask:%v", web3AuthToken.Address),
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
@ -109,6 +109,10 @@ 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()
|
||||
case "Web3Onboard":
|
||||
return NewWeb3OnboardIdProvider()
|
||||
default:
|
||||
if isGothSupport(idpInfo.Type) {
|
||||
return NewGothIdProvider(idpInfo.Type, idpInfo.ClientId, idpInfo.ClientSecret, redirectUrl, idpInfo.HostUrl)
|
||||
|
103
idp/web3onboard.go
Normal file
103
idp/web3onboard.go
Normal file
@ -0,0 +1,103 @@
|
||||
// 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"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
const Web3AuthTokenKey = "web3AuthToken"
|
||||
|
||||
type Web3AuthToken struct {
|
||||
Address string `json:"address"`
|
||||
Nonce string `json:"nonce"`
|
||||
CreateAt uint64 `json:"createAt"`
|
||||
TypedData string `json:"typedData"` // typed data use for application
|
||||
Signature string `json:"signature"` // signature for typed data
|
||||
WalletType string `json:"walletType"` // e.g."MetaMask", "Coinbase"
|
||||
}
|
||||
|
||||
type Web3OnboardIdProvider struct {
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
func NewWeb3OnboardIdProvider() *Web3OnboardIdProvider {
|
||||
idp := &Web3OnboardIdProvider{}
|
||||
return idp
|
||||
}
|
||||
|
||||
func (idp *Web3OnboardIdProvider) SetHttpClient(client *http.Client) {
|
||||
idp.Client = client
|
||||
}
|
||||
|
||||
func (idp *Web3OnboardIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
web3AuthToken := Web3AuthToken{}
|
||||
if err := json.Unmarshal([]byte(code), &web3AuthToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
token := &oauth2.Token{
|
||||
AccessToken: fmt.Sprintf("%v:%v", Web3AuthTokenKey, web3AuthToken.Address),
|
||||
TokenType: "Bearer",
|
||||
Expiry: time.Now().AddDate(0, 1, 0),
|
||||
}
|
||||
|
||||
token = token.WithExtra(map[string]interface{}{
|
||||
Web3AuthTokenKey: web3AuthToken,
|
||||
})
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (idp *Web3OnboardIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
web3AuthToken, ok := token.Extra(Web3AuthTokenKey).(Web3AuthToken)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid web3AuthToken")
|
||||
}
|
||||
|
||||
fmtAddress := fmt.Sprintf("%v_%v",
|
||||
strings.ReplaceAll(strings.TrimSpace(web3AuthToken.WalletType), " ", "_"),
|
||||
web3AuthToken.Address,
|
||||
)
|
||||
userInfo := &UserInfo{
|
||||
Id: fmtAddress,
|
||||
Username: fmtAddress,
|
||||
DisplayName: fmtAddress,
|
||||
AvatarUrl: fmt.Sprintf("metamask:%v", forceEthereumAddress(web3AuthToken.Address)),
|
||||
}
|
||||
return userInfo, nil
|
||||
}
|
||||
|
||||
func forceEthereumAddress(address string) string {
|
||||
// The required address to general MetaMask avatar is a string of length 42 that represents an Ethereum address.
|
||||
// This function is used to force any address as an Ethereum address
|
||||
address = strings.TrimSpace(address)
|
||||
var builder strings.Builder
|
||||
for _, ch := range address {
|
||||
builder.WriteRune(ch)
|
||||
}
|
||||
for len(builder.String()) < 42 {
|
||||
builder.WriteString("0")
|
||||
}
|
||||
if len(builder.String()) > 42 {
|
||||
return builder.String()[:42]
|
||||
}
|
||||
return builder.String()
|
||||
}
|
@ -9,11 +9,11 @@
|
||||
"passwordType": "plain",
|
||||
"passwordSalt": "",
|
||||
"passwordOptions": ["AtLeast6"],
|
||||
"countryCodes": ["US", "ES", "CN", "FR", "DE", "GB", "JP", "KR", "VN", "ID", "SG", "IN"],
|
||||
"countryCodes": ["US", "ES", "CN", "FR", "DE", "GB", "JP", "KR", "VN", "ID", "SG", "IN", "IT", "MY", "TR", "DZ", "IL", "PH"],
|
||||
"defaultAvatar": "",
|
||||
"defaultApplication": "",
|
||||
"tags": [],
|
||||
"languages": ["en", "zh", "es", "fr", "de", "id", "ja", "ko", "ru", "vi"],
|
||||
"languages": ["en", "zh", "es", "fr", "de", "id", "ja", "ko", "ru", "vi", "it", "ms", "tr","ar", "he", "fi"],
|
||||
"masterPassword": "",
|
||||
"initScore": 2000,
|
||||
"enableSoftDeletion": false,
|
||||
@ -123,7 +123,6 @@
|
||||
"score": 2000,
|
||||
"ranking": 1,
|
||||
"isAdmin": true,
|
||||
"isGlobalAdmin": true,
|
||||
"isForbidden": false,
|
||||
"isDeleted": false,
|
||||
"signupApplication": "",
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ func handleBind(w ldap.ResponseWriter, m *ldap.Message) {
|
||||
return
|
||||
}
|
||||
|
||||
if bindOrg == "built-in" || bindUser.IsGlobalAdmin {
|
||||
if bindOrg == "built-in" || bindUser.IsGlobalAdmin() {
|
||||
m.Client.IsGlobalAdmin, m.Client.IsOrgAdmin = true, true
|
||||
} else if bindUser.IsAdmin {
|
||||
m.Client.IsOrgAdmin = true
|
||||
|
18
main.go
18
main.go
@ -15,7 +15,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/beego/beego"
|
||||
@ -30,17 +29,10 @@ import (
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
func getCreateDatabaseFlag() bool {
|
||||
res := flag.Bool("createDatabase", false, "true if you need Casdoor to create database")
|
||||
flag.Parse()
|
||||
return *res
|
||||
}
|
||||
|
||||
func main() {
|
||||
createDatabase := getCreateDatabaseFlag()
|
||||
|
||||
object.InitFlag()
|
||||
object.InitAdapter()
|
||||
object.CreateTables(createDatabase)
|
||||
object.CreateTables()
|
||||
object.DoMigration()
|
||||
|
||||
object.InitDb()
|
||||
@ -48,7 +40,9 @@ func main() {
|
||||
object.InitDefaultStorageProvider()
|
||||
object.InitLdapAutoSynchronizer()
|
||||
proxy.InitHttpClient()
|
||||
authz.InitAuthz()
|
||||
authz.InitApi()
|
||||
object.InitUserManager()
|
||||
object.InitCasvisorConfig()
|
||||
|
||||
util.SafeGoroutine(func() { object.RunSyncUsersJob() })
|
||||
|
||||
@ -62,7 +56,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)
|
||||
|
||||
|
73
notification/custom_http.go
Normal file
73
notification/custom_http.go
Normal file
@ -0,0 +1,73 @@
|
||||
// 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 notification
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/casdoor/casdoor/proxy"
|
||||
)
|
||||
|
||||
type HttpNotificationClient struct {
|
||||
endpoint string
|
||||
method string
|
||||
paramName string
|
||||
}
|
||||
|
||||
func NewCustomHttpProvider(endpoint string, method string, paramName string) (*HttpNotificationClient, error) {
|
||||
client := &HttpNotificationClient{
|
||||
endpoint: endpoint,
|
||||
method: method,
|
||||
paramName: paramName,
|
||||
}
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *HttpNotificationClient) Send(ctx context.Context, subject string, content string) error {
|
||||
var err error
|
||||
|
||||
httpClient := proxy.DefaultHttpClient
|
||||
|
||||
req, err := http.NewRequest(c.method, c.endpoint, bytes.NewBufferString(content))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if c.method == "POST" {
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.PostForm = map[string][]string{
|
||||
c.paramName: {content},
|
||||
}
|
||||
} else if c.method == "GET" {
|
||||
q := req.URL.Query()
|
||||
q.Add(c.paramName, content)
|
||||
req.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("SendMessage() error, custom HTTP Notification request failed with status: %s", resp.Status)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
@ -12,17 +12,16 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ai
|
||||
package notification
|
||||
|
||||
import "github.com/pkoukk/tiktoken-go"
|
||||
import "github.com/nikoksr/notify"
|
||||
|
||||
func getTokenSize(model string, prompt string) (int, error) {
|
||||
tkm, err := tiktoken.EncodingForModel(model)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
func GetNotificationProvider(typ string, appId string, receiver string, method string, title string) (notify.Notifier, error) {
|
||||
if typ == "Telegram" {
|
||||
return NewTelegramProvider(appId, receiver)
|
||||
} else if typ == "Custom HTTP" {
|
||||
return NewCustomHttpProvider(receiver, method, title)
|
||||
}
|
||||
|
||||
token := tkm.Encode(prompt, nil, nil)
|
||||
res := len(token)
|
||||
return res, nil
|
||||
return nil, nil
|
||||
}
|
42
notification/telegram.go
Normal file
42
notification/telegram.go
Normal file
@ -0,0 +1,42 @@
|
||||
// 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 notification
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/casdoor/casdoor/proxy"
|
||||
api "github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"github.com/nikoksr/notify"
|
||||
"github.com/nikoksr/notify/service/telegram"
|
||||
)
|
||||
|
||||
func NewTelegramProvider(apiToken string, chatIdStr string) (notify.Notifier, error) {
|
||||
client, err := api.NewBotAPIWithClient(apiToken, proxy.ProxyHttpClient)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := &telegram.Telegram{}
|
||||
t.SetClient(client)
|
||||
|
||||
chatId, err := strconv.ParseInt(chatIdStr, 10, 64)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
t.AddReceivers(chatId)
|
||||
|
||||
return t, nil
|
||||
}
|
@ -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,205 @@ package object
|
||||
|
||||
import (
|
||||
"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 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"`
|
||||
DatabaseType string `xorm:"varchar(100)" json:"databaseType"`
|
||||
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"`
|
||||
Database string `xorm:"varchar(100)" json:"database"`
|
||||
Table string `xorm:"varchar(100)" json:"table"`
|
||||
TableNamePrefix string `xorm:"varchar(100)" json:"tableNamePrefix"`
|
||||
|
||||
*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 (adapter *Adapter) InitAdapter() error {
|
||||
if adapter.Adapter == nil {
|
||||
var dataSourceName string
|
||||
|
||||
// Open the DB, create it if not existed.
|
||||
a.open()
|
||||
if adapter.builtInAdapter() {
|
||||
dataSourceName = conf.GetConfigString("dataSourceName")
|
||||
if adapter.DatabaseType == "mysql" {
|
||||
dataSourceName = dataSourceName + adapter.Database
|
||||
}
|
||||
} else {
|
||||
switch adapter.DatabaseType {
|
||||
case "mssql":
|
||||
dataSourceName = fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s", adapter.User,
|
||||
adapter.Password, adapter.Host, adapter.Port, adapter.Database)
|
||||
case "mysql":
|
||||
dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", adapter.User,
|
||||
adapter.Password, adapter.Host, adapter.Port, adapter.Database)
|
||||
case "postgres":
|
||||
dataSourceName = fmt.Sprintf("user=%s password=%s host=%s port=%d 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=%d 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.Host)
|
||||
default:
|
||||
return fmt.Errorf("unsupported database type: %s", adapter.DatabaseType)
|
||||
}
|
||||
}
|
||||
|
||||
// Call the destructor when the object is released.
|
||||
runtime.SetFinalizer(a, finalizer)
|
||||
if !isCloudIntranet {
|
||||
dataSourceName = strings.ReplaceAll(dataSourceName, "dbi.", "db.")
|
||||
}
|
||||
|
||||
return a
|
||||
var err error
|
||||
engine, err := xorm.NewEngine(adapter.DatabaseType, dataSourceName)
|
||||
adapter.Adapter, err = xormadapter.NewAdapterByEngineWithTableName(engine, adapter.getTable(), adapter.TableNamePrefix)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Adapter) CreateDatabase() error {
|
||||
engine, err := xorm.NewEngine(a.driverName, a.dataSourceName)
|
||||
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
|
||||
func (adapter *Adapter) builtInAdapter() bool {
|
||||
if adapter.Owner != "built-in" {
|
||||
return false
|
||||
}
|
||||
|
||||
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))
|
||||
} else {
|
||||
session = session.Desc(util.SnakeString(sortField))
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
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
|
||||
return adapter.Name == "user-adapter-built-in" || adapter.Name == "api-adapter-built-in"
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ type Application struct {
|
||||
GrantTypes []string `xorm:"varchar(1000)" json:"grantTypes"`
|
||||
OrganizationObj *Organization `xorm:"-" json:"organizationObj"`
|
||||
Tags []string `xorm:"mediumtext" json:"tags"`
|
||||
InvitationCodes []string `xorm:"varchar(200)" json:"invitationCodes"`
|
||||
|
||||
ClientId string `xorm:"varchar(100)" json:"clientId"`
|
||||
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
|
||||
@ -92,7 +93,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 +103,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 +183,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 +207,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 +254,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 +282,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 = "***"
|
||||
}
|
||||
@ -304,6 +312,11 @@ func GetMaskedApplication(application *Application, userId string) *Application
|
||||
application.OrganizationObj.PasswordSalt = "***"
|
||||
}
|
||||
}
|
||||
|
||||
if application.InvitationCodes != nil {
|
||||
application.InvitationCodes = []string{"***"}
|
||||
}
|
||||
|
||||
return application
|
||||
}
|
||||
|
||||
@ -349,7 +362,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 +401,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 +414,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 +490,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 +520,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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
@ -162,10 +162,10 @@ func UpdateCert(id string, cert *Cert) (bool, error) {
|
||||
if name != cert.Name {
|
||||
err := certChangeTrigger(name, cert.Name)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
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()
|
||||
|
166
object/chat.go
166
object/chat.go
@ -1,166 +0,0 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/xorm-io/core"
|
||||
)
|
||||
|
||||
type Chat 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)" json:"updatedTime"`
|
||||
|
||||
Organization string `xorm:"varchar(100)" json:"organization"`
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
Type string `xorm:"varchar(100)" json:"type"`
|
||||
Category string `xorm:"varchar(100)" json:"category"`
|
||||
User1 string `xorm:"varchar(100)" json:"user1"`
|
||||
User2 string `xorm:"varchar(100)" json:"user2"`
|
||||
Users []string `xorm:"varchar(100)" json:"users"`
|
||||
MessageCount int `json:"messageCount"`
|
||||
}
|
||||
|
||||
func GetMaskedChat(chat *Chat, err ...error) (*Chat, error) {
|
||||
if len(err) > 0 && err[0] != nil {
|
||||
return nil, err[0]
|
||||
}
|
||||
|
||||
if chat == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return chat, nil
|
||||
}
|
||||
|
||||
func GetMaskedChats(chats []*Chat, errs ...error) ([]*Chat, error) {
|
||||
if len(errs) > 0 && errs[0] != nil {
|
||||
return nil, errs[0]
|
||||
}
|
||||
var err error
|
||||
for _, chat := range chats {
|
||||
chat, err = GetMaskedChat(chat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return chats, nil
|
||||
}
|
||||
|
||||
func GetChatCount(owner, field, value string) (int64, error) {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
return session.Count(&Chat{})
|
||||
}
|
||||
|
||||
func GetChats(owner string) ([]*Chat, error) {
|
||||
chats := []*Chat{}
|
||||
err := adapter.Engine.Desc("created_time").Find(&chats, &Chat{Owner: owner})
|
||||
if err != nil {
|
||||
return chats, err
|
||||
}
|
||||
|
||||
return chats, nil
|
||||
}
|
||||
|
||||
func GetPaginationChats(owner string, offset, limit int, field, value, sortField, sortOrder string) ([]*Chat, error) {
|
||||
chats := []*Chat{}
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&chats)
|
||||
if err != nil {
|
||||
return chats, err
|
||||
}
|
||||
|
||||
return chats, nil
|
||||
}
|
||||
|
||||
func getChat(owner string, name string) (*Chat, error) {
|
||||
if owner == "" || name == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
chat := Chat{Owner: owner, Name: name}
|
||||
existed, err := adapter.Engine.Get(&chat)
|
||||
if err != nil {
|
||||
return &chat, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return &chat, nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func GetChat(id string) (*Chat, error) {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
return getChat(owner, name)
|
||||
}
|
||||
|
||||
func UpdateChat(id string, chat *Chat) (bool, error) {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
if c, err := getChat(owner, name); err != nil {
|
||||
return false, err
|
||||
} else if c == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(chat)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func AddChat(chat *Chat) (bool, error) {
|
||||
if chat.Type == "AI" && chat.User2 == "" {
|
||||
provider, err := getDefaultAiProvider()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if provider != nil {
|
||||
chat.User2 = provider.Name
|
||||
}
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.Insert(chat)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteChat(chat *Chat) (bool, error) {
|
||||
affected, err := adapter.Engine.ID(core.PK{chat.Owner, chat.Name}).Delete(&Chat{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if affected != 0 {
|
||||
return DeleteChatMessages(chat.Name)
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func (p *Chat) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", p.Owner, p.Name)
|
||||
}
|
@ -124,6 +124,16 @@ func CheckUserSignup(application *Application, organization *Organization, form
|
||||
}
|
||||
}
|
||||
|
||||
if len(application.InvitationCodes) > 0 {
|
||||
if form.InvitationCode == "" {
|
||||
return i18n.Translate(lang, "check:Invitation code cannot be blank")
|
||||
} else {
|
||||
if !util.InSlice(application.InvitationCodes, form.InvitationCode) {
|
||||
return i18n.Translate(lang, "check:Invitation code is invalid")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
@ -141,7 +151,7 @@ func checkSigninErrorTimes(user *User, lang string) string {
|
||||
// reset the error times
|
||||
user.SigninWrongTimes = 0
|
||||
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times"}, user.IsGlobalAdmin)
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times"}, false)
|
||||
}
|
||||
|
||||
return ""
|
||||
@ -319,7 +329,7 @@ func CheckUserPermission(requestUserId, userId string, strict bool, lang string)
|
||||
if requestUser == nil {
|
||||
return false, fmt.Errorf(i18n.Translate(lang, "check:Session outdated, please login again"))
|
||||
}
|
||||
if requestUser.IsGlobalAdmin {
|
||||
if requestUser.IsGlobalAdmin() {
|
||||
hasPermission = true
|
||||
} else if requestUserId == userId {
|
||||
hasPermission = true
|
||||
@ -365,7 +375,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
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ func resetUserSigninErrorTimes(user *User) {
|
||||
return
|
||||
}
|
||||
user.SigninWrongTimes = 0
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, user.IsGlobalAdmin)
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, false)
|
||||
}
|
||||
|
||||
func recordSigninErrorInfo(user *User, lang string, options ...bool) string {
|
||||
@ -61,7 +61,7 @@ func recordSigninErrorInfo(user *User, lang string, options ...bool) string {
|
||||
}
|
||||
|
||||
// update user
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, user.IsGlobalAdmin)
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, false)
|
||||
leftChances := SigninWrongTimesLimit - user.SigninWrongTimes
|
||||
if leftChances == 0 && enableCaptcha {
|
||||
return fmt.Sprint(i18n.Translate(lang, "check:password or code is incorrect"))
|
||||
|
253
object/enforcer.go
Normal file
253
object/enforcer.go
Normal file
@ -0,0 +1,253 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/casbin/casbin/v2/config"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
xormadapter "github.com/casdoor/xorm-adapter/v3"
|
||||
"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"`
|
||||
|
||||
ModelCfg map[string]string `xorm:"-" json:"modelCfg"`
|
||||
*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) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", enforcer.Owner, enforcer.Name)
|
||||
}
|
||||
|
||||
func (enforcer *Enforcer) InitEnforcer() error {
|
||||
if enforcer.Enforcer != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if enforcer.Model == "" {
|
||||
return fmt.Errorf("the model for enforcer: %s should not be empty", enforcer.GetId())
|
||||
}
|
||||
if enforcer.Adapter == "" {
|
||||
return fmt.Errorf("the adapter for enforcer: %s should not be empty", enforcer.GetId())
|
||||
}
|
||||
|
||||
m, err := GetModel(enforcer.Model)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if m == nil {
|
||||
return fmt.Errorf("the model: %s for enforcer: %s is not found", enforcer.Model, enforcer.GetId())
|
||||
}
|
||||
|
||||
a, err := GetAdapter(enforcer.Adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if a == nil {
|
||||
return fmt.Errorf("the adapter: %s for enforcer: %s is not found", enforcer.Adapter, enforcer.GetId())
|
||||
}
|
||||
|
||||
err = m.initModel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = a.InitAdapter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
casbinEnforcer, err := casbin.NewEnforcer(m.Model, a.Adapter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
enforcer.Enforcer = casbinEnforcer
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetInitializedEnforcer(enforcerId string) (*Enforcer, error) {
|
||||
enforcer, err := GetEnforcer(enforcerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if enforcer == nil {
|
||||
return nil, fmt.Errorf("the enforcer: %s is not found", enforcerId)
|
||||
}
|
||||
|
||||
err = enforcer.InitEnforcer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return enforcer, nil
|
||||
}
|
||||
|
||||
func GetPolicies(id string) ([]*xormadapter.CasbinRule, error) {
|
||||
enforcer, err := GetInitializedEnforcer(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policies := util.MatrixToCasbinRules("p", enforcer.GetPolicy())
|
||||
if enforcer.GetModel()["g"] != nil {
|
||||
policies = append(policies, util.MatrixToCasbinRules("g", enforcer.GetGroupingPolicy())...)
|
||||
}
|
||||
|
||||
return policies, nil
|
||||
}
|
||||
|
||||
func UpdatePolicy(id string, oldPolicy, newPolicy []string) (bool, error) {
|
||||
enforcer, err := GetInitializedEnforcer(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return enforcer.UpdatePolicy(oldPolicy, newPolicy)
|
||||
}
|
||||
|
||||
func AddPolicy(id string, policy []string) (bool, error) {
|
||||
enforcer, err := GetInitializedEnforcer(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return enforcer.AddPolicy(policy)
|
||||
}
|
||||
|
||||
func RemovePolicy(id string, policy []string) (bool, error) {
|
||||
enforcer, err := GetInitializedEnforcer(id)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return enforcer.RemovePolicy(policy)
|
||||
}
|
||||
|
||||
func (enforcer *Enforcer) LoadModelCfg() error {
|
||||
if enforcer.ModelCfg != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
model, err := GetModel(enforcer.Model)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if model == nil {
|
||||
return fmt.Errorf("the model: %s for enforcer: %s is not found", enforcer.Model, enforcer.GetId())
|
||||
}
|
||||
|
||||
cfg, err := config.NewConfigFromText(model.ModelText)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
enforcer.ModelCfg = make(map[string]string)
|
||||
enforcer.ModelCfg["p"] = cfg.String("policy_definition::p")
|
||||
if cfg.String("role_definition::g") != "" {
|
||||
enforcer.ModelCfg["g"] = cfg.String("role_definition::g")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
140
object/get-dashboard.go
Normal file
140
object/get-dashboard.go
Normal file
@ -0,0 +1,140 @@
|
||||
// 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 (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Dashboard struct {
|
||||
OrganizationCounts []int `json:"organizationCounts"`
|
||||
UserCounts []int `json:"userCounts"`
|
||||
ProviderCounts []int `json:"providerCounts"`
|
||||
ApplicationCounts []int `json:"applicationCounts"`
|
||||
SubscriptionCounts []int `json:"subscriptionCounts"`
|
||||
}
|
||||
|
||||
func GetDashboard(owner string) (*Dashboard, error) {
|
||||
dashboard := &Dashboard{
|
||||
OrganizationCounts: make([]int, 31),
|
||||
UserCounts: make([]int, 31),
|
||||
ProviderCounts: make([]int, 31),
|
||||
ApplicationCounts: make([]int, 31),
|
||||
SubscriptionCounts: make([]int, 31),
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
organizations := []Organization{}
|
||||
users := []User{}
|
||||
providers := []Provider{}
|
||||
applications := []Application{}
|
||||
subscriptions := []Subscription{}
|
||||
|
||||
wg.Add(5)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
if err := ormer.Engine.Find(&organizations, &Organization{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&users, &User{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&providers, &Provider{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&applications, &Application{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
if err := ormer.Engine.Find(&subscriptions, &Subscription{Owner: owner}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
wg.Wait()
|
||||
|
||||
nowTime := time.Now()
|
||||
for i := 30; i >= 0; i-- {
|
||||
cutTime := nowTime.AddDate(0, 0, -i)
|
||||
dashboard.OrganizationCounts[30-i] = countCreatedBefore(organizations, cutTime)
|
||||
dashboard.UserCounts[30-i] = countCreatedBefore(users, cutTime)
|
||||
dashboard.ProviderCounts[30-i] = countCreatedBefore(providers, cutTime)
|
||||
dashboard.ApplicationCounts[30-i] = countCreatedBefore(applications, cutTime)
|
||||
dashboard.SubscriptionCounts[30-i] = countCreatedBefore(subscriptions, cutTime)
|
||||
}
|
||||
return dashboard, nil
|
||||
}
|
||||
|
||||
func countCreatedBefore(objects interface{}, before time.Time) int {
|
||||
count := 0
|
||||
switch obj := objects.(type) {
|
||||
case []Organization:
|
||||
for _, o := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", o.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []User:
|
||||
for _, u := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", u.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Provider:
|
||||
for _, p := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", p.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Application:
|
||||
for _, a := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", a.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
case []Subscription:
|
||||
for _, s := range obj {
|
||||
createdTime, _ := time.Parse("2006-01-02T15:04:05-07:00", s.CreatedTime)
|
||||
if createdTime.Before(before) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
@ -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,24 +153,24 @@ 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")
|
||||
}
|
||||
|
||||
if count, err := GetGroupUserCount(group.Name, "", ""); err != nil {
|
||||
if count, err := GetGroupUserCount(group.GetId(), "", ""); err != nil {
|
||||
return false, err
|
||||
} else if count > 0 {
|
||||
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)
|
||||
}
|
||||
@ -193,39 +214,33 @@ func ConvertToTreeData(groups []*Group, parentId string) []*Group {
|
||||
return treeData
|
||||
}
|
||||
|
||||
func RemoveUserFromGroup(owner, name, groupName string) (bool, error) {
|
||||
user, err := getUser(owner, name)
|
||||
func GetGroupUserCount(groupId string, field, value string) (int64, error) {
|
||||
owner, _ := util.GetOwnerAndNameFromId(groupId)
|
||||
names, err := userEnforcer.GetUserNamesByGroupName(groupId)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if user == nil {
|
||||
return false, errors.New("user not exist")
|
||||
return 0, err
|
||||
}
|
||||
|
||||
user.Groups = util.DeleteVal(user.Groups, groupName)
|
||||
affected, err := updateUser(user.GetId(), user, []string{"groups"})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return affected != 0, err
|
||||
}
|
||||
|
||||
func GetGroupUserCount(groupName string, field, value string) (int64, error) {
|
||||
if field == "" && value == "" {
|
||||
return adapter.Engine.Where(builder.Like{"`groups`", groupName}).
|
||||
Count(&User{})
|
||||
return int64(len(names)), nil
|
||||
} else {
|
||||
return adapter.Engine.Table("user").
|
||||
Where(builder.Like{"`groups`", groupName}).
|
||||
return ormer.Engine.Table("user").
|
||||
Where("owner = ?", owner).In("name", names).
|
||||
And(fmt.Sprintf("user.%s LIKE ?", util.CamelToSnakeCase(field)), "%"+value+"%").
|
||||
Count()
|
||||
}
|
||||
}
|
||||
|
||||
func GetPaginationGroupUsers(groupName string, offset, limit int, field, value, sortField, sortOrder string) ([]*User, error) {
|
||||
func GetPaginationGroupUsers(groupId string, offset, limit int, field, value, sortField, sortOrder string) ([]*User, error) {
|
||||
users := []*User{}
|
||||
session := adapter.Engine.Table("user").
|
||||
Where(builder.Like{"`groups`", groupName})
|
||||
owner, _ := util.GetOwnerAndNameFromId(groupId)
|
||||
names, err := userEnforcer.GetUserNamesByGroupName(groupId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
session := ormer.Engine.Table("user").
|
||||
Where("owner = ?", owner).In("name", names)
|
||||
|
||||
if offset != -1 && limit != -1 {
|
||||
session.Limit(limit, offset)
|
||||
@ -244,7 +259,7 @@ func GetPaginationGroupUsers(groupName string, offset, limit int, field, value,
|
||||
session = session.Desc(fmt.Sprintf("user.%s", util.SnakeString(sortField)))
|
||||
}
|
||||
|
||||
err := session.Find(&users)
|
||||
err = session.Find(&users)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -252,20 +267,20 @@ func GetPaginationGroupUsers(groupName string, offset, limit int, field, value,
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func GetGroupUsers(groupName string) ([]*User, error) {
|
||||
func GetGroupUsers(groupId string) ([]*User, error) {
|
||||
users := []*User{}
|
||||
err := adapter.Engine.Table("user").
|
||||
Where(builder.Like{"`groups`", groupName}).
|
||||
Find(&users)
|
||||
owner, _ := util.GetOwnerAndNameFromId(groupId)
|
||||
names, err := userEnforcer.GetUserNamesByGroupName(groupId)
|
||||
|
||||
err = ormer.Engine.Where("owner = ?", owner).In("name", names).Find(&users)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return users, nil
|
||||
}
|
||||
|
||||
func GroupChangeTrigger(oldName, newName string) error {
|
||||
session := adapter.Engine.NewSession()
|
||||
session := ormer.Engine.NewSession()
|
||||
defer session.Close()
|
||||
err := session.Begin()
|
||||
if err != nil {
|
||||
|
171
object/init.go
171
object/init.go
@ -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 {
|
||||
initBuiltInApiAdapter()
|
||||
initBuiltInApiEnforcer()
|
||||
initBuiltInUserModel()
|
||||
initBuiltInUserAdapter()
|
||||
initBuiltInUserEnforcer()
|
||||
}
|
||||
|
||||
initWebAuthn()
|
||||
}
|
||||
|
||||
@ -65,7 +73,6 @@ func getBuiltInAccountItems() []*AccountItem {
|
||||
{Name: "3rd-party logins", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
{Name: "Properties", Visible: false, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is admin", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is global admin", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is forbidden", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Is deleted", Visible: true, ViewRule: "Admin", ModifyRule: "Admin"},
|
||||
{Name: "Multi-factor authentication", Visible: true, ViewRule: "Self", ModifyRule: "Self"},
|
||||
@ -137,7 +144,6 @@ func initBuiltInUser() {
|
||||
Score: 2000,
|
||||
Ranking: 1,
|
||||
IsAdmin: true,
|
||||
IsGlobalAdmin: true,
|
||||
IsForbidden: false,
|
||||
IsDeleted: false,
|
||||
SignupApplication: "app-built-in",
|
||||
@ -295,8 +301,8 @@ func initWebAuthn() {
|
||||
gob.Register(webauthn.SessionData{})
|
||||
}
|
||||
|
||||
func initBuiltInModel() {
|
||||
model, err := GetModel("built-in/model-built-in")
|
||||
func initBuiltInUserModel() {
|
||||
model, err := GetModel("built-in/user-model-built-in")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -307,21 +313,23 @@ func initBuiltInModel() {
|
||||
|
||||
model = &Model{
|
||||
Owner: "built-in",
|
||||
Name: "model-built-in",
|
||||
Name: "user-model-built-in",
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: "Built-in Model",
|
||||
IsEnabled: true,
|
||||
ModelText: `[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
[policy_definition]
|
||||
p = sub, obj, act
|
||||
|
||||
[role_definition]
|
||||
g = _, _
|
||||
|
||||
[policy_effect]
|
||||
e = some(where (p.eft == allow))
|
||||
|
||||
[matchers]
|
||||
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act`,
|
||||
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`,
|
||||
}
|
||||
_, err = AddModel(model)
|
||||
if err != nil {
|
||||
@ -329,6 +337,51 @@ 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",
|
||||
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 +411,105 @@ func initBuiltInPermission() {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initBuiltInUserAdapter() {
|
||||
adapter, err := GetAdapter("built-in/user-adapter-built-in")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if adapter != nil {
|
||||
return
|
||||
}
|
||||
|
||||
adapter = &Adapter{
|
||||
Owner: "built-in",
|
||||
Name: "user-adapter-built-in",
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
Type: "Database",
|
||||
DatabaseType: conf.GetConfigString("driverName"),
|
||||
TableNamePrefix: conf.GetConfigString("tableNamePrefix"),
|
||||
Database: conf.GetConfigString("dbName"),
|
||||
Table: "casbin_user_rule",
|
||||
}
|
||||
_, err = AddAdapter(adapter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initBuiltInApiAdapter() {
|
||||
adapter, err := GetAdapter("built-in/api-adapter-built-in")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if adapter != nil {
|
||||
return
|
||||
}
|
||||
|
||||
adapter = &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",
|
||||
}
|
||||
_, err = AddAdapter(adapter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initBuiltInUserEnforcer() {
|
||||
enforcer, err := GetEnforcer("built-in/user-enforcer-built-in")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if enforcer != nil {
|
||||
return
|
||||
}
|
||||
|
||||
enforcer = &Enforcer{
|
||||
Owner: "built-in",
|
||||
Name: "user-enforcer-built-in",
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: "User Enforcer",
|
||||
Model: "built-in/user-model-built-in",
|
||||
Adapter: "built-in/user-adapter-built-in",
|
||||
}
|
||||
|
||||
_, err = AddEnforcer(enforcer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func initBuiltInApiEnforcer() {
|
||||
enforcer, err := GetEnforcer("built-in/api-enforcer-built-in")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if enforcer != nil {
|
||||
return
|
||||
}
|
||||
|
||||
enforcer = &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",
|
||||
}
|
||||
|
||||
_, err = AddEnforcer(enforcer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
@ -135,13 +135,19 @@ func GetMaskedLdaps(ldaps []*Ldap, errs ...error) ([]*Ldap, error) {
|
||||
}
|
||||
|
||||
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
|
||||
@ -151,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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -41,19 +41,20 @@ type LdapUser struct {
|
||||
GidNumber string `json:"gidNumber"`
|
||||
// Gcn string
|
||||
Uuid string `json:"uuid"`
|
||||
UserPrincipalName string `json:"userPrincipalName"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Mail string
|
||||
Email string `json:"email"`
|
||||
EmailAddress string
|
||||
TelephoneNumber string
|
||||
Mobile string
|
||||
Mobile string `json:"mobile"`
|
||||
MobileTelephoneNumber string
|
||||
RegisteredAddress string
|
||||
PostalAddress string
|
||||
|
||||
GroupId string `json:"groupId"`
|
||||
Phone string `json:"phone"`
|
||||
Address string `json:"address"`
|
||||
GroupId string `json:"groupId"`
|
||||
Address string `json:"address"`
|
||||
MemberOf string `json:"memberOf"`
|
||||
}
|
||||
|
||||
func (ldap *Ldap) GetLdapConn() (c *LdapConn, err error) {
|
||||
@ -168,6 +169,8 @@ func (l *LdapConn) GetLdapUsers(ldapServer *Ldap) ([]LdapUser, error) {
|
||||
user.Uuid = attribute.Values[0]
|
||||
case "objectGUID":
|
||||
user.Uuid = attribute.Values[0]
|
||||
case "userPrincipalName":
|
||||
user.UserPrincipalName = attribute.Values[0]
|
||||
case "displayName":
|
||||
user.DisplayName = attribute.Values[0]
|
||||
case "mail":
|
||||
@ -186,6 +189,8 @@ func (l *LdapConn) GetLdapUsers(ldapServer *Ldap) ([]LdapUser, error) {
|
||||
user.RegisteredAddress = attribute.Values[0]
|
||||
case "postalAddress":
|
||||
user.PostalAddress = attribute.Values[0]
|
||||
case "memberOf":
|
||||
user.MemberOf = attribute.Values[0]
|
||||
}
|
||||
}
|
||||
ldapUsers = append(ldapUsers, user)
|
||||
@ -306,18 +311,20 @@ func SyncLdapUsers(owner string, syncUsers []LdapUser, ldapId string) (existUser
|
||||
}
|
||||
|
||||
newUser := &User{
|
||||
Owner: owner,
|
||||
Name: name,
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: syncUser.buildLdapDisplayName(),
|
||||
Avatar: organization.DefaultAvatar,
|
||||
Email: syncUser.Email,
|
||||
Phone: syncUser.Phone,
|
||||
Address: []string{syncUser.Address},
|
||||
Affiliation: affiliation,
|
||||
Tag: tag,
|
||||
Score: score,
|
||||
Ldap: syncUser.Uuid,
|
||||
Owner: owner,
|
||||
Name: name,
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
DisplayName: syncUser.buildLdapDisplayName(),
|
||||
SignupApplication: organization.DefaultApplication,
|
||||
Type: "normal-user",
|
||||
Avatar: organization.DefaultAvatar,
|
||||
Email: syncUser.Email,
|
||||
Phone: syncUser.Mobile,
|
||||
Address: []string{syncUser.Address},
|
||||
Affiliation: affiliation,
|
||||
Tag: tag,
|
||||
Score: score,
|
||||
Ldap: syncUser.Uuid,
|
||||
}
|
||||
|
||||
affected, err := AddUser(newUser)
|
||||
@ -338,7 +345,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 +357,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
|
||||
}
|
||||
|
@ -1,143 +0,0 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/xorm-io/core"
|
||||
)
|
||||
|
||||
type Message 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"`
|
||||
|
||||
Organization string `xorm:"varchar(100)" json:"organization"`
|
||||
Chat string `xorm:"varchar(100) index" json:"chat"`
|
||||
ReplyTo string `xorm:"varchar(100) index" json:"replyTo"`
|
||||
Author string `xorm:"varchar(100)" json:"author"`
|
||||
Text string `xorm:"mediumtext" json:"text"`
|
||||
}
|
||||
|
||||
func GetMaskedMessage(message *Message) *Message {
|
||||
if message == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
func GetMaskedMessages(messages []*Message) []*Message {
|
||||
for _, message := range messages {
|
||||
message = GetMaskedMessage(message)
|
||||
}
|
||||
return messages
|
||||
}
|
||||
|
||||
func GetMessageCount(owner, organization, field, value string) (int64, error) {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
return session.Count(&Message{Organization: organization})
|
||||
}
|
||||
|
||||
func GetMessages(owner string) ([]*Message, error) {
|
||||
messages := []*Message{}
|
||||
err := adapter.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})
|
||||
return messages, err
|
||||
}
|
||||
|
||||
func GetPaginationMessages(owner, organization string, offset, limit int, field, value, sortField, sortOrder string) ([]*Message, error) {
|
||||
messages := []*Message{}
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&messages, &Message{Organization: organization})
|
||||
return messages, err
|
||||
}
|
||||
|
||||
func getMessage(owner string, name string) (*Message, error) {
|
||||
if owner == "" || name == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
message := Message{Owner: owner, Name: name}
|
||||
existed, err := adapter.Engine.Get(&message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existed {
|
||||
return &message, nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func GetMessage(id string) (*Message, error) {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
return getMessage(owner, name)
|
||||
}
|
||||
|
||||
func UpdateMessage(id string, message *Message) (bool, error) {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
if m, err := getMessage(owner, name); err != nil {
|
||||
return false, err
|
||||
} else if m == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(message)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func AddMessage(message *Message) (bool, error) {
|
||||
affected, err := adapter.Engine.Insert(message)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteMessage(message *Message) (bool, error) {
|
||||
affected, err := adapter.Engine.ID(core.PK{message.Owner, message.Name}).Delete(&Message{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func DeleteChatMessages(chat string) (bool, error) {
|
||||
affected, err := adapter.Engine.Delete(&Message{Chat: chat})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return affected != 0, nil
|
||||
}
|
||||
|
||||
func (p *Message) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", p.Owner, p.Name)
|
||||
}
|
@ -84,7 +84,7 @@ func MfaRecover(user *User, recoveryCode string) error {
|
||||
return fmt.Errorf("recovery code not found")
|
||||
}
|
||||
|
||||
_, err := UpdateUser(user.GetId(), user, []string{"recovery_codes"}, user.IsAdminUser())
|
||||
_, err := UpdateUser(user.GetId(), user, []string{"recovery_codes"}, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -181,7 +181,7 @@ func DisabledMultiFactorAuth(user *User) error {
|
||||
func SetPreferredMultiFactorAuth(user *User, mfaType string) error {
|
||||
user.PreferredMfaType = mfaType
|
||||
|
||||
_, err := UpdateUser(user.GetId(), user, []string{"preferred_mfa_type"}, user.IsAdminUser())
|
||||
_, err := UpdateUser(user.GetId(), user, []string{"preferred_mfa_type"}, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package object
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/beego/beego"
|
||||
"github.com/beego/beego/context"
|
||||
@ -25,7 +26,10 @@ import (
|
||||
"github.com/pquerna/otp/totp"
|
||||
)
|
||||
|
||||
const MfaTotpSecretSession = "mfa_totp_secret"
|
||||
const (
|
||||
MfaTotpSecretSession = "mfa_totp_secret"
|
||||
MfaTotpPeriodInSeconds = 30
|
||||
)
|
||||
|
||||
type TotpMfa struct {
|
||||
Config *MfaProps
|
||||
@ -76,7 +80,13 @@ func (mfa *TotpMfa) SetupVerify(ctx *context.Context, passcode string) error {
|
||||
if secret == nil {
|
||||
return errors.New("totp secret is missing")
|
||||
}
|
||||
result := totp.Validate(passcode, secret.(string))
|
||||
|
||||
result, _ := totp.ValidateCustom(passcode, secret.(string), time.Now().UTC(), totp.ValidateOpts{
|
||||
Period: MfaTotpPeriodInSeconds,
|
||||
Skew: 1,
|
||||
Digits: otp.DigitsSix,
|
||||
Algorithm: otp.AlgorithmSHA1,
|
||||
})
|
||||
|
||||
if result {
|
||||
return nil
|
||||
@ -133,7 +143,7 @@ func NewTotpMfaUtil(config *MfaProps) *TotpMfa {
|
||||
|
||||
return &TotpMfa{
|
||||
Config: config,
|
||||
period: 30,
|
||||
period: MfaTotpPeriodInSeconds,
|
||||
secretSize: 20,
|
||||
digits: otp.DigitsSix,
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -30,7 +30,8 @@ type Model struct {
|
||||
Description string `xorm:"varchar(100)" json:"description"`
|
||||
|
||||
ModelText string `xorm:"mediumtext" json:"modelText"`
|
||||
IsEnabled bool `json:"isEnabled"`
|
||||
|
||||
model.Model `xorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
func GetModelCount(owner, field, value string) (int64, error) {
|
||||
@ -40,7 +41,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 +66,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 +112,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 +121,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 +130,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 +138,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 +155,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 +171,20 @@ 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() error {
|
||||
if m.Model == nil {
|
||||
casbinModel, err := model.NewModelFromString(m.ModelText)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.Model = casbinModel
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
42
object/notification.go
Normal file
42
object/notification.go
Normal file
@ -0,0 +1,42 @@
|
||||
// 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 (
|
||||
"context"
|
||||
|
||||
"github.com/casdoor/casdoor/notification"
|
||||
"github.com/nikoksr/notify"
|
||||
)
|
||||
|
||||
func getNotificationClient(provider *Provider) (notify.Notifier, error) {
|
||||
var client notify.Notifier
|
||||
client, err := notification.GetNotificationProvider(provider.Type, provider.AppId, provider.Receiver, provider.Method, provider.Title)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func SendNotification(provider *Provider, content string) error {
|
||||
client, err := getNotificationClient(provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = client.Send(context.Background(), "", content)
|
||||
return err
|
||||
}
|
@ -103,7 +103,7 @@ func GetOidcDiscovery(host string) OidcDiscovery {
|
||||
SubjectTypesSupported: []string{"public"},
|
||||
IdTokenSigningAlgValuesSupported: []string{"RS256"},
|
||||
ScopesSupported: []string{"openid", "email", "profile", "address", "phone", "offline_access"},
|
||||
ClaimsSupported: []string{"iss", "ver", "sub", "aud", "iat", "exp", "id", "type", "displayName", "avatar", "permanentAvatar", "email", "phone", "location", "affiliation", "title", "homepage", "bio", "tag", "region", "language", "score", "ranking", "isOnline", "isAdmin", "isGlobalAdmin", "isForbidden", "signupApplication", "ldap"},
|
||||
ClaimsSupported: []string{"iss", "ver", "sub", "aud", "iat", "exp", "id", "type", "displayName", "avatar", "permanentAvatar", "email", "phone", "location", "affiliation", "title", "homepage", "bio", "tag", "region", "language", "score", "ranking", "isOnline", "isAdmin", "isForbidden", "signupApplication", "ldap"},
|
||||
RequestParameterSupported: true,
|
||||
RequestObjectSigningAlgValuesSupported: []string{"HS256", "HS384", "HS512"},
|
||||
EndSessionEndpoint: fmt.Sprintf("%s/api/logout", originBackend),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user