mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-08 00:50:28 +08:00
Compare commits
125 Commits
Author | SHA1 | Date | |
---|---|---|---|
8698f4111a | |||
fdccb8b22b | |||
19e7d0b0bd | |||
f6a502f7ff | |||
b34e16b145 | |||
11b56c340f | |||
cc6ea1b60e | |||
95b32d5ebf | |||
b47baa06e1 | |||
24a824d394 | |||
75b8357de8 | |||
087405dad2 | |||
6a6a1fa920 | |||
907d18d2e9 | |||
a728e083eb | |||
457e6208ad | |||
d10b1347a8 | |||
f5b7f8cb45 | |||
5d9b17542f | |||
0021226a60 | |||
79fc0516dd | |||
a73be11990 | |||
eddd8acbf4 | |||
d0741e3705 | |||
c66561dc9a | |||
fcdf1e8dd2 | |||
6d4f94986e | |||
9ca686b240 | |||
c93bc0dda2 | |||
7d25b9cdd8 | |||
ead844131e | |||
ce2a4bbf6e | |||
fcb80b800f | |||
6daadf8d3c | |||
090389b86a | |||
b566af8e11 | |||
57028c2059 | |||
a6e9084973 | |||
6fb3e2cd7f | |||
8b6bde6d82 | |||
fb2b03f00f | |||
1681138729 | |||
1d8b0a264e | |||
b525210835 | |||
4ab2ca7a25 | |||
dcf148fb7f | |||
c8846f1a2d | |||
0559298d6c | |||
ddb5e26fcd | |||
1f39027b78 | |||
eae3b0d367 | |||
186f0ac97b | |||
308f305c53 | |||
d498bc60ce | |||
7bbe1e38c1 | |||
f465fc6ce0 | |||
c952c2f2f4 | |||
86ae97d1e5 | |||
6ea73e3eca | |||
a71a190db5 | |||
da69d94445 | |||
b8b915abe1 | |||
5d1548e989 | |||
a0dc6e06cd | |||
ae130788ec | |||
f075d0fd74 | |||
65d4946042 | |||
26acece8af | |||
48a0c8473f | |||
082ae3c91e | |||
1ee2ff1d30 | |||
c0d9969013 | |||
1bdee13150 | |||
d668022af0 | |||
e227875c2b | |||
e473de3162 | |||
c5ef841d3f | |||
d46288b591 | |||
b968bf033c | |||
eca2527bc0 | |||
ef836acfe9 | |||
a51f0d7c08 | |||
e3c36beaf4 | |||
19dce838d1 | |||
b41d8652f0 | |||
e705eecffe | |||
2bb2c36f22 | |||
1bb3d2dea9 | |||
96566a626b | |||
042e52bd16 | |||
e207fd243b | |||
30b7fd963f | |||
ca314bbfb5 | |||
812c44e070 | |||
78e45d07cf | |||
0856977b92 | |||
a44a4b0300 | |||
4b29dd8c41 | |||
165e2e33e3 | |||
d13a307ad5 | |||
27bd771fed | |||
9f3ee275a8 | |||
fcda64ad7d | |||
d815bf92bd | |||
7867060b71 | |||
8890d1d7c7 | |||
6e6a0a074a | |||
cff3007992 | |||
fe448cbcf4 | |||
2ab25df950 | |||
b895926754 | |||
5bb7a4153f | |||
b7cd598ee8 | |||
b10fb97c92 | |||
b337b908ea | |||
ba9d1e2388 | |||
29ec1d2d9c | |||
84a03f6c8e | |||
56ff06bbea | |||
7e756b8ee2 | |||
19ba37e0c2 | |||
b98ce19211 | |||
37d1a73c0c | |||
727877cf54 | |||
939b416717 |
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -1,2 +1,5 @@
|
||||
*.go linguist-detectable=true
|
||||
*.js linguist-detectable=false
|
||||
*.js linguist-detectable=false
|
||||
# Declare files that will always have LF line endings on checkout.
|
||||
# Git will always convert line endings to LF on checkout. You should use this for files that must keep LF endings, even on Windows.
|
||||
*.sh text eol=lf
|
50
.github/workflows/build.yml
vendored
50
.github/workflows/build.yml
vendored
@ -76,11 +76,59 @@ jobs:
|
||||
version: latest
|
||||
args: --disable-all -c dummy.yml -E=gofumpt --max-same-issues=0 --timeout 5m --modules-download-mode=mod
|
||||
|
||||
e2e:
|
||||
name: e2e-test
|
||||
runs-on: ubuntu-latest
|
||||
needs: [ go-tests ]
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
env:
|
||||
MYSQL_DATABASE: casdoor
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
ports:
|
||||
- 3306:3306
|
||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16.5'
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
- name: front install
|
||||
run: yarn install
|
||||
working-directory: ./web
|
||||
- name: front start
|
||||
run: nohup yarn start &
|
||||
working-directory: ./web
|
||||
- name: back start
|
||||
run: nohup go run ./main.go &
|
||||
working-directory: ./
|
||||
- name: Sleep for starting
|
||||
run: sleep 90s
|
||||
shell: bash
|
||||
- name: e2e
|
||||
run: npx cypress run --spec "**/e2e/**.cy.js"
|
||||
working-directory: ./web
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
name: cypress-screenshots
|
||||
path: ./web/cypress/screenshots
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: cypress-videos
|
||||
path: ./web/cypress/videos
|
||||
|
||||
release-and-push:
|
||||
name: Release And Push
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'casdoor/casdoor' && github.event_name == 'push'
|
||||
needs: [ frontend, backend, linter ]
|
||||
needs: [ frontend, backend, linter, e2e ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
21
.github/workflows/sync.yml
vendored
21
.github/workflows/sync.yml
vendored
@ -33,3 +33,24 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_PROJECT_ID: '463556'
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
||||
- name: crowdin backend action
|
||||
uses: crowdin/github-action@1.4.8
|
||||
with:
|
||||
upload_translations: true
|
||||
|
||||
download_translations: true
|
||||
push_translations: true
|
||||
commit_message: 'refactor: New Crowdin Backend translations by Github Action'
|
||||
|
||||
localization_branch_name: l10n_crowdin_action
|
||||
create_pull_request: true
|
||||
pull_request_title: 'refactor: New Crowdin Backend translations'
|
||||
|
||||
crowdin_branch_name: l10n_branch
|
||||
config: './crowdin.yml'
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_PROJECT_ID: '463556'
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
@ -44,14 +44,12 @@
|
||||
|
||||
## Online demo
|
||||
|
||||
- International: https://door.casdoor.org (read-only)
|
||||
- Asian mirror: https://door.casdoor.com (read-only)
|
||||
- Asian mirror: https://demo.casdoor.com (read-write, will restore for every 5 minutes)
|
||||
- Read-only site: https://door.casdoor.com (any modification operation will fail)
|
||||
- Writable site: https://demo.casdoor.com (original data will be restored for every 5 minutes)
|
||||
|
||||
## Documentation
|
||||
|
||||
- International: https://casdoor.org
|
||||
- Asian mirror: https://casdoor.cn
|
||||
https://casdoor.org
|
||||
|
||||
## Install
|
||||
|
||||
|
@ -32,7 +32,9 @@ func InitAuthz() {
|
||||
var err error
|
||||
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
a, err := xormadapter.NewAdapterWithTableName(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName()+conf.GetConfigString("dbName"), "casbin_rule", tableNamePrefix, true)
|
||||
driverName := conf.GetConfigString("driverName")
|
||||
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
|
||||
a, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, "casbin_rule", tableNamePrefix, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -158,7 +160,7 @@ func IsAllowed(subOwner string, subName string, method string, urlPath string, o
|
||||
|
||||
func isAllowedInDemoMode(subOwner string, subName string, method string, urlPath string, objOwner string, objName string) bool {
|
||||
if method == "POST" {
|
||||
if strings.HasPrefix(urlPath, "/api/login") || urlPath == "/api/logout" || urlPath == "/api/signup" || urlPath == "/api/send-verification-code" {
|
||||
if strings.HasPrefix(urlPath, "/api/login") || urlPath == "/api/logout" || urlPath == "/api/signup" || urlPath == "/api/send-verification-code" || urlPath == "/api/send-email" {
|
||||
return true
|
||||
} else if urlPath == "/api/update-user" {
|
||||
// Allow ordinary users to update their own information
|
||||
|
@ -31,6 +31,8 @@ func GetCaptchaProvider(captchaType string) CaptchaProvider {
|
||||
return NewAliyunCaptchaProvider()
|
||||
} else if captchaType == "GEETEST" {
|
||||
return NewGEETESTCaptchaProvider()
|
||||
} else if captchaType == "Cloudflare Turnstile" {
|
||||
return NewCloudflareTurnstileProvider()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
66
captcha/turnstile.go
Normal file
66
captcha/turnstile.go
Normal file
@ -0,0 +1,66 @@
|
||||
// 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 captcha
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const CloudflareTurnstileVerifyUrl = "https://challenges.cloudflare.com/turnstile/v0/siteverify"
|
||||
|
||||
type CloudflareTurnstileProvider struct{}
|
||||
|
||||
func NewCloudflareTurnstileProvider() *CloudflareTurnstileProvider {
|
||||
captcha := &CloudflareTurnstileProvider{}
|
||||
return captcha
|
||||
}
|
||||
|
||||
func (captcha *CloudflareTurnstileProvider) VerifyCaptcha(token, clientSecret string) (bool, error) {
|
||||
reqData := url.Values{
|
||||
"secret": {clientSecret},
|
||||
"response": {token},
|
||||
}
|
||||
resp, err := http.PostForm(CloudflareTurnstileVerifyUrl, reqData)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
type captchaResponse struct {
|
||||
Success bool `json:"success"`
|
||||
ErrorCodes []string `json:"error-codes"`
|
||||
}
|
||||
captchaResp := &captchaResponse{}
|
||||
err = json.Unmarshal(body, captchaResp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if len(captchaResp.ErrorCodes) > 0 {
|
||||
return false, errors.New(strings.Join(captchaResp.ErrorCodes, ","))
|
||||
}
|
||||
|
||||
return captchaResp.Success, nil
|
||||
}
|
@ -21,3 +21,4 @@ isDemoMode = false
|
||||
batchSize = 100
|
||||
ldapServerPort = 389
|
||||
languages = en,zh,es,fr,de,ja,ko,ru
|
||||
quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
|
||||
|
35
conf/conf.go
35
conf/conf.go
@ -15,6 +15,7 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
@ -24,6 +25,15 @@ 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"}
|
||||
@ -35,6 +45,17 @@ 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 {
|
||||
@ -95,3 +116,17 @@ func GetConfigBatchSize() int {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func GetConfigQuota() *Quota {
|
||||
return quota
|
||||
}
|
||||
|
||||
func GetConfigRealDataSourceName(driverName string) string {
|
||||
var dataSourceName string
|
||||
if driverName != "mysql" {
|
||||
dataSourceName = GetConfigDataSourceName()
|
||||
} else {
|
||||
dataSourceName = GetConfigDataSourceName() + GetConfigString("dbName")
|
||||
}
|
||||
return dataSourceName
|
||||
}
|
||||
|
@ -93,3 +93,19 @@ func TestGetConfBool(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetConfigQuota(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
description string
|
||||
expected *Quota
|
||||
}{
|
||||
{"default", &Quota{-1, -1, -1, -1}},
|
||||
}
|
||||
|
||||
err := beego.LoadAppConfig("ini", "app.conf")
|
||||
assert.Nil(t, err)
|
||||
for _, scenery := range scenarios {
|
||||
quota := GetConfigQuota()
|
||||
assert.Equal(t, scenery.expected, quota)
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -102,7 +103,7 @@ type Captcha struct {
|
||||
// @router /signup [post]
|
||||
func (c *ApiController) Signup() {
|
||||
if c.GetSessionUsername() != "" {
|
||||
c.ResponseError(c.T("SignUpErr.SignOutFirst"), c.GetSessionUsername())
|
||||
c.ResponseError(c.T("account:Please sign out first before signing up"), c.GetSessionUsername())
|
||||
return
|
||||
}
|
||||
|
||||
@ -115,7 +116,7 @@ func (c *ApiController) Signup() {
|
||||
|
||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||
if !application.EnableSignUp {
|
||||
c.ResponseError(c.T("SignUpErr.DoNotAllowSignUp"))
|
||||
c.ResponseError(c.T("account:The application does not allow to sign up new account"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -129,7 +130,7 @@ func (c *ApiController) Signup() {
|
||||
if application.IsSignupItemVisible("Email") && application.GetSignupItemRule("Email") != "No verification" && form.Email != "" {
|
||||
checkResult := object.CheckVerificationCode(form.Email, form.EmailCode, c.GetAcceptLanguage())
|
||||
if len(checkResult) != 0 {
|
||||
c.ResponseError(c.T("EmailErr.EmailCheckResult"), checkResult)
|
||||
c.ResponseError(c.T("account:Email: %s"), checkResult)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -139,7 +140,7 @@ func (c *ApiController) Signup() {
|
||||
checkPhone = fmt.Sprintf("+%s%s", form.PhonePrefix, form.Phone)
|
||||
checkResult := object.CheckVerificationCode(checkPhone, form.PhoneCode, c.GetAcceptLanguage())
|
||||
if len(checkResult) != 0 {
|
||||
c.ResponseError(c.T("PhoneErr.PhoneCheckResult"), checkResult)
|
||||
c.ResponseError(c.T("account:Phone: %s"), checkResult)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -161,9 +162,9 @@ func (c *ApiController) Signup() {
|
||||
username = id
|
||||
}
|
||||
|
||||
initScore, err := getInitScore()
|
||||
initScore, err := getInitScore(organization)
|
||||
if err != nil {
|
||||
c.ResponseError(fmt.Errorf(c.T("InitErr.InitScoreFailed"), err).Error())
|
||||
c.ResponseError(fmt.Errorf(c.T("account:Get init score failed, error: %w"), err).Error())
|
||||
return
|
||||
}
|
||||
|
||||
@ -209,7 +210,7 @@ func (c *ApiController) Signup() {
|
||||
|
||||
affected := object.AddUser(user)
|
||||
if !affected {
|
||||
c.ResponseError(c.T("UserErr.InvalidInformation"), util.StructToJson(user))
|
||||
c.ResponseError(c.T("account:Invalid information"), util.StructToJson(user))
|
||||
return
|
||||
}
|
||||
|
||||
@ -238,20 +239,67 @@ func (c *ApiController) Signup() {
|
||||
// @Title Logout
|
||||
// @Tag Login API
|
||||
// @Description logout the current user
|
||||
// @Param id_token_hint query string false "id_token_hint"
|
||||
// @Param post_logout_redirect_uri query string false "post_logout_redirect_uri"
|
||||
// @Param state query string false "state"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /logout [get,post]
|
||||
func (c *ApiController) Logout() {
|
||||
user := c.GetSessionUsername()
|
||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||
|
||||
application := c.GetSessionApplication()
|
||||
c.ClearUserSession()
|
||||
// https://openid.net/specs/openid-connect-rpinitiated-1_0-final.html
|
||||
accessToken := c.Input().Get("id_token_hint")
|
||||
redirectUri := c.Input().Get("post_logout_redirect_uri")
|
||||
state := c.Input().Get("state")
|
||||
|
||||
if application == nil || application.Name == "app-built-in" || application.HomepageUrl == "" {
|
||||
c.ResponseOk(user)
|
||||
if accessToken == "" && redirectUri == "" {
|
||||
c.ClearUserSession()
|
||||
object.DeleteSessionId(user, c.Ctx.Input.CruSession.SessionID())
|
||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||
|
||||
application := c.GetSessionApplication()
|
||||
if application == nil || application.Name == "app-built-in" || application.HomepageUrl == "" {
|
||||
c.ResponseOk(user)
|
||||
return
|
||||
}
|
||||
c.ResponseOk(user, application.HomepageUrl)
|
||||
return
|
||||
} else {
|
||||
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
|
||||
}
|
||||
|
||||
affected, application, token := object.ExpireTokenByAccessToken(accessToken)
|
||||
if !affected {
|
||||
c.ResponseError(c.T("token:Token not found, invalid accessToken"))
|
||||
return
|
||||
}
|
||||
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist")), token.Application)
|
||||
return
|
||||
}
|
||||
|
||||
if application.IsRedirectUriValid(redirectUri) {
|
||||
if user == "" {
|
||||
user = util.GetId(token.Organization, token.User)
|
||||
}
|
||||
|
||||
c.ClearUserSession()
|
||||
object.DeleteSessionId(user, c.Ctx.Input.CruSession.SessionID())
|
||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||
|
||||
c.Ctx.Redirect(http.StatusFound, fmt.Sprintf("%s?state=%s", strings.TrimRight(redirectUri, "/"), state))
|
||||
} else {
|
||||
c.ResponseError(fmt.Sprintf(c.T("token:Redirect URI: %s doesn't exist in the allowed Redirect URI list"), redirectUri))
|
||||
return
|
||||
}
|
||||
}
|
||||
c.ResponseOk(user, application.HomepageUrl)
|
||||
}
|
||||
|
||||
// GetAccount
|
||||
@ -271,12 +319,17 @@ func (c *ApiController) GetAccount() {
|
||||
user = object.ExtendManagedAccountsWithUser(user)
|
||||
}
|
||||
|
||||
object.ExtendUserWithRolesAndPermissions(user)
|
||||
|
||||
user.Permissions = object.GetMaskedPermissions(user.Permissions)
|
||||
user.Roles = object.GetMaskedRoles(user.Roles)
|
||||
|
||||
organization := object.GetMaskedOrganization(object.GetOrganizationByUser(user))
|
||||
resp := Response{
|
||||
Status: "ok",
|
||||
Sub: user.Id,
|
||||
Name: user.Name,
|
||||
Data: user,
|
||||
Data: object.GetMaskedUser(user),
|
||||
Data2: organization,
|
||||
}
|
||||
c.Data["json"] = resp
|
||||
|
@ -46,7 +46,7 @@ func (c *ApiController) GetApplications() {
|
||||
if organization == "" {
|
||||
applications = object.GetApplications(owner)
|
||||
} else {
|
||||
applications = object.GetApplicationsByOrganizationName(owner, organization)
|
||||
applications = object.GetOrganizationApplications(owner, organization)
|
||||
}
|
||||
|
||||
c.Data["json"] = object.GetMaskedApplications(applications, userId)
|
||||
@ -86,7 +86,7 @@ func (c *ApiController) GetUserApplication() {
|
||||
id := c.Input().Get("id")
|
||||
user := object.GetUser(id)
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExist"), id))
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), id))
|
||||
return
|
||||
}
|
||||
|
||||
@ -103,17 +103,31 @@ func (c *ApiController) GetUserApplication() {
|
||||
// @router /get-organization-applications [get]
|
||||
func (c *ApiController) GetOrganizationApplications() {
|
||||
userId := c.GetSessionUsername()
|
||||
owner := c.Input().Get("owner")
|
||||
organization := c.Input().Get("organization")
|
||||
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 organization == "" {
|
||||
c.ResponseError(c.T("ParameterErr.OrgMissingErr"))
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": organization")
|
||||
return
|
||||
}
|
||||
|
||||
applications := object.GetApplicationsByOrganizationName(owner, organization)
|
||||
c.Data["json"] = object.GetMaskedApplications(applications, userId)
|
||||
c.ServeJSON()
|
||||
if limit == "" || page == "" {
|
||||
var applications []*object.Application
|
||||
applications = object.GetOrganizationApplications(owner, organization)
|
||||
c.Data["json"] = object.GetMaskedApplications(applications, userId)
|
||||
c.ServeJSON()
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetOrganizationApplicationCount(owner, organization, field, value)))
|
||||
applications := object.GetMaskedApplications(object.GetPaginationOrganizationApplications(owner, organization, paginator.Offset(), limit, field, value, sortField, sortOrder), userId)
|
||||
c.ResponseOk(applications, paginator.Nums())
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateApplication
|
||||
@ -153,6 +167,12 @@ func (c *ApiController) AddApplication() {
|
||||
return
|
||||
}
|
||||
|
||||
count := object.GetApplicationCount("", "", "")
|
||||
if err := checkQuotaForApplication(count); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddApplication(&application))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ func tokenToResponse(token *object.Token) *Response {
|
||||
if token.AccessToken == "" {
|
||||
return &Response{Status: "error", Msg: "fail to get accessToken", Data: token.AccessToken}
|
||||
}
|
||||
return &Response{Status: "ok", Msg: "", Data: token.AccessToken}
|
||||
return &Response{Status: "ok", Msg: "", Data: token.AccessToken, Data2: token.RefreshToken}
|
||||
}
|
||||
|
||||
// HandleLoggedIn ...
|
||||
@ -65,7 +65,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
return
|
||||
}
|
||||
if !allowed {
|
||||
c.ResponseError(c.T("AuthErr.Unauthorized"))
|
||||
c.ResponseError(c.T("auth:Unauthorized operation"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
codeChallenge := c.Input().Get("code_challenge")
|
||||
|
||||
if challengeMethod != "S256" && challengeMethod != "null" && challengeMethod != "" {
|
||||
c.ResponseError(c.T("AuthErr.ChallengeMethodErr"))
|
||||
c.ResponseError(c.T("auth:Challenge method should be S256"))
|
||||
return
|
||||
}
|
||||
code := object.GetOAuthCode(userId, clientId, responseType, redirectUri, scope, state, nonce, codeChallenge, c.Ctx.Request.Host, c.GetAcceptLanguage())
|
||||
@ -103,12 +103,12 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
resp = tokenToResponse(token)
|
||||
}
|
||||
} else if form.Type == ResponseTypeSaml { // saml flow
|
||||
res, redirectUrl, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host)
|
||||
res, redirectUrl, method, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error(), nil)
|
||||
return
|
||||
}
|
||||
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: redirectUrl}
|
||||
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: map[string]string{"redirectUrl": redirectUrl, "method": method}}
|
||||
} else if form.Type == ResponseTypeCas {
|
||||
// not oauth but CAS SSO protocol
|
||||
service := c.Input().Get("service")
|
||||
@ -139,6 +139,10 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
})
|
||||
}
|
||||
|
||||
if resp.Status == "ok" {
|
||||
object.SetSession(user.GetId(), c.Ctx.Input.CruSession.SessionID())
|
||||
}
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
@ -170,13 +174,36 @@ func (c *ApiController) GetApplicationLogin() {
|
||||
}
|
||||
|
||||
func setHttpClient(idProvider idp.IdProvider, providerType string) {
|
||||
if providerType == "GitHub" || providerType == "Google" || providerType == "Facebook" || providerType == "LinkedIn" || providerType == "Steam" {
|
||||
if isProxyProviderType(providerType) {
|
||||
idProvider.SetHttpClient(proxy.ProxyHttpClient)
|
||||
} else {
|
||||
idProvider.SetHttpClient(proxy.DefaultHttpClient)
|
||||
}
|
||||
}
|
||||
|
||||
func isProxyProviderType(providerType string) bool {
|
||||
providerTypes := []string{
|
||||
"GitHub",
|
||||
"Google",
|
||||
"Facebook",
|
||||
"LinkedIn",
|
||||
"Steam",
|
||||
"Line",
|
||||
"Amazon",
|
||||
"Instagram",
|
||||
"TikTok",
|
||||
"Twitter",
|
||||
"Uber",
|
||||
"Yahoo",
|
||||
}
|
||||
for _, v := range providerTypes {
|
||||
if strings.EqualFold(v, providerType) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Login ...
|
||||
// @Title Login
|
||||
// @Tag Login API
|
||||
@ -205,7 +232,7 @@ func (c *ApiController) Login() {
|
||||
if form.Username != "" {
|
||||
if form.Type == ResponseTypeLogin {
|
||||
if c.GetSessionUsername() != "" {
|
||||
c.ResponseError(c.T("LoginErr.SignOutFirst"), c.GetSessionUsername())
|
||||
c.ResponseError(c.T("account:Please sign out first before signing in"), c.GetSessionUsername())
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -222,27 +249,33 @@ func (c *ApiController) Login() {
|
||||
}
|
||||
|
||||
// check result through Email or Phone
|
||||
var checkDest string
|
||||
if strings.Contains(form.Username, "@") {
|
||||
verificationCodeType = "email"
|
||||
if user != nil && util.GetMaskedEmail(user.Email) == form.Username {
|
||||
form.Username = user.Email
|
||||
}
|
||||
checkResult = object.CheckVerificationCode(form.Username, form.Code, c.GetAcceptLanguage())
|
||||
checkDest = form.Username
|
||||
} else {
|
||||
verificationCodeType = "phone"
|
||||
if len(form.PhonePrefix) == 0 {
|
||||
responseText := fmt.Sprintf(c.T("PhoneErr.NoPrefix"), verificationCodeType)
|
||||
responseText := fmt.Sprintf(c.T("auth:%s No phone prefix"), verificationCodeType)
|
||||
c.ResponseError(responseText)
|
||||
return
|
||||
}
|
||||
if user != nil && util.GetMaskedPhone(user.Phone) == form.Username {
|
||||
form.Username = user.Phone
|
||||
}
|
||||
checkPhone := fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)
|
||||
checkResult = object.CheckVerificationCode(checkPhone, form.Code, c.GetAcceptLanguage())
|
||||
checkDest = fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username)
|
||||
}
|
||||
user = object.GetUserByFields(form.Organization, form.Username)
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
|
||||
return
|
||||
}
|
||||
checkResult = object.CheckSigninCode(user, checkDest, form.Code, c.GetAcceptLanguage())
|
||||
if len(checkResult) != 0 {
|
||||
responseText := fmt.Sprintf("%s%s", verificationCodeType, checkResult)
|
||||
responseText := fmt.Sprintf("%s - %s", verificationCodeType, checkResult)
|
||||
c.ResponseError(responseText)
|
||||
return
|
||||
}
|
||||
@ -253,16 +286,14 @@ func (c *ApiController) Login() {
|
||||
} else {
|
||||
object.DisableVerificationCode(fmt.Sprintf("+%s%s", form.PhonePrefix, form.Username))
|
||||
}
|
||||
|
||||
user = object.GetUserByFields(form.Organization, form.Username)
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.UserDoNotExist"), form.Organization, form.Username))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf("The application: %s does not exist", form.Application))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
||||
return
|
||||
}
|
||||
if !application.EnablePassword {
|
||||
c.ResponseError(c.T("auth:The login method: login with password is not enabled for the application"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -274,7 +305,7 @@ func (c *ApiController) Login() {
|
||||
}
|
||||
|
||||
if !isHuman {
|
||||
c.ResponseError("Turing test failed.")
|
||||
c.ResponseError(c.T("auth:Turing test failed."))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -288,7 +319,7 @@ func (c *ApiController) Login() {
|
||||
} else {
|
||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppDoNotExist"), form.Application))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
||||
return
|
||||
}
|
||||
|
||||
@ -302,15 +333,15 @@ func (c *ApiController) Login() {
|
||||
} else if form.Provider != "" {
|
||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppDoNotExist"), form.Application))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
||||
return
|
||||
}
|
||||
|
||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", application.Organization))
|
||||
provider := object.GetProvider(fmt.Sprintf("admin/%s", form.Provider))
|
||||
provider := object.GetProvider(util.GetId("admin", form.Provider))
|
||||
providerItem := application.GetProviderItem(provider.Name)
|
||||
if !providerItem.IsProviderVisible() {
|
||||
c.ResponseError(fmt.Sprintf(c.T("ProviderErr.ProviderNotEnabled"), provider.Name))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The provider: %s is not enabled for the application"), provider.Name))
|
||||
return
|
||||
}
|
||||
|
||||
@ -334,14 +365,14 @@ func (c *ApiController) Login() {
|
||||
|
||||
idProvider := idp.GetIdProvider(provider.Type, provider.SubType, clientId, clientSecret, provider.AppId, form.RedirectUri, provider.Domain, provider.CustomAuthUrl, provider.CustomTokenUrl, provider.CustomUserInfoUrl)
|
||||
if idProvider == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("ProviderErr.ProviderNotSupported"), provider.Type))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The provider type: %s is not supported"), provider.Type))
|
||||
return
|
||||
}
|
||||
|
||||
setHttpClient(idProvider, provider.Type)
|
||||
|
||||
if form.State != conf.GetConfigString("authState") && form.State != application.Name {
|
||||
c.ResponseError(fmt.Sprintf(c.T("AuthErr.AuthStateWrong"), conf.GetConfigString("authState"), form.State))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:State expected: %s, but got: %s"), conf.GetConfigString("authState"), form.State))
|
||||
return
|
||||
}
|
||||
|
||||
@ -353,13 +384,13 @@ func (c *ApiController) Login() {
|
||||
}
|
||||
|
||||
if !token.Valid() {
|
||||
c.ResponseError(c.T("TokenErr.InvalidToken"))
|
||||
c.ResponseError(c.T("auth:Invalid token"))
|
||||
return
|
||||
}
|
||||
|
||||
userInfo, err = idProvider.GetUserInfo(token)
|
||||
if err != nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.LoginFail"), err.Error()))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to login in: %s"), err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -376,7 +407,7 @@ func (c *ApiController) Login() {
|
||||
// Sign in via OAuth (want to sign up but already have account)
|
||||
|
||||
if user.IsForbidden {
|
||||
c.ResponseError(c.T("LoginErr.UserIsForbidden"))
|
||||
c.ResponseError(c.T("auth:The user is forbidden to sign in, please contact the administrator"))
|
||||
}
|
||||
|
||||
resp = c.HandleLoggedIn(application, user, &form)
|
||||
@ -388,63 +419,70 @@ func (c *ApiController) Login() {
|
||||
} else if provider.Category == "OAuth" {
|
||||
// Sign up via OAuth
|
||||
if !application.EnableSignUp {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppNotEnableSignUp"), provider.Type, userInfo.Username, userInfo.DisplayName))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth: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"), provider.Type, userInfo.Username, userInfo.DisplayName))
|
||||
return
|
||||
}
|
||||
|
||||
if !providerItem.CanSignUp {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.ProviderCanNotSignUp"), provider.Type, userInfo.Username, userInfo.DisplayName, provider.Type))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth: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"), provider.Type, userInfo.Username, userInfo.DisplayName, provider.Type))
|
||||
return
|
||||
}
|
||||
|
||||
// Handle username conflicts
|
||||
tmpUser := object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Username))
|
||||
if tmpUser != nil {
|
||||
uid, err := uuid.NewRandom()
|
||||
if application.EnableLinkWithEmail {
|
||||
// find user that has the same email
|
||||
user = object.GetUserByField(application.Organization, "email", userInfo.Email)
|
||||
}
|
||||
|
||||
if user == nil || user.IsDeleted {
|
||||
// Handle username conflicts
|
||||
tmpUser := object.GetUser(fmt.Sprintf("%s/%s", application.Organization, userInfo.Username))
|
||||
if tmpUser != nil {
|
||||
uid, err := uuid.NewRandom()
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
uidStr := strings.Split(uid.String(), "-")
|
||||
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
|
||||
}
|
||||
|
||||
properties := map[string]string{}
|
||||
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
||||
initScore, err := getInitScore(organization)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
c.ResponseError(fmt.Errorf(c.T("account:Get init score failed, error: %w"), err).Error())
|
||||
return
|
||||
}
|
||||
|
||||
uidStr := strings.Split(uid.String(), "-")
|
||||
userInfo.Username = fmt.Sprintf("%s_%s", userInfo.Username, uidStr[1])
|
||||
user = &object.User{
|
||||
Owner: application.Organization,
|
||||
Name: userInfo.Username,
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
Id: util.GenerateId(),
|
||||
Type: "normal-user",
|
||||
DisplayName: userInfo.DisplayName,
|
||||
Avatar: userInfo.AvatarUrl,
|
||||
Address: []string{},
|
||||
Email: userInfo.Email,
|
||||
Score: initScore,
|
||||
IsAdmin: false,
|
||||
IsGlobalAdmin: false,
|
||||
IsForbidden: false,
|
||||
IsDeleted: false,
|
||||
SignupApplication: application.Name,
|
||||
Properties: properties,
|
||||
}
|
||||
|
||||
affected := object.AddUser(user)
|
||||
if !affected {
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:Failed to create user, user information is invalid: %s"), util.StructToJson(user)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
properties := map[string]string{}
|
||||
properties["no"] = strconv.Itoa(len(object.GetUsers(application.Organization)) + 2)
|
||||
initScore, err := getInitScore()
|
||||
if err != nil {
|
||||
c.ResponseError(fmt.Errorf(c.T("InitErr.InitScoreFailed"), err).Error())
|
||||
return
|
||||
}
|
||||
|
||||
user = &object.User{
|
||||
Owner: application.Organization,
|
||||
Name: userInfo.Username,
|
||||
CreatedTime: util.GetCurrentTime(),
|
||||
Id: util.GenerateId(),
|
||||
Type: "normal-user",
|
||||
DisplayName: userInfo.DisplayName,
|
||||
Avatar: userInfo.AvatarUrl,
|
||||
Address: []string{},
|
||||
Email: userInfo.Email,
|
||||
Score: initScore,
|
||||
IsAdmin: false,
|
||||
IsGlobalAdmin: false,
|
||||
IsForbidden: false,
|
||||
IsDeleted: false,
|
||||
SignupApplication: application.Name,
|
||||
Properties: properties,
|
||||
}
|
||||
// sync info from 3rd-party if possible
|
||||
object.SetUserOAuthProperties(organization, user, provider.Type, userInfo)
|
||||
|
||||
affected := object.AddUser(user)
|
||||
if !affected {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.InvalidUserInformation"), util.StructToJson(user)))
|
||||
return
|
||||
}
|
||||
|
||||
object.LinkUserAccount(user, provider.Type, userInfo.Id)
|
||||
|
||||
resp = c.HandleLoggedIn(application, user, &form)
|
||||
@ -460,19 +498,19 @@ func (c *ApiController) Login() {
|
||||
record2.User = user.Name
|
||||
util.SafeGoroutine(func() { object.AddRecord(record2) })
|
||||
} else if provider.Category == "SAML" {
|
||||
resp = &Response{Status: "error", Msg: "The account does not exist"}
|
||||
resp = &Response{Status: "error", Msg: fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id))}
|
||||
}
|
||||
// resp = &Response{Status: "ok", Msg: "", Data: res}
|
||||
} else { // form.Method != "signup"
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("LoginErr.AccountDoNotExist"), userInfo)
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(application.Organization, userInfo.Id)), userInfo)
|
||||
return
|
||||
}
|
||||
|
||||
oldUser := object.GetUserByField(application.Organization, provider.Type, userInfo.Id)
|
||||
if oldUser != nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.OldUser"), provider.Type, userInfo.Username, userInfo.DisplayName, oldUser.Name, oldUser.DisplayName))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)"), provider.Type, userInfo.Username, userInfo.DisplayName, oldUser.Name, oldUser.DisplayName))
|
||||
return
|
||||
}
|
||||
|
||||
@ -493,7 +531,7 @@ func (c *ApiController) Login() {
|
||||
// user already signed in to Casdoor, so let the user click the avatar button to do the quick sign-in
|
||||
application := object.GetApplication(fmt.Sprintf("admin/%s", form.Application))
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.AppDoNotExist"), form.Application))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:The application: %s does not exist"), form.Application))
|
||||
return
|
||||
}
|
||||
|
||||
@ -505,7 +543,7 @@ func (c *ApiController) Login() {
|
||||
record.User = user.Name
|
||||
util.SafeGoroutine(func() { object.AddRecord(record) })
|
||||
} else {
|
||||
c.ResponseError(fmt.Sprintf(c.T("LoginErr.UnknownAuthentication"), util.StructToJson(form)))
|
||||
c.ResponseError(fmt.Sprintf(c.T("auth:Unknown authentication type (not password or provider), form = %s"), util.StructToJson(form)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ func (c *RootController) SamlValidate() {
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(target, service) {
|
||||
c.ResponseError(fmt.Sprintf(c.T("CasErr.ServiceDoNotMatch"), target, service))
|
||||
c.ResponseError(fmt.Sprintf(c.T("cas:Service %s and %s do not match"), target, service))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
xormadapter "github.com/casbin/xorm-adapter/v3"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
@ -31,8 +32,8 @@ func (c *ApiController) GetCasbinAdapters() {
|
||||
sortField := c.Input().Get("sortField")
|
||||
sortOrder := c.Input().Get("sortOrder")
|
||||
if limit == "" || page == "" {
|
||||
c.Data["json"] = object.GetCasbinAdapters(owner)
|
||||
c.ServeJSON()
|
||||
adapters := object.GetCasbinAdapters(owner)
|
||||
c.ResponseOk(adapters)
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetCasbinAdapterCount(owner, field, value)))
|
||||
@ -43,8 +44,8 @@ func (c *ApiController) GetCasbinAdapters() {
|
||||
|
||||
func (c *ApiController) GetCasbinAdapter() {
|
||||
id := c.Input().Get("id")
|
||||
c.Data["json"] = object.GetCasbinAdapter(id)
|
||||
c.ServeJSON()
|
||||
adapter := object.GetCasbinAdapter(id)
|
||||
c.ResponseOk(adapter)
|
||||
}
|
||||
|
||||
func (c *ApiController) UpdateCasbinAdapter() {
|
||||
@ -89,6 +90,68 @@ func (c *ApiController) SyncPolicies() {
|
||||
id := c.Input().Get("id")
|
||||
adapter := object.GetCasbinAdapter(id)
|
||||
|
||||
c.Data["json"] = object.SyncPolicies(adapter)
|
||||
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 := object.GetCasbinAdapter(id)
|
||||
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 := object.GetCasbinAdapter(id)
|
||||
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 := object.GetCasbinAdapter(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(util.CasbinToSlice(policy), adapter)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(affected)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -21,12 +21,6 @@ import (
|
||||
)
|
||||
|
||||
func (c *ApiController) Enforce() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||
return
|
||||
}
|
||||
|
||||
var permissionRule object.PermissionRule
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &permissionRule)
|
||||
if err != nil {
|
||||
@ -34,17 +28,11 @@ func (c *ApiController) Enforce() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.Enforce(userId, &permissionRule)
|
||||
c.Data["json"] = object.Enforce(&permissionRule)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) BatchEnforce() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||
return
|
||||
}
|
||||
|
||||
var permissionRules []object.PermissionRule
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &permissionRules)
|
||||
if err != nil {
|
||||
@ -52,14 +40,14 @@ func (c *ApiController) BatchEnforce() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = object.BatchEnforce(userId, permissionRules)
|
||||
c.Data["json"] = object.BatchEnforce(permissionRules)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
func (c *ApiController) GetAllObjects() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -70,7 +58,7 @@ func (c *ApiController) GetAllObjects() {
|
||||
func (c *ApiController) GetAllActions() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -81,7 +69,7 @@ func (c *ApiController) GetAllActions() {
|
||||
func (c *ApiController) GetAllRoles() {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("EnforcerErr.SignInFirst"))
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ func (c *ApiController) GetLdapUser() {
|
||||
ldapServer := LdapServer{}
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldapServer)
|
||||
if err != nil || util.IsStrsEmpty(ldapServer.Host, ldapServer.Admin, ldapServer.Passwd, ldapServer.BaseDn) {
|
||||
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ func (c *ApiController) GetLdap() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
if util.IsStrsEmpty(id) {
|
||||
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -136,17 +136,17 @@ func (c *ApiController) AddLdap() {
|
||||
var ldap object.Ldap
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldap)
|
||||
if err != nil {
|
||||
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
if util.IsStrsEmpty(ldap.Owner, ldap.ServerName, ldap.Host, ldap.Admin, ldap.Passwd, ldap.BaseDn) {
|
||||
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
if object.CheckLdapExist(&ldap) {
|
||||
c.ResponseError(c.T("LdapErr.ServerExisted"))
|
||||
c.ResponseError(c.T("ldap:Ldap server exist"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ func (c *ApiController) UpdateLdap() {
|
||||
var ldap object.Ldap
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &ldap)
|
||||
if err != nil || util.IsStrsEmpty(ldap.Owner, ldap.ServerName, ldap.Host, ldap.Admin, ldap.Passwd, ldap.BaseDn) {
|
||||
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -105,14 +105,34 @@ func handleSearch(w ldapserver.ResponseWriter, m *ldapserver.Message) {
|
||||
}
|
||||
for i := 0; i < len(users); i++ {
|
||||
user := users[i]
|
||||
dn := fmt.Sprintf("cn=%s,%s", user.DisplayName, string(r.BaseObject()))
|
||||
dn := fmt.Sprintf("cn=%s,%s", user.Name, string(r.BaseObject()))
|
||||
e := ldapserver.NewSearchResultEntry(dn)
|
||||
e.AddAttribute("cn", message.AttributeValue(user.Name))
|
||||
e.AddAttribute("uid", message.AttributeValue(user.Name))
|
||||
e.AddAttribute("email", message.AttributeValue(user.Email))
|
||||
e.AddAttribute("mobile", message.AttributeValue(user.Phone))
|
||||
e.AddAttribute("userPassword", message.AttributeValue(getUserPasswordWithType(user)))
|
||||
// e.AddAttribute("postalAddress", message.AttributeValue(user.Address[0]))
|
||||
w.Write(e)
|
||||
}
|
||||
w.Write(res)
|
||||
}
|
||||
|
||||
// get user password with hash type prefix
|
||||
// TODO not handle salt yet
|
||||
// @return {md5}5f4dcc3b5aa765d61d8327deb882cf99
|
||||
func getUserPasswordWithType(user *object.User) string {
|
||||
org := object.GetOrganizationByUser(user)
|
||||
if org.PasswordType == "" || org.PasswordType == "plain" {
|
||||
return user.Password
|
||||
}
|
||||
prefix := org.PasswordType
|
||||
if prefix == "salt" {
|
||||
prefix = "sha256"
|
||||
} else if prefix == "md5-salt" {
|
||||
prefix = "md5"
|
||||
} else if prefix == "pbkdf2-salt" {
|
||||
prefix = "pbkdf2"
|
||||
}
|
||||
return fmt.Sprintf("{%s}%s", prefix, user.Password)
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ func (c *ApiController) Unlink() {
|
||||
|
||||
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("AuthErr.CanNotUnlinkUsers"))
|
||||
c.ResponseError(c.T("link:You are not the global admin, you can't unlink other users"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -55,23 +55,23 @@ func (c *ApiController) Unlink() {
|
||||
// if the user is unlinking themselves, should check the provider can be unlinked, if not, we should return an error.
|
||||
application := object.GetApplicationByUser(user)
|
||||
if application == nil {
|
||||
c.ResponseError(c.T("AuthErr.CanNotLinkMySelf"))
|
||||
c.ResponseError(c.T("link:You can't unlink yourself, you are not a member of any application"))
|
||||
return
|
||||
}
|
||||
|
||||
if len(application.Providers) == 0 {
|
||||
c.ResponseError(c.T("ApplicationErr.HasNoProviders"))
|
||||
c.ResponseError(c.T("link:This application has no providers"))
|
||||
return
|
||||
}
|
||||
|
||||
provider := application.GetProviderItemByType(providerType)
|
||||
if provider == nil {
|
||||
c.ResponseError(c.T("ApplicationErr.HasNoProvidersOfType") + providerType)
|
||||
c.ResponseError(c.T("link:This application has no providers of type") + providerType)
|
||||
return
|
||||
}
|
||||
|
||||
if !provider.CanUnlink {
|
||||
c.ResponseError(c.T("ProviderErr.CanNotBeUnlinked"))
|
||||
c.ResponseError(c.T("link:This provider can't be unlinked"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ func (c *ApiController) Unlink() {
|
||||
value := object.GetUserField(&unlinkedUser, providerType)
|
||||
|
||||
if value == "" {
|
||||
c.ResponseError(c.T("ProviderErr.LinkFirstErr"), value)
|
||||
c.ResponseError(c.T("link:Please link first"), value)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ func (c *ApiController) UpdateModel() {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateModel(id, &model))
|
||||
c.Data["json"] = wrapErrorResponse(object.UpdateModelWithCheck(id, &model))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
|
@ -99,6 +99,12 @@ func (c *ApiController) AddOrganization() {
|
||||
return
|
||||
}
|
||||
|
||||
count := object.GetOrganizationCount("", "", "")
|
||||
if err := checkQuotaForOrganization(count); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddOrganization(&organization))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -65,6 +65,20 @@ func (c *ApiController) GetPermissionsBySubmitter() {
|
||||
return
|
||||
}
|
||||
|
||||
// GetPermissionsByRole
|
||||
// @Title GetPermissionsByRole
|
||||
// @Tag Permission API
|
||||
// @Description get permissions by role
|
||||
// @Param id query string true "The id of the role"
|
||||
// @Success 200 {array} object.Permission The Response object
|
||||
// @router /get-permissions-by-role [get]
|
||||
func (c *ApiController) GetPermissionsByRole() {
|
||||
id := c.Input().Get("id")
|
||||
permissions := object.GetPermissionsByRole(id)
|
||||
c.ResponseOk(permissions, len(permissions))
|
||||
return
|
||||
}
|
||||
|
||||
// GetPermission
|
||||
// @Title GetPermission
|
||||
// @Tag Permission API
|
||||
|
@ -141,13 +141,13 @@ func (c *ApiController) BuyProduct() {
|
||||
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
user := object.GetUser(userId)
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExist"), userId))
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), userId))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,6 @@ func (c *ApiController) GetGlobalProviders() {
|
||||
// @router /get-provider [get]
|
||||
func (c *ApiController) GetProvider() {
|
||||
id := c.Input().Get("id")
|
||||
|
||||
c.Data["json"] = object.GetMaskedProvider(object.GetProvider(id))
|
||||
c.ServeJSON()
|
||||
}
|
||||
@ -123,6 +122,12 @@ func (c *ApiController) AddProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
count := object.GetProviderCount("", "", "")
|
||||
if err := checkQuotaForProvider(count); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddProvider(&provider))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -40,6 +40,15 @@ func (c *ApiController) GetResources() {
|
||||
value := c.Input().Get("value")
|
||||
sortField := c.Input().Get("sortField")
|
||||
sortOrder := c.Input().Get("sortOrder")
|
||||
|
||||
userObj, ok := c.RequireSignedInUser()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if userObj.IsAdmin {
|
||||
user = ""
|
||||
}
|
||||
|
||||
if limit == "" || page == "" {
|
||||
c.Data["json"] = object.GetResources(owner, user)
|
||||
c.ServeJSON()
|
||||
@ -145,7 +154,7 @@ func (c *ApiController) UploadResource() {
|
||||
defer file.Close()
|
||||
|
||||
if username == "" || fullFilePath == "" {
|
||||
c.ResponseError(fmt.Sprintf(c.T("ResourceErr.UsernameOrFilePathEmpty"), username, fullFilePath))
|
||||
c.ResponseError(fmt.Sprintf(c.T("resource:Username or fullFilePath is empty: username = %s, fullFilePath = %s"), username, fullFilePath))
|
||||
return
|
||||
}
|
||||
|
||||
@ -156,7 +165,7 @@ func (c *ApiController) UploadResource() {
|
||||
return
|
||||
}
|
||||
|
||||
provider, user, ok := c.GetProviderFromContext("Storage")
|
||||
provider, _, ok := c.GetProviderFromContext("Storage")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
@ -171,6 +180,20 @@ func (c *ApiController) UploadResource() {
|
||||
fileType, _ = util.GetOwnerAndNameFromId(mimeType)
|
||||
}
|
||||
|
||||
if tag != "avatar" && tag != "termsOfUse" {
|
||||
ext := filepath.Ext(filepath.Base(fullFilePath))
|
||||
index := len(fullFilePath) - len(ext)
|
||||
for i := 1; ; i++ {
|
||||
_, objectKey := object.GetUploadFileUrl(provider, fullFilePath, true)
|
||||
if object.GetResourceCount(owner, username, "name", objectKey) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// duplicated fullFilePath found, change it
|
||||
fullFilePath = fullFilePath[:index] + fmt.Sprintf("-%d", i) + ext
|
||||
}
|
||||
}
|
||||
|
||||
fileUrl, objectKey, err := object.UploadFileSafe(provider, fullFilePath, fileBuffer)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
@ -202,12 +225,10 @@ func (c *ApiController) UploadResource() {
|
||||
|
||||
switch tag {
|
||||
case "avatar":
|
||||
user := object.GetUserNoCheck(util.GetId(owner, username))
|
||||
if user == nil {
|
||||
user = object.GetUserNoCheck(username)
|
||||
if user == nil {
|
||||
c.ResponseError(c.T("ResourceErr.UserIsNil"))
|
||||
return
|
||||
}
|
||||
c.ResponseError(c.T("resource:User is nil for tag: avatar"))
|
||||
return
|
||||
}
|
||||
|
||||
user.Avatar = fileUrl
|
||||
|
@ -25,7 +25,7 @@ func (c *ApiController) GetSamlMeta() {
|
||||
paramApp := c.Input().Get("application")
|
||||
application := object.GetApplication(paramApp)
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("ApplicationErr.AppNotFound"), paramApp))
|
||||
c.ResponseError(fmt.Sprintf(c.T("saml:Application %s not found"), paramApp))
|
||||
return
|
||||
}
|
||||
metadata, _ := object.GetSamlMeta(application, host)
|
||||
|
@ -60,7 +60,7 @@ func (c *ApiController) SendEmail() {
|
||||
var provider *object.Provider
|
||||
if emailForm.Provider != "" {
|
||||
// called by frontend's TestEmailWidget, provider name is set by frontend
|
||||
provider = object.GetProvider(fmt.Sprintf("admin/%s", emailForm.Provider))
|
||||
provider = object.GetProvider(util.GetId("admin", emailForm.Provider))
|
||||
} else {
|
||||
// called by Casdoor SDK via Client ID & Client Secret, so the used Email provider will be the application' Email provider or the default Email provider
|
||||
var ok bool
|
||||
@ -81,7 +81,7 @@ func (c *ApiController) SendEmail() {
|
||||
}
|
||||
|
||||
if util.IsStrsEmpty(emailForm.Title, emailForm.Content, emailForm.Sender) {
|
||||
c.ResponseError(fmt.Sprintf(c.T("EmailErr.EmptyParam"), emailForm))
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Empty parameters for emailForm: %v"), emailForm))
|
||||
return
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ func (c *ApiController) SendEmail() {
|
||||
}
|
||||
|
||||
if len(invalidReceivers) != 0 {
|
||||
c.ResponseError(fmt.Sprintf(c.T("EmailErr.InvalidReceivers"), invalidReceivers))
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid Email receivers: %s"), invalidReceivers))
|
||||
return
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ func (c *ApiController) SendSms() {
|
||||
}
|
||||
|
||||
if len(invalidReceivers) != 0 {
|
||||
c.ResponseError(fmt.Sprintf(c.T("PhoneErr.InvalidReceivers"), invalidReceivers))
|
||||
c.ResponseError(fmt.Sprintf(c.T("service:Invalid phone receivers: %s"), invalidReceivers))
|
||||
return
|
||||
}
|
||||
|
||||
|
68
controllers/session.go
Normal file
68
controllers/session.go
Normal file
@ -0,0 +1,68 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
// DeleteSession
|
||||
// @Title DeleteSession
|
||||
// @Tag Session API
|
||||
// @Description Delete session by userId
|
||||
// @Param ID query string true "The ID(owner/name) of user."
|
||||
// @Success 200 {array} string The Response object
|
||||
// @router /delete-session [post]
|
||||
func (c *ApiController) DeleteSession() {
|
||||
var session object.Session
|
||||
err := json.Unmarshal(c.Ctx.Input.RequestBody, &session)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteSession(util.GetId(session.Owner, session.Name)))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetSessions
|
||||
// @Title GetSessions
|
||||
// @Tag Session API
|
||||
// @Description Get organization user sessions
|
||||
// @Param owner query string true "The organization name"
|
||||
// @Success 200 {array} string The Response object
|
||||
// @router /get-sessions [get]
|
||||
func (c *ApiController) GetSessions() {
|
||||
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")
|
||||
owner := c.Input().Get("owner")
|
||||
if limit == "" || page == "" {
|
||||
c.Data["json"] = object.GetSessions(owner)
|
||||
c.ServeJSON()
|
||||
} else {
|
||||
limit := util.ParseInt(limit)
|
||||
paginator := pagination.SetPaginator(c.Ctx, limit, int64(object.GetSessionCount(owner, field, value)))
|
||||
sessions := object.GetPaginationSessions(owner, paginator.Offset(), limit, field, value, sortField, sortOrder)
|
||||
c.ResponseOk(sessions, paginator.Nums())
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ func (c *ApiController) GetSystemInfo() {
|
||||
|
||||
user := object.GetUser(id)
|
||||
if user == nil || !user.IsGlobalAdmin {
|
||||
c.ResponseError(c.T("ResourceErr.NotAuthorized"))
|
||||
c.ResponseError(c.T("auth:Unauthorized operation"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@ package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@ -150,7 +149,7 @@ func (c *ApiController) GetOAuthCode() {
|
||||
codeChallenge := c.Input().Get("code_challenge")
|
||||
|
||||
if challengeMethod != "S256" && challengeMethod != "null" && challengeMethod != "" {
|
||||
c.ResponseError(c.T("AuthErr.ChallengeMethodErr"))
|
||||
c.ResponseError(c.T("auth:Challenge method should be S256"))
|
||||
return
|
||||
}
|
||||
host := c.Ctx.Request.Host
|
||||
@ -247,28 +246,6 @@ func (c *ApiController) RefreshToken() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// TokenLogout
|
||||
// @Title TokenLogout
|
||||
// @Tag Token API
|
||||
// @Description delete token by AccessToken
|
||||
// @Param id_token_hint query string true "id_token_hint"
|
||||
// @Param post_logout_redirect_uri query string false "post_logout_redirect_uri"
|
||||
// @Param state query string true "state"
|
||||
// @Success 200 {object} controllers.Response The Response object
|
||||
// @router /login/oauth/logout [get]
|
||||
func (c *ApiController) TokenLogout() {
|
||||
token := c.Input().Get("id_token_hint")
|
||||
flag, application := object.DeleteTokenByAccessToken(token)
|
||||
redirectUri := c.Input().Get("post_logout_redirect_uri")
|
||||
state := c.Input().Get("state")
|
||||
if application != nil && object.CheckRedirectUriValid(application, redirectUri) {
|
||||
c.Ctx.Redirect(http.StatusFound, redirectUri+"?state="+state)
|
||||
return
|
||||
}
|
||||
c.Data["json"] = wrapActionResponse(flag)
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// IntrospectToken
|
||||
// @Title IntrospectToken
|
||||
// @Description The introspection endpoint is an OAuth 2.0 endpoint that takes a
|
||||
@ -290,7 +267,7 @@ func (c *ApiController) IntrospectToken() {
|
||||
clientId = c.Input().Get("client_id")
|
||||
clientSecret = c.Input().Get("client_secret")
|
||||
if clientId == "" || clientSecret == "" {
|
||||
c.ResponseError(c.T("TokenErr.EmptyClientID"))
|
||||
c.ResponseError(c.T("token:Empty clientId or clientSecret"))
|
||||
c.Data["json"] = &object.TokenError{
|
||||
Error: object.InvalidRequest,
|
||||
}
|
||||
@ -301,7 +278,7 @@ func (c *ApiController) IntrospectToken() {
|
||||
}
|
||||
application := object.GetApplicationByClientId(clientId)
|
||||
if application == nil || application.ClientSecret != clientSecret {
|
||||
c.ResponseError(c.T("TokenErr.InvalidAppOrWrongClientSecret"))
|
||||
c.ResponseError(c.T("token:Invalid application or wrong clientSecret"))
|
||||
c.Data["json"] = &object.TokenError{
|
||||
Error: object.InvalidClient,
|
||||
}
|
||||
|
@ -148,8 +148,8 @@ func (c *ApiController) UpdateUser() {
|
||||
return
|
||||
}
|
||||
|
||||
if user.DisplayName == "" {
|
||||
c.ResponseError(c.T("UserErr.DisplayNameCanNotBeEmpty"))
|
||||
if msg := object.CheckUpdateUser(object.GetUser(id), &user, c.GetAcceptLanguage()); msg != "" {
|
||||
c.ResponseError(msg)
|
||||
return
|
||||
}
|
||||
|
||||
@ -159,6 +159,12 @@ func (c *ApiController) UpdateUser() {
|
||||
}
|
||||
|
||||
isGlobalAdmin := c.IsGlobalAdmin()
|
||||
|
||||
if pass, err := checkPermissionForUpdateUser(id, user, c); !pass {
|
||||
c.ResponseError(err)
|
||||
return
|
||||
}
|
||||
|
||||
affected := object.UpdateUser(id, &user, columns, isGlobalAdmin)
|
||||
if affected {
|
||||
object.UpdateUserToOriginalDatabase(&user)
|
||||
@ -183,6 +189,12 @@ func (c *ApiController) AddUser() {
|
||||
return
|
||||
}
|
||||
|
||||
count := object.GetUserCount("", "", "")
|
||||
if err := checkQuotaForUser(count); err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
msg := object.CheckUsername(user.Name, c.GetAcceptLanguage())
|
||||
if msg != "" {
|
||||
c.ResponseError(msg)
|
||||
@ -230,7 +242,7 @@ func (c *ApiController) GetEmailAndPhone() {
|
||||
|
||||
user := object.GetUserByFields(form.Organization, form.Username)
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExistInOrg"), form.Organization, form.Username))
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(form.Organization, form.Username)))
|
||||
return
|
||||
}
|
||||
|
||||
@ -288,12 +300,12 @@ func (c *ApiController) SetPassword() {
|
||||
}
|
||||
|
||||
if strings.Contains(newPassword, " ") {
|
||||
c.ResponseError(c.T("SetPasswordErr.CanNotContainBlank"))
|
||||
c.ResponseError(c.T("user:New password cannot contain blank space."))
|
||||
return
|
||||
}
|
||||
|
||||
if len(newPassword) <= 5 {
|
||||
c.ResponseError(c.T("SetPasswordErr.LessThanSixCharacters"))
|
||||
c.ResponseError(c.T("user:New password must have at least 6 characters"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,6 @@ func (c *ApiController) UploadUsers() {
|
||||
if affected {
|
||||
c.ResponseOk()
|
||||
} else {
|
||||
c.ResponseError(c.T("UserErr.FailToImportUsers"))
|
||||
c.ResponseError(c.T("user_upload:Failed to import users"))
|
||||
}
|
||||
}
|
||||
|
135
controllers/user_util.go
Normal file
135
controllers/user_util.go
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright 2023 The Casdoor Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
)
|
||||
|
||||
func checkPermissionForUpdateUser(userId string, newUser object.User, c *ApiController) (bool, string) {
|
||||
oldUser := object.GetUser(userId)
|
||||
organization := object.GetOrganizationByUser(oldUser)
|
||||
var itemsChanged []*object.AccountItem
|
||||
|
||||
if oldUser.Owner != newUser.Owner {
|
||||
item := object.GetAccountItemByName("Organization", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Name != newUser.Name {
|
||||
item := object.GetAccountItemByName("Name", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Id != newUser.Id {
|
||||
item := object.GetAccountItemByName("ID", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.DisplayName != newUser.DisplayName {
|
||||
item := object.GetAccountItemByName("Display name", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Avatar != newUser.Avatar {
|
||||
item := object.GetAccountItemByName("Avatar", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Type != newUser.Type {
|
||||
item := object.GetAccountItemByName("User type", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
// The password is *** when not modified
|
||||
if oldUser.Password != newUser.Password && newUser.Password != "***" {
|
||||
item := object.GetAccountItemByName("Password", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Email != newUser.Email {
|
||||
item := object.GetAccountItemByName("Email", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Phone != newUser.Phone {
|
||||
item := object.GetAccountItemByName("Phone", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Region != newUser.Region {
|
||||
item := object.GetAccountItemByName("Country/Region", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Location != newUser.Location {
|
||||
item := object.GetAccountItemByName("Location", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Affiliation != newUser.Affiliation {
|
||||
item := object.GetAccountItemByName("Affiliation", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Title != newUser.Title {
|
||||
item := object.GetAccountItemByName("Title", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Homepage != newUser.Homepage {
|
||||
item := object.GetAccountItemByName("Homepage", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Bio != newUser.Bio {
|
||||
item := object.GetAccountItemByName("Bio", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.Tag != newUser.Tag {
|
||||
item := object.GetAccountItemByName("Tag", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.SignupApplication != newUser.SignupApplication {
|
||||
item := object.GetAccountItemByName("Signup application", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
|
||||
oldUserPropertiesJson, _ := json.Marshal(oldUser.Properties)
|
||||
newUserPropertiesJson, _ := json.Marshal(newUser.Properties)
|
||||
if string(oldUserPropertiesJson) != string(newUserPropertiesJson) {
|
||||
item := object.GetAccountItemByName("Properties", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
|
||||
if oldUser.IsAdmin != newUser.IsAdmin {
|
||||
item := object.GetAccountItemByName("Is admin", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.IsGlobalAdmin != newUser.IsGlobalAdmin {
|
||||
item := object.GetAccountItemByName("Is global admin", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.IsForbidden != newUser.IsForbidden {
|
||||
item := object.GetAccountItemByName("Is forbidden", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
if oldUser.IsDeleted != newUser.IsDeleted {
|
||||
item := object.GetAccountItemByName("Is deleted", organization)
|
||||
itemsChanged = append(itemsChanged, item)
|
||||
}
|
||||
|
||||
currentUser := c.getCurrentUser()
|
||||
if currentUser == nil && c.IsGlobalAdmin() {
|
||||
currentUser = &object.User{
|
||||
IsGlobalAdmin: true,
|
||||
}
|
||||
}
|
||||
|
||||
for i := range itemsChanged {
|
||||
if pass, err := object.CheckAccountItemModifyRule(itemsChanged[i], currentUser, c.GetAcceptLanguage()); !pass {
|
||||
return pass, err
|
||||
}
|
||||
}
|
||||
return true, ""
|
||||
}
|
@ -17,6 +17,7 @@ package controllers
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/i18n"
|
||||
@ -56,7 +57,7 @@ func (c *ApiController) T(error string) string {
|
||||
// GetAcceptLanguage ...
|
||||
func (c *ApiController) GetAcceptLanguage() string {
|
||||
lang := c.Ctx.Request.Header.Get("Accept-Language")
|
||||
if lang == "" {
|
||||
if lang == "" || !strings.Contains(conf.GetConfigString("languages"), lang[0:2]) {
|
||||
lang = "en"
|
||||
}
|
||||
return lang[0:2]
|
||||
@ -83,7 +84,7 @@ func (c *ApiController) SetTokenErrorHttpStatus() {
|
||||
func (c *ApiController) RequireSignedIn() (string, bool) {
|
||||
userId := c.GetSessionUsername()
|
||||
if userId == "" {
|
||||
c.ResponseError(c.T("LoginErr.LoginFirst"), "Please login first")
|
||||
c.ResponseError(c.T("general:Please login first"), "Please login first")
|
||||
return "", false
|
||||
}
|
||||
return userId, true
|
||||
@ -99,7 +100,7 @@ func (c *ApiController) RequireSignedInUser() (*object.User, bool) {
|
||||
user := object.GetUser(userId)
|
||||
if user == nil {
|
||||
c.ClearUserSession()
|
||||
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExist"), userId))
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), userId))
|
||||
return nil, false
|
||||
}
|
||||
return user, true
|
||||
@ -118,16 +119,20 @@ func (c *ApiController) RequireAdmin() (string, bool) {
|
||||
return user.Owner, true
|
||||
}
|
||||
|
||||
func getInitScore() (int, error) {
|
||||
return strconv.Atoi(conf.GetConfigString("initScore"))
|
||||
func getInitScore(organization *object.Organization) (int, error) {
|
||||
if organization != nil {
|
||||
return organization.InitScore, nil
|
||||
} else {
|
||||
return strconv.Atoi(conf.GetConfigString("initScore"))
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ApiController) GetProviderFromContext(category string) (*object.Provider, *object.User, bool) {
|
||||
providerName := c.Input().Get("provider")
|
||||
if providerName != "" {
|
||||
provider := object.GetProvider(util.GetId(providerName))
|
||||
provider := object.GetProvider(util.GetId("admin", providerName))
|
||||
if provider == nil {
|
||||
c.ResponseError(c.T("ProviderErr.ProviderNotFound"), providerName)
|
||||
c.ResponseError(c.T("util:The provider: %s is not found"), providerName)
|
||||
return nil, nil, false
|
||||
}
|
||||
return provider, nil, true
|
||||
@ -140,15 +145,59 @@ func (c *ApiController) GetProviderFromContext(category string) (*object.Provide
|
||||
|
||||
application, user := object.GetApplicationByUserId(userId)
|
||||
if application == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("ApplicationErr.AppNotFoundForUserID"), userId))
|
||||
c.ResponseError(fmt.Sprintf(c.T("util:No application is found for userId: %s"), userId))
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
provider := application.GetProviderByCategory(category)
|
||||
if provider == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("ProviderErr.ProviderNotFoundForCategory"), category, application.Name))
|
||||
c.ResponseError(fmt.Sprintf(c.T("util:No provider for category: %s is found for application: %s"), category, application.Name))
|
||||
return nil, nil, false
|
||||
}
|
||||
|
||||
return provider, user, true
|
||||
}
|
||||
|
||||
func checkQuotaForApplication(count int) error {
|
||||
quota := conf.GetConfigQuota().Application
|
||||
if quota == -1 {
|
||||
return nil
|
||||
}
|
||||
if count >= quota {
|
||||
return fmt.Errorf("application quota is exceeded")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkQuotaForOrganization(count int) error {
|
||||
quota := conf.GetConfigQuota().Organization
|
||||
if quota == -1 {
|
||||
return nil
|
||||
}
|
||||
if count >= quota {
|
||||
return fmt.Errorf("organization quota is exceeded")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkQuotaForProvider(count int) error {
|
||||
quota := conf.GetConfigQuota().Provider
|
||||
if quota == -1 {
|
||||
return nil
|
||||
}
|
||||
if count >= quota {
|
||||
return fmt.Errorf("provider quota is exceeded")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkQuotaForUser(count int) error {
|
||||
quota := conf.GetConfigQuota().User
|
||||
if quota == -1 {
|
||||
return nil
|
||||
}
|
||||
if count >= quota {
|
||||
return fmt.Errorf("user quota is exceeded")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -47,26 +47,27 @@ func (c *ApiController) SendVerificationCode() {
|
||||
checkKey := c.Ctx.Request.Form.Get("checkKey")
|
||||
checkUser := c.Ctx.Request.Form.Get("checkUser")
|
||||
applicationId := c.Ctx.Request.Form.Get("applicationId")
|
||||
method := c.Ctx.Request.Form.Get("method")
|
||||
remoteAddr := util.GetIPFromRequest(c.Ctx.Request)
|
||||
|
||||
if destType == "" {
|
||||
c.ResponseError(c.T("ParameterErr.Missing") + ": type.")
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": type.")
|
||||
return
|
||||
}
|
||||
if dest == "" {
|
||||
c.ResponseError(c.T("ParameterErr.Missing") + ": dest.")
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": dest.")
|
||||
return
|
||||
}
|
||||
if applicationId == "" {
|
||||
c.ResponseError(c.T("ParameterErr.Missing") + ": applicationId.")
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": applicationId.")
|
||||
return
|
||||
}
|
||||
if !strings.Contains(applicationId, "/") {
|
||||
c.ResponseError(c.T("ParameterErr.Wrong") + ": applicationId.")
|
||||
c.ResponseError(c.T("verification:Wrong parameter") + ": applicationId.")
|
||||
return
|
||||
}
|
||||
if checkType == "" {
|
||||
c.ResponseError(c.T("ParameterErr.Missing") + ": checkType.")
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": checkType.")
|
||||
return
|
||||
}
|
||||
|
||||
@ -74,7 +75,7 @@ func (c *ApiController) SendVerificationCode() {
|
||||
|
||||
if captchaProvider != nil {
|
||||
if checkKey == "" {
|
||||
c.ResponseError(c.T("ParameterErr.Missing") + ": checkKey.")
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": checkKey.")
|
||||
return
|
||||
}
|
||||
isHuman, err := captchaProvider.VerifyCaptcha(checkKey, checkId)
|
||||
@ -84,7 +85,7 @@ func (c *ApiController) SendVerificationCode() {
|
||||
}
|
||||
|
||||
if !isHuman {
|
||||
c.ResponseError(c.T("AuthErr.NotHuman"))
|
||||
c.ResponseError(c.T("verification:Turing test failed."))
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -92,9 +93,13 @@ func (c *ApiController) SendVerificationCode() {
|
||||
user := c.getCurrentUser()
|
||||
application := object.GetApplication(applicationId)
|
||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", application.Owner, application.Organization))
|
||||
if organization == nil {
|
||||
c.ResponseError(c.T("verification:Organization does not exist"))
|
||||
return
|
||||
}
|
||||
|
||||
if checkUser == "true" && user == nil && object.GetUserByFields(organization.Name, dest) == nil {
|
||||
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -110,7 +115,13 @@ func (c *ApiController) SendVerificationCode() {
|
||||
dest = user.Email
|
||||
}
|
||||
if !util.IsEmailValid(dest) {
|
||||
c.ResponseError(c.T("EmailErr.EmailInvalid"))
|
||||
c.ResponseError(c.T("verification:Email is invalid"))
|
||||
return
|
||||
}
|
||||
|
||||
userByEmail := object.GetUserByEmail(organization.Name, dest)
|
||||
if userByEmail == nil && method != "signup" && method != "reset" {
|
||||
c.ResponseError(c.T("verification:the user does not exist, please sign up first"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -121,11 +132,13 @@ func (c *ApiController) SendVerificationCode() {
|
||||
dest = user.Phone
|
||||
}
|
||||
if !util.IsPhoneCnValid(dest) {
|
||||
c.ResponseError(c.T("PhoneErr.NumberInvalid"))
|
||||
c.ResponseError(c.T("verification:Phone number is invalid"))
|
||||
return
|
||||
}
|
||||
if organization == nil {
|
||||
c.ResponseError(c.T("OrgErr.DoNotExist"))
|
||||
|
||||
userByPhone := object.GetUserByPhone(organization.Name, dest)
|
||||
if userByPhone == nil && method != "signup" && method != "reset" {
|
||||
c.ResponseError(c.T("verification:the user does not exist, please sign up first"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -157,16 +170,21 @@ func (c *ApiController) ResetEmailOrPhone() {
|
||||
dest := c.Ctx.Request.Form.Get("dest")
|
||||
code := c.Ctx.Request.Form.Get("code")
|
||||
if len(dest) == 0 || len(code) == 0 || len(destType) == 0 {
|
||||
c.ResponseError(c.T("ParameterErr.Missing"))
|
||||
c.ResponseError(c.T("general:Missing parameter"))
|
||||
return
|
||||
}
|
||||
|
||||
checkDest := dest
|
||||
org := object.GetOrganizationByUser(user)
|
||||
organization := object.GetOrganizationByUser(user)
|
||||
if destType == "phone" {
|
||||
phoneItem := object.GetAccountItemByName("Phone", org)
|
||||
if object.HasUserByField(user.Owner, "phone", user.Phone) {
|
||||
c.ResponseError(c.T("check:Phone already exists"))
|
||||
return
|
||||
}
|
||||
|
||||
phoneItem := object.GetAccountItemByName("Phone", organization)
|
||||
if phoneItem == nil {
|
||||
c.ResponseError(c.T("PhoneErr.UnableGetModifyRule"))
|
||||
c.ResponseError(c.T("verification:Unable to get the phone modify rule."))
|
||||
return
|
||||
}
|
||||
|
||||
@ -176,14 +194,19 @@ func (c *ApiController) ResetEmailOrPhone() {
|
||||
}
|
||||
|
||||
phonePrefix := "86"
|
||||
if org != nil && org.PhonePrefix != "" {
|
||||
phonePrefix = org.PhonePrefix
|
||||
if organization != nil && organization.PhonePrefix != "" {
|
||||
phonePrefix = organization.PhonePrefix
|
||||
}
|
||||
checkDest = fmt.Sprintf("+%s%s", phonePrefix, dest)
|
||||
} else if destType == "email" {
|
||||
emailItem := object.GetAccountItemByName("Email", org)
|
||||
if object.HasUserByField(user.Owner, "email", user.Email) {
|
||||
c.ResponseError(c.T("check:Email already exists"))
|
||||
return
|
||||
}
|
||||
|
||||
emailItem := object.GetAccountItemByName("Email", organization)
|
||||
if emailItem == nil {
|
||||
c.ResponseError(c.T("EmailErr.UnableGetModifyRule"))
|
||||
c.ResponseError(c.T("verification:Unable to get the email modify rule."))
|
||||
return
|
||||
}
|
||||
|
||||
@ -205,7 +228,7 @@ func (c *ApiController) ResetEmailOrPhone() {
|
||||
user.Phone = dest
|
||||
object.SetUserField(user, "phone", user.Phone)
|
||||
default:
|
||||
c.ResponseError(c.T("ParameterErr.UnknownType"))
|
||||
c.ResponseError(c.T("verification:Unknown type"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -224,17 +247,17 @@ func (c *ApiController) VerifyCaptcha() {
|
||||
captchaToken := c.Ctx.Request.Form.Get("captchaToken")
|
||||
clientSecret := c.Ctx.Request.Form.Get("clientSecret")
|
||||
if captchaToken == "" {
|
||||
c.ResponseError(c.T("ParameterErr.Missing") + ": captchaToken.")
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": captchaToken.")
|
||||
return
|
||||
}
|
||||
if clientSecret == "" {
|
||||
c.ResponseError(c.T("ParameterErr.Missing") + ": clientSecret.")
|
||||
c.ResponseError(c.T("general:Missing parameter") + ": clientSecret.")
|
||||
return
|
||||
}
|
||||
|
||||
provider := captcha.GetCaptchaProvider(captchaType)
|
||||
if provider == nil {
|
||||
c.ResponseError(c.T("ProviderErr.InvalidProvider"))
|
||||
c.ResponseError(c.T("verification:Invalid captcha provider."))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ func (c *ApiController) WebAuthnSignupBegin() {
|
||||
webauthnObj := object.GetWebAuthnObject(c.Ctx.Request.Host)
|
||||
user := c.getCurrentUser()
|
||||
if user == nil {
|
||||
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
|
||||
@ -66,13 +66,13 @@ func (c *ApiController) WebAuthnSignupFinish() {
|
||||
webauthnObj := object.GetWebAuthnObject(c.Ctx.Request.Host)
|
||||
user := c.getCurrentUser()
|
||||
if user == nil {
|
||||
c.ResponseError(c.T("LoginErr.LoginFirst"))
|
||||
c.ResponseError(c.T("general:Please login first"))
|
||||
return
|
||||
}
|
||||
sessionObj := c.GetSession("registration")
|
||||
sessionData, ok := sessionObj.(webauthn.SessionData)
|
||||
if !ok {
|
||||
c.ResponseError(c.T("AuthErr.CallWebAuthnSigninBegin"))
|
||||
c.ResponseError(c.T("webauthn:Please call WebAuthnSigninBegin first"))
|
||||
return
|
||||
}
|
||||
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||
@ -101,9 +101,14 @@ func (c *ApiController) WebAuthnSigninBegin() {
|
||||
userName := c.Input().Get("name")
|
||||
user := object.GetUserByFields(userOwner, userName)
|
||||
if user == nil {
|
||||
c.ResponseError(fmt.Sprintf(c.T("UserErr.DoNotExistInOrg"), userOwner, userName))
|
||||
c.ResponseError(fmt.Sprintf(c.T("general:The user: %s doesn't exist"), util.GetId(userOwner, userName)))
|
||||
return
|
||||
}
|
||||
if len(user.WebauthnCredentials) == 0 {
|
||||
c.ResponseError(c.T("webauthn:Found no credentials for this user"))
|
||||
return
|
||||
}
|
||||
|
||||
options, sessionData, err := webauthnObj.BeginLogin(user)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
@ -127,7 +132,7 @@ func (c *ApiController) WebAuthnSigninFinish() {
|
||||
sessionObj := c.GetSession("authentication")
|
||||
sessionData, ok := sessionObj.(webauthn.SessionData)
|
||||
if !ok {
|
||||
c.ResponseError(c.T("AuthErr.CallWebAuthnSigninBegin"))
|
||||
c.ResponseError(c.T("webauthn:Please call WebAuthnSigninBegin first"))
|
||||
return
|
||||
}
|
||||
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||
|
10
crowdin.yml
Normal file
10
crowdin.yml
Normal file
@ -0,0 +1,10 @@
|
||||
project_id: '491513'
|
||||
api_token_env: 'CROWDIN_PERSONAL_TOKEN'
|
||||
preserve_hierarchy: true
|
||||
files: [
|
||||
# JSON translation files
|
||||
{
|
||||
source: '/i18n/locales/en/data.json',
|
||||
translation: '/i18n/locales/%two_letters_code%/data.json',
|
||||
},
|
||||
]
|
@ -21,9 +21,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
func TestDeployStaticFiles(t *testing.T) {
|
||||
provider := object.GetProvider("admin/provider_storage_aliyun_oss")
|
||||
provider := object.GetProvider(util.GetId("admin", "provider_storage_aliyun_oss"))
|
||||
deployStaticFiles(provider)
|
||||
}
|
||||
|
19
go.mod
19
go.mod
@ -4,7 +4,6 @@ go 1.16
|
||||
|
||||
require (
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b
|
||||
github.com/Unknwon/goconfig v1.0.0
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
|
||||
github.com/aws/aws-sdk-go v1.44.4
|
||||
github.com/beego/beego v1.12.11
|
||||
@ -12,10 +11,9 @@ require (
|
||||
github.com/casbin/casbin/v2 v2.30.1
|
||||
github.com/casbin/xorm-adapter/v3 v3.0.1
|
||||
github.com/casdoor/go-sms-sender v0.5.1
|
||||
github.com/casdoor/goth v1.69.0-FIX2
|
||||
github.com/casdoor/oss v1.2.0
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc
|
||||
github.com/denisenkom/go-mssqldb v0.9.0
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
|
||||
github.com/forestmgy/ldapserver v1.1.0
|
||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
||||
@ -23,12 +21,14 @@ require (
|
||||
github.com/go-pay/gopay v1.5.72
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/lestrrat-go/jwx v0.9.0
|
||||
github.com/lestrrat-go/jwx v1.2.21
|
||||
github.com/lib/pq v1.8.0
|
||||
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3
|
||||
github.com/markbates/goth v1.75.2
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
@ -36,22 +36,23 @@ require (
|
||||
github.com/russellhaering/goxmldsig v1.1.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/tealeg/xlsx v1.0.5
|
||||
github.com/thanhpk/randstr v1.0.4
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0
|
||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84
|
||||
xorm.io/builder v0.3.12 // indirect
|
||||
xorm.io/core v0.7.2
|
||||
xorm.io/xorm v1.0.4
|
||||
xorm.io/xorm v1.1.2
|
||||
)
|
||||
|
199
go.sum
199
go.sum
@ -20,23 +20,18 @@ cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNF
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0 h1:PQcPefKFdaIzjQFbiyOgAqyx8q5djaE7x9Sqe712DPA=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
@ -50,7 +45,6 @@ github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZ
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
@ -60,36 +54,26 @@ github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzU
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw=
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||
github.com/PuerkitoBio/goquery v1.5.1 h1:PSPBGne8NIUWw+/7vFBV+kG2J/5MOjbzc7154OaKCSE=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b h1:EgJ6N2S0h1WfFIjU5/VVHWbMSVYXAluop97Qxpr/lfQ=
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b/go.mod h1:3SAoF0F5EbcOuBD5WT9nYkbIJieBS84cUQXADbXeBsU=
|
||||
github.com/Unknwon/goconfig v1.0.0 h1:9IAu/BYbSLQi8puFjUQApZTxIHqSwrj5d8vpP8vTq4A=
|
||||
github.com/Unknwon/goconfig v1.0.0/go.mod h1:wngxua9XCNjvHjDiTiV26DaKDT+0c63QR6H5hjVUUxw=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387 h1:loy0fjI90vF44BPW4ZYOkE3tDkGTy7yHURusOJimt+I=
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387/go.mod h1:GuR5j/NW7AU7tDAQUDGCtpiPxWIOy/c3kiRDnlwiCHc=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 h1:45bxf7AZMwWcqkLzDAQugVEwedisr5nRJ1r+7LYnv0U=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1075 h1:Z0SzZttfYI/raZ5O9WF3cezZJTSW4Yz4Kow9uWdyRwg=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1075/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/aws/aws-sdk-go v1.44.4 h1:ePN0CVJMdiz2vYUcJH96eyxRrtKGSDMgyhP6rah2OgE=
|
||||
github.com/aws/aws-sdk-go v1.44.4/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
@ -97,9 +81,7 @@ github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/beego/beego v1.12.11 h1:MWKcnpavb7iAIS0m6uuEq6pHKkYvGNw/5umIUKqL7jM=
|
||||
github.com/beego/beego v1.12.11/go.mod h1:QURFL1HldOcCZAxnc1cZ7wrplsYR5dKPHFjmk6WkLAs=
|
||||
github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd h1:jZtX5jh5IOMu0fpOTC3ayh6QGSPJ/KWOv1lgPvbRw1M=
|
||||
github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542 h1:nYXb+3jF6Oq/j8R/y90XrKpreCxIalBWfeyeKymgOPk=
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
|
||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||
@ -107,7 +89,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737 h1:rRISKWyXfVxvoa702s91Zl5oREZTrR3yv+tXrrX7G/g=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
|
||||
github.com/casbin/casbin v1.7.0 h1:PuzlE8w0JBg/DhIqnkF1Dewf3z+qmUZMVN07PonvVUQ=
|
||||
github.com/casbin/casbin v1.7.0/go.mod h1:c67qKN6Oum3UF5Q1+BByfFxkwKvhwW57ITjqwtzR1KE=
|
||||
@ -119,110 +100,86 @@ github.com/casbin/xorm-adapter/v3 v3.0.1 h1:0l0zkYxo6cNuIdrBZgFxlje1TRvmheYa/zIp
|
||||
github.com/casbin/xorm-adapter/v3 v3.0.1/go.mod h1:1BL7rHEDXrxO+vQdSo/ZaWKRivXl7YTos67GdMYcd20=
|
||||
github.com/casdoor/go-sms-sender v0.5.1 h1:1/Wp1OLkVAVY4lEGQhekSNetSAWhnPcxYPV7xpCZgC0=
|
||||
github.com/casdoor/go-sms-sender v0.5.1/go.mod h1:kBykbqwgRDXbXdMAIxmZKinVM1WjdqEbej5LAbUbcfI=
|
||||
github.com/casdoor/goth v1.69.0-FIX2 h1:RgfIMkL9kekylgxHHK2ZY8ASAwOGns2HVlaBwLu7Bcs=
|
||||
github.com/casdoor/goth v1.69.0-FIX2/go.mod h1:Om55nRo8CkeDkPSNBbzXW4G5uI28ZUkSk5S69dPek3s=
|
||||
github.com/casdoor/oss v1.2.0 h1:ozLAE+nnNdFQBWbzH8U9spzaO8h8NrB57lBcdyMUUQ8=
|
||||
github.com/casdoor/oss v1.2.0/go.mod h1:qii35VBuxnR/uEuYSKpS0aJ8htQFOcCVsZ4FHgHLuss=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7 h1:Puu1hUwfps3+1CUzYdAZXijuvLuRMirgiXdf3zsM2Ig=
|
||||
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20201216133707-c04035124b17 h1:1ZELwRDUvpBpmgKSIUP6VMW1jIehzD0sCdWxRyejegw=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20201216133707-c04035124b17/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
|
||||
github.com/couchbase/gomemcached v0.1.2-0.20201224031647-c432ccf49f32 h1:xnKbM9umdDcpWfEsJzVqRf5PGnIMbiZj2OmDYbleQjM=
|
||||
github.com/couchbase/gomemcached v0.1.2-0.20201224031647-c432ccf49f32/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo=
|
||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 h1:4KDlx3vjalrHD/EfsjCpV91HNX3JPaIqRtt83zZ7x+Y=
|
||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f h1:q/DpyjJjZs94bziQ7YkBmIlpqbVP7yw179rnzoNVX1M=
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f/go.mod h1:QGrK8vMWWHQYQ3QU9bw9Y9OPNfxccGzfb41qjvVeXtY=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc h1:VRRKCwnzqk8QCaRC4os14xoKDdbHqqlJtJA0oc1ZAjg=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk=
|
||||
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b h1:L63RATZFZuFMXy6ixnKmv3eNAXwYQF6HW1vd4IYsQqQ=
|
||||
github.com/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b/go.mod h1:EYSpSkwoEcryMmQGfhol2IiB3IMN9IIIaNd/wcAQMGQ=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712 h1:aaQcKT9WumO6JEJcRyTqFVq4XUZiUcKR2/GI31TOcz8=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+niDAlj5M8TK8=
|
||||
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/forestmgy/ldapserver v1.1.0 h1:gvil4nuLhqPEL8SugCkFhRyA0/lIvRdwZSqlrw63ll4=
|
||||
github.com/forestmgy/ldapserver v1.1.0/go.mod h1:1RZ8lox1QSY7rmbjdmy+sYQXY4Lp7SpGzpdE3+j3IyM=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fxamacker/cbor/v2 v2.2.0 h1:6eXqdDDe588rSYAi1HfZKbx6YYQO4mxQ9eC6xYpU/JQ=
|
||||
github.com/fxamacker/cbor/v2 v2.2.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c h1:iRTj5SRYwbvsygdwVp+y9kZT145Y1s6xOPpeOEIeGc4=
|
||||
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df h1:Bao6dhmbTA1KFVxmJ6nBoMuOJit2yjEgLJpIMYpop0E=
|
||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df/go.mod h1:GJr+FCSXshIwgHBtLglIg9M2l2kQSi6QjVAngtzI08Y=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-pay/gopay v1.5.72 h1:3zm64xMBhJBa8rXbm//q5UiGgOa4WO5XYEnU394N2Zw=
|
||||
github.com/go-pay/gopay v1.5.72/go.mod h1:0qOGIJuFW7PKDOjmecwKyW0mgsVImgwB9yPJj0ilpn8=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k=
|
||||
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
||||
github.com/go-redis/redis v6.14.2+incompatible h1:UE9pLhzmWf+xHNmZsoccjXosPicuiNaInPgym8nzfg0=
|
||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
|
||||
github.com/goccy/go-json v0.9.6 h1:5/4CtRQdtsX0sal8fdVhTaiMN01Ri8BExZZ8iRmHQ6E=
|
||||
github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d h1:lBXNCxVENCipq4D1Is42JVOP4eQjlB8TQ6H69Yx5J9Q=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
@ -231,11 +188,9 @@ github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
@ -262,12 +217,12 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/certificate-transparency-go v1.0.21 h1:Yf1aXowfZ2nuboBsg7iYGLmwsOARdV86pfH3g95wXmE=
|
||||
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
|
||||
@ -279,13 +234,11 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
@ -294,17 +247,13 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7 h1:k+KkMRk8mGOu1xG38StS7dQ+Z6oW1i9n3dgrAVU9Q/E=
|
||||
github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
@ -312,9 +261,7 @@ github.com/gorilla/mux v1.6.2 h1:Pgr17XVTNXAk3q/r4CpKzC5xBM/qW1uVLV+IhRZpIIk=
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5oVvhMjDyLhmA1LG86oSo+IqY=
|
||||
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
|
||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/sessions v1.1.1 h1:YMDmfaK68mUixINzY/XjscuJ47uXFWSSHzFbBQM0PrE=
|
||||
github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
@ -322,9 +269,7 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da h1:FjHUJJ7oBW4G/9j1KzlHaXL09LyMVM9rupS39lncbXk=
|
||||
github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4=
|
||||
github.com/jinzhu/configor v1.2.1 h1:OKk9dsR8i6HPOCZR8BcMtcEImAFjIhbJFZNyn5GCZko=
|
||||
github.com/jinzhu/configor v1.2.1/go.mod h1:nX89/MOmDba7ZX7GCyU/VIaQ2Ar2aizBl2d3JLF/rDc=
|
||||
@ -338,39 +283,43 @@ github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9q
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
|
||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6 h1:wxyqOzKxsRJ6vVRL9sXQ64Z45wmBuQ+OTH9sLsC5rKc=
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lestrrat-go/jwx v0.9.0 h1:Fnd0EWzTm0kFrBPzE/PEPp9nzllES5buMkksPMjEKpM=
|
||||
github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk=
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
|
||||
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
|
||||
github.com/lestrrat-go/blackmagic v1.0.0 h1:XzdxDbuQTz0RZZEmdU7cnQxUtFUzgCSPq8RCz4BxIi4=
|
||||
github.com/lestrrat-go/blackmagic v1.0.0/go.mod h1:TNgH//0vYSs8VXDCfkZLgIrVTTXQELZffUV0tz3MtdQ=
|
||||
github.com/lestrrat-go/httpcc v1.0.0 h1:FszVC6cKfDvBKcJv646+lkh4GydQg2Z29scgUfkOpYc=
|
||||
github.com/lestrrat-go/httpcc v1.0.0/go.mod h1:tGS/u00Vh5N6FHNkExqGGNId8e0Big+++0Gf8MBnAvE=
|
||||
github.com/lestrrat-go/iter v1.0.1 h1:q8faalr2dY6o8bV45uwrxq12bRa1ezKrB6oM9FUgN4A=
|
||||
github.com/lestrrat-go/iter v1.0.1/go.mod h1:zIdgO1mRKhn8l9vrZJZz9TUMMFbQbLeTsbqPDrJ/OJc=
|
||||
github.com/lestrrat-go/jwx v1.2.21 h1:n+yG95UMm5ZFsDdvsZmui+bqat4Cj/di4ys6XbgSlE8=
|
||||
github.com/lestrrat-go/jwx v1.2.21/go.mod h1:9cfxnOH7G1gN75CaJP2hKGcxFEx5sPh1abRIA/ZJVh4=
|
||||
github.com/lestrrat-go/option v1.0.0 h1:WqAWL8kh8VcSoD6xjSH34/1m8yxluXQbDeKNfvFeEO4=
|
||||
github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||
@ -379,12 +328,17 @@ github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3 h1:wIONC+HMNRqmWBjuM
|
||||
github.com/lor00x/goldap v0.0.0-20180618054307-a546dffdd1a3/go.mod h1:37YR9jabpiIxsb8X9VCIx8qFOjTDIIrIHHODa8C4gz0=
|
||||
github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0=
|
||||
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
|
||||
github.com/markbates/goth v1.75.2 h1:C7KloBMMk50JyXaHhzfqWYLW6+bDcSVIvUGHXneLWro=
|
||||
github.com/markbates/goth v1.75.2/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911 h1:erppMjjp69Rertg1zlgRbLJH1u+eCmRPxKjMZ5I8/Ro=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
|
||||
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
|
||||
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
@ -399,9 +353,7 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c h1:3wkDRdxK92dF+c1ke2dtj7ZzemFWBHB9plnJOtlwdFA=
|
||||
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223 h1:F9x/1yl3T2AeKLr2AMdilSD8+f9bvMnNN8VS5iDtovc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d h1:VhgPp6v9qf9Agr/56bj7Y/xa04UccTW04VP0Qed4vnQ=
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d/go.mod h1:YUTz3bUH2ZwIWBy3CJBeOBEugqcmXREj14T+iG/4k4U=
|
||||
@ -412,11 +364,8 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/pelletier/go-toml v1.0.1 h1:0nx4vKBl23+hEaCOV1mFhKS9vhhBtFYWC7rQY0vJAyE=
|
||||
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233 h1:jmJndGFBPjNWW+MAYarU/Nl8QrQVzbw4B/AYE0LzETo=
|
||||
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -442,12 +391,11 @@ github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFB
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0 h1:q0y8TPa/sTwtriJPRe8gWL++PuZ+XbOUuvKU+hvtTYs=
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0/go.mod h1:PElPB7b7HnGKTsuADAffFpOQXHqjEGJz1+U1a6yR5wA=
|
||||
github.com/qiniu/dyn v1.3.0 h1:s+xPTeV0H8yikgM4ZMBc7Rrefam8UNI3asBlkaOQg5o=
|
||||
github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
|
||||
github.com/qiniu/go-sdk/v7 v7.12.1 h1:FZG5dhs2MZBV/mHVhmHnsgsQ+j1gSE0RqIoA2WwEDwY=
|
||||
github.com/qiniu/go-sdk/v7 v7.12.1/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w=
|
||||
github.com/qiniu/x v1.10.5 h1:7V/CYWEmo9axJULvrJN6sMYh2FdY+esN5h8jwDkA4b0=
|
||||
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@ -465,27 +413,18 @@ github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI
|
||||
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0 h1:QIF48X1cihydXibm+4wfAc0r/qyPyuFiPFRNphdMpEE=
|
||||
github.com/siddontang/go v0.0.0-20170517070808-cb568a3e5cc0/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400 h1:091wFNQB3PXcL5+me0joH7EiyqQaI0wGMpEjVCkK04U=
|
||||
github.com/siddontang/goredis v0.0.0-20150324035039-760763f78400/go.mod h1:DDcKzU3qCuvj/tPnimWSsZZzvk9qvkvrIL5naVBPh5s=
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d h1:NVwnfyR3rENtlz62bcrkXME3INVUa4lcdGt+opvxExs=
|
||||
github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec h1:q6XVwXmKvCRHRqesF3cSv6lNqqHi0QWOvgDlSohg8UA=
|
||||
github.com/ssdb/gossdb v0.0.0-20180723034631-88f6b59b84ec/go.mod h1:QBvMkMya+gXctz3kmljlUCu/yB3GZ6oee+dUozsezQE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
@ -511,11 +450,9 @@ github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/twilio/twilio-go v0.26.0 h1:wFW4oTe3/LKt6bvByP7eio8JsjtaLHjMQKOUEzQry7U=
|
||||
github.com/twilio/twilio-go v0.26.0/go.mod h1:lz62Hopu4vicpQ056H5TJ0JE4AP0rS3sQ35/ejmgOwE=
|
||||
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83 h1:9AUN7+NK4IV+A11igqjQM5i8obiOAQo4SXgjaxe+orI=
|
||||
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.19 h1:jJp+aJgK0e//rZ9I0K2Y7ufJwvuZRo/AQsYDynXMNgA=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.19/go.mod h1:+GGi447k4p1I5PNdbpG2GLaF0Ui9vIInTojMM0IfSS4=
|
||||
github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec h1:bua919NvciYmjqfeZMsVkXTny1QvXMrri0X6NlqILRs=
|
||||
github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
@ -523,19 +460,15 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973 h1:iCnkJ/qjKZGdZnlcj1N55AxPDan814kpc3s1cDpQKd8=
|
||||
github.com/yuin/gopher-lua v0.0.0-20171031051903-609c9cd26973/go.mod h1:aEV29XrmTYFr3CiRxZeGHpkvbwq+prZduBqMaascyCU=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@ -552,8 +485,9 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 h1:BkypuErRT9A9I/iljuaG3/zdMjd/J6m8tKKJQtGfSdA=
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -563,10 +497,8 @@ golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@ -577,10 +509,8 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
@ -622,7 +552,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
@ -645,8 +575,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -670,6 +600,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -684,7 +615,10 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -697,7 +631,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbuf
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -755,6 +688,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -778,7 +712,6 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.32.0 h1:Le77IccnTqEa8ryp9wIpX5W3zYm7Gf9LhOp9PHcwFts=
|
||||
google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@ -818,7 +751,6 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200929141702-51c3e5b607fe h1:6SgESkjJknFUnsfQ2yxQbmTAi37BxhwS/riq+VdLo9c=
|
||||
google.golang.org/genproto v0.0.0-20200929141702-51c3e5b607fe/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
@ -833,7 +765,6 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0=
|
||||
google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@ -846,7 +777,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
@ -856,7 +786,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
@ -865,7 +794,6 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkp
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
@ -888,18 +816,43 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009 h1:u0oCo5b9wyLr++HF3AN9JicGhkUxJhMz51+8TIZH9N0=
|
||||
modernc.org/cc/v3 v3.31.5-0.20210308123301-7a3e9dab9009/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
|
||||
modernc.org/ccgo/v3 v3.9.0 h1:JbcEIqjw4Agf+0g3Tc85YvfYqkkFOv6xBwS4zkfqSoA=
|
||||
modernc.org/ccgo/v3 v3.9.0/go.mod h1:nQbgkn8mwzPdp4mm6BT6+p85ugQ7FrGgIcYaE7nSrpY=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.8.0 h1:Pp4uv9g0csgBMpGPABKtkieF6O5MGhfGo6ZiOdlYfR8=
|
||||
modernc.org/libc v1.8.0/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84 h1:rgEUzE849tFlHSoeCrKyS9cZAljC+DY7MdMHKq6R6sY=
|
||||
modernc.org/sqlite v1.10.1-0.20210314190707-798bbeb9bb84/go.mod h1:PGzq6qlhyYjL6uVbSgS6WoF7ZopTW/sI7+7p+mb4ZVU=
|
||||
modernc.org/strutil v1.1.0 h1:+1/yCzZxY2pZwwrsbH+4T7BQMoLQ9QiBshRC9eicYsc=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/tcl v1.5.0 h1:euZSUNfE0Fd4W8VqXI1Ly1v7fqDJoBuAV88Ea+SnaSs=
|
||||
modernc.org/tcl v1.5.0/go.mod h1:gb57hj4pO8fRrK54zveIfFXBaMHK3SKJNWcmRw1cRzc=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc=
|
||||
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
xorm.io/builder v0.3.7 h1:2pETdKRK+2QG4mLX4oODHEhn5Z8j1m8sXa7jfu+/SZI=
|
||||
xorm.io/builder v0.3.7/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.8/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/builder v0.3.12 h1:ASZYX7fQmy+o8UJdhlLHSW57JDOkM8DNhcAF5d0LiJM=
|
||||
xorm.io/builder v0.3.12/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
|
||||
xorm.io/core v0.7.2 h1:mEO22A2Z7a3fPaZMk6gKL/jMD80iiyNwRrX5HOv3XLw=
|
||||
xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
|
||||
xorm.io/xorm v1.0.3/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
||||
xorm.io/xorm v1.0.4 h1:UBXA4I3NhiyjXfPqxXUkS2t5hMta9SSPATeMMaZg9oA=
|
||||
xorm.io/xorm v1.0.4/go.mod h1:uF9EtbhODq5kNWxMbnBEj8hRRZnlcNSz2t2N7HW/+A4=
|
||||
xorm.io/xorm v1.1.2 h1:bje+1KZvK3m5AHtZNfUDlKEEyuw/IRHT+an0CLIG5TU=
|
||||
xorm.io/xorm v1.1.2/go.mod h1:Cb0DKYTHbyECMaSfgRnIZp5aiUgQozxcJJ0vzcLGJSg=
|
||||
|
@ -26,16 +26,22 @@ import (
|
||||
|
||||
type I18nData map[string]map[string]string
|
||||
|
||||
var reI18n *regexp.Regexp
|
||||
var (
|
||||
reI18nFrontend *regexp.Regexp
|
||||
reI18nBackendObject *regexp.Regexp
|
||||
reI18nBackendController *regexp.Regexp
|
||||
)
|
||||
|
||||
func init() {
|
||||
reI18n, _ = regexp.Compile("i18next.t\\(\"(.*?)\"\\)")
|
||||
reI18nFrontend, _ = regexp.Compile("i18next.t\\(\"(.*?)\"\\)")
|
||||
reI18nBackendObject, _ = regexp.Compile("i18n.Translate\\((.*?)\"\\)")
|
||||
reI18nBackendController, _ = regexp.Compile("c.T\\((.*?)\"\\)")
|
||||
}
|
||||
|
||||
func getAllI18nStrings(fileContent string) []string {
|
||||
func getAllI18nStringsFrontend(fileContent string) []string {
|
||||
res := []string{}
|
||||
|
||||
matches := reI18n.FindAllStringSubmatch(fileContent, -1)
|
||||
matches := reI18nFrontend.FindAllStringSubmatch(fileContent, -1)
|
||||
if matches == nil {
|
||||
return res
|
||||
}
|
||||
@ -46,17 +52,39 @@ func getAllI18nStrings(fileContent string) []string {
|
||||
return res
|
||||
}
|
||||
|
||||
func getAllJsFilePaths() []string {
|
||||
path := "../web/src"
|
||||
|
||||
func getAllI18nStringsBackend(fileContent string, isObjectPackage bool) []string {
|
||||
res := []string{}
|
||||
err := filepath.Walk(path,
|
||||
if isObjectPackage {
|
||||
matches := reI18nBackendObject.FindAllStringSubmatch(fileContent, -1)
|
||||
if matches == nil {
|
||||
return res
|
||||
}
|
||||
for _, match := range matches {
|
||||
match := strings.SplitN(match[1], ",", 2)
|
||||
res = append(res, match[1][2:])
|
||||
}
|
||||
} else {
|
||||
matches := reI18nBackendController.FindAllStringSubmatch(fileContent, -1)
|
||||
if matches == nil {
|
||||
return res
|
||||
}
|
||||
for _, match := range matches {
|
||||
res = append(res, match[1][1:])
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func getAllFilePathsInFolder(folder string, fileSuffix string) []string {
|
||||
res := []string{}
|
||||
err := filepath.Walk(folder,
|
||||
func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(info.Name(), ".js") {
|
||||
if !strings.HasSuffix(info.Name(), fileSuffix) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -71,19 +99,32 @@ func getAllJsFilePaths() []string {
|
||||
return res
|
||||
}
|
||||
|
||||
func parseToData() *I18nData {
|
||||
func parseEnData(category string) *I18nData {
|
||||
var paths []string
|
||||
if category == "backend" {
|
||||
paths = getAllFilePathsInFolder("../", ".go")
|
||||
} else {
|
||||
paths = getAllFilePathsInFolder("../web/src", ".js")
|
||||
}
|
||||
|
||||
allWords := []string{}
|
||||
paths := getAllJsFilePaths()
|
||||
for _, path := range paths {
|
||||
fileContent := util.ReadStringFromPath(path)
|
||||
words := getAllI18nStrings(fileContent)
|
||||
|
||||
var words []string
|
||||
if category == "backend" {
|
||||
isObjectPackage := strings.Contains(path, "object")
|
||||
words = getAllI18nStringsBackend(fileContent, isObjectPackage)
|
||||
} else {
|
||||
words = getAllI18nStringsFrontend(fileContent)
|
||||
}
|
||||
allWords = append(allWords, words...)
|
||||
}
|
||||
fmt.Printf("%v\n", allWords)
|
||||
|
||||
data := I18nData{}
|
||||
for _, word := range allWords {
|
||||
tokens := strings.Split(word, ":")
|
||||
tokens := strings.SplitN(word, ":", 2)
|
||||
namespace := tokens[0]
|
||||
key := tokens[1]
|
||||
|
||||
|
@ -1,122 +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 i18n
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/Unknwon/goconfig"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
var (
|
||||
reI18nBackendObject *regexp.Regexp
|
||||
re18nBackendController *regexp.Regexp
|
||||
)
|
||||
|
||||
func init() {
|
||||
reI18nBackendObject, _ = regexp.Compile("i18n.Translate\\((.*?)\"\\)")
|
||||
re18nBackendController, _ = regexp.Compile("c.T\\((.*?)\"\\)")
|
||||
}
|
||||
|
||||
func GetAllI18nStrings(fileContent string, path string) []string {
|
||||
res := []string{}
|
||||
if strings.Contains(path, "object") {
|
||||
matches := reI18nBackendObject.FindAllStringSubmatch(fileContent, -1)
|
||||
if matches == nil {
|
||||
return res
|
||||
}
|
||||
for _, match := range matches {
|
||||
match := strings.Split(match[1], ",")
|
||||
res = append(res, match[1][2:])
|
||||
}
|
||||
} else {
|
||||
matches := re18nBackendController.FindAllStringSubmatch(fileContent, -1)
|
||||
if matches == nil {
|
||||
return res
|
||||
}
|
||||
for _, match := range matches {
|
||||
res = append(res, match[1][1:])
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func getAllGoFilePaths() []string {
|
||||
path := "../"
|
||||
|
||||
res := []string{}
|
||||
err := filepath.Walk(path,
|
||||
func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(info.Name(), ".go") {
|
||||
return nil
|
||||
}
|
||||
|
||||
res = append(res, path)
|
||||
// fmt.Println(path, info.Name())
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func getErrName(paths []string) map[string]bool {
|
||||
ErrName := make(map[string]bool)
|
||||
for i := 0; i < len(paths); i++ {
|
||||
content := util.ReadStringFromPath(paths[i])
|
||||
words := GetAllI18nStrings(content, paths[i])
|
||||
for i := 0; i < len(words); i++ {
|
||||
ErrName[words[i]] = true
|
||||
}
|
||||
}
|
||||
return ErrName
|
||||
}
|
||||
|
||||
func writeToAllLanguageFiles(errName map[string]bool) {
|
||||
languages := "en,zh,es,fr,de,ja,ko,ru"
|
||||
languageArr := strings.Split(languages, ",")
|
||||
var c [10]*goconfig.ConfigFile
|
||||
for i := 0; i < len(languageArr); i++ {
|
||||
var err error
|
||||
c[i], err = goconfig.LoadConfigFile("../i18n/languages/" + "locale_" + languageArr[i] + ".ini")
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
for j := range errName {
|
||||
parts := strings.Split(j, ".")
|
||||
_, err := c[i].GetValue(parts[0], parts[1])
|
||||
if err != nil {
|
||||
c[i].SetValue(parts[0], parts[1], parts[1])
|
||||
}
|
||||
}
|
||||
c[i].SetPrettyFormat(true)
|
||||
err = goconfig.SaveConfigFile(c[i], "../i18n/languages/"+"locale_"+languageArr[i]+".ini")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
@ -15,40 +15,39 @@
|
||||
package i18n
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func applyToOtherLanguage(dataEn *I18nData, lang string) {
|
||||
dataOther := readI18nFile(lang)
|
||||
println(dataOther)
|
||||
func applyToOtherLanguage(category string, language string, i18nData *I18nData) {
|
||||
newData := readI18nFile(category, language)
|
||||
println(newData)
|
||||
|
||||
applyData(dataEn, dataOther)
|
||||
writeI18nFile(lang, dataEn)
|
||||
applyData(i18nData, newData)
|
||||
writeI18nFile(category, language, i18nData)
|
||||
}
|
||||
|
||||
func TestGenerateI18nStringsForFrontend(t *testing.T) {
|
||||
dataEn := parseToData()
|
||||
writeI18nFile("en", dataEn)
|
||||
func TestGenerateI18nFrontend(t *testing.T) {
|
||||
enData := parseEnData("frontend")
|
||||
writeI18nFile("frontend", "en", enData)
|
||||
|
||||
applyToOtherLanguage(dataEn, "de")
|
||||
applyToOtherLanguage(dataEn, "fr")
|
||||
applyToOtherLanguage(dataEn, "ja")
|
||||
applyToOtherLanguage(dataEn, "ko")
|
||||
applyToOtherLanguage(dataEn, "ru")
|
||||
applyToOtherLanguage(dataEn, "zh")
|
||||
applyToOtherLanguage("frontend", "de", enData)
|
||||
applyToOtherLanguage("frontend", "es", enData)
|
||||
applyToOtherLanguage("frontend", "fr", enData)
|
||||
applyToOtherLanguage("frontend", "ja", enData)
|
||||
applyToOtherLanguage("frontend", "ko", enData)
|
||||
applyToOtherLanguage("frontend", "ru", enData)
|
||||
applyToOtherLanguage("frontend", "zh", enData)
|
||||
}
|
||||
|
||||
func TestGenerateI18nStringsForBackend(t *testing.T) {
|
||||
paths := getAllGoFilePaths()
|
||||
func TestGenerateI18nBackend(t *testing.T) {
|
||||
enData := parseEnData("backend")
|
||||
writeI18nFile("backend", "en", enData)
|
||||
|
||||
errName := getErrName(paths)
|
||||
|
||||
writeToAllLanguageFiles(errName)
|
||||
|
||||
fmt.Println("Total Err Words:", len(errName))
|
||||
|
||||
for i := range errName {
|
||||
fmt.Println(i)
|
||||
}
|
||||
applyToOtherLanguage("backend", "de", enData)
|
||||
applyToOtherLanguage("backend", "es", enData)
|
||||
applyToOtherLanguage("backend", "fr", enData)
|
||||
applyToOtherLanguage("backend", "ja", enData)
|
||||
applyToOtherLanguage("backend", "ko", enData)
|
||||
applyToOtherLanguage("backend", "ru", enData)
|
||||
applyToOtherLanguage("backend", "zh", enData)
|
||||
}
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = Application %s not found
|
||||
AppNotFoundForUserID = No application is found for userId: %s
|
||||
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||
HasNoProviders = This application has no providers
|
||||
HasNoProvidersOfType = This application has no providers of type
|
||||
InvalidID = Invalid application id
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = State expected: %s, but got: %s
|
||||
ChallengeMethodErr = Challenge method should be S256
|
||||
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||
NotHuman = Turing test failed.
|
||||
Unauthorized = Unauthorized operation
|
||||
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = Service %s and %s do not match
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = Email already exists
|
||||
EmptyErr = Email cannot be empty
|
||||
EmailInvalid = Email is invalid
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = Empty parameters for emailForm: %v
|
||||
InvalidReceivers = Invalid Email receivers: %s
|
||||
UnableGetModifyRule = Unable to get the email modify rule.
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = Please sign in first
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = Get init score failed, error: %%w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||
PasswordWrong = Ldap user name or password incorrect
|
||||
ServerExisted = Ldap server exist
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = The application: %s does not exist
|
||||
AppNotEnableSignUp = 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
|
||||
AccountDoNotExist = The account does not exist
|
||||
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||
LoginFirst = Please login first
|
||||
LoginFail = Failed to login in: %s
|
||||
NoPermission = You don't have the permission to do this
|
||||
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||
ProviderCanNotSignUp = 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
|
||||
SessionOutdated = Session outdated, please login again
|
||||
SignOutFirst = Please sign out first before signing in
|
||||
UserDoNotExist = The user: %s/%s doesn't exist
|
||||
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||
UnsupportedPasswordType = unsupported password type: %s
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = Organization does not exist
|
||||
Immutable = The %s is immutable.
|
||||
OnlyAdmin = Only admin can modify the %s.
|
||||
UnknownModifyRule = Unknown modify rule %s.
|
||||
|
||||
[ParameterErr]
|
||||
OrgMissingErr = Parameter organization is missing
|
||||
Missing = Missing parameter
|
||||
UnknownType = Unknown type
|
||||
Wrong = Wrong parameter
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = Code has not been sent yet!
|
||||
CodeTimeOut = You should verify your code in %d min!
|
||||
ExistedErr = Phone already exists
|
||||
EmptyErr = Phone cannot be empty
|
||||
InvalidReceivers = Invalid phone receivers: %s
|
||||
NumberInvalid = Phone number is invalid
|
||||
NoPrefix = %s No phone prefix
|
||||
PhoneCheckResult = Phone: %s
|
||||
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = This provider can't be unlinked
|
||||
CategoryNotSAML = provider %s's category is not SAML
|
||||
DoNotExist = the provider: %s does not exist
|
||||
InvalidProvider = Invalid captcha provider.
|
||||
LinkFirstErr = Please link first
|
||||
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||
ProviderNotSupported = The provider type: %s is not supported
|
||||
ProviderNotFound = The provider: %s is not found
|
||||
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = You are not authorized to access this resource
|
||||
UserIsNil = User is nil for tag: /"avatar/"
|
||||
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = New password cannot contain blank space.
|
||||
LessThanSixCharacters = New password must have at least 6 characters
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||
SignOutFirst = Please sign out first before signing up
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = Empty clientId or clientSecret
|
||||
InvalidToken = Invalid token
|
||||
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||
InvalidClientId = Invalid client_id
|
||||
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = Affiliation cannot be blank
|
||||
DisplayNameBlankErr = DisplayName cannot be blank
|
||||
DisplayNameInvalid = DisplayName is not valid real name
|
||||
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||
DoNotExist = The user: %s doesn't exist
|
||||
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||
DoNotExistSignUp = the user does not exist, please sign up first
|
||||
FirstNameBlankErr = FirstName cannot be blank
|
||||
FailToImportUsers = Failed to import users
|
||||
LastNameBlankErr = LastName cannot be blank
|
||||
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||
NameStartWithADigitErr = Username cannot start with a digit
|
||||
NameIsEmailErr = Username cannot be an email address
|
||||
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||
NameExistedErr = Username already exists
|
||||
NameEmptyErr = Empty username.
|
||||
NameTooLang = Username is too long (maximum is 39 characters).
|
||||
NameFormatErr = 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.
|
||||
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||
InvalidInformation = Invalid information
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = Application %s not found
|
||||
AppNotFoundForUserID = No application is found for userId: %s
|
||||
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||
HasNoProviders = This application has no providers
|
||||
HasNoProvidersOfType = This application has no providers of type
|
||||
InvalidID = Invalid application id
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = State expected: %s, but got: %s
|
||||
ChallengeMethodErr = Challenge method should be S256
|
||||
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||
NotHuman = Turing test failed.
|
||||
WrongPasswordManyTimes = You have entered the wrong password too many times, please wait for %d minutes %d seconds and try again
|
||||
Unauthorized = Unauthorized operation
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = Service %s and %s do not match
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = Email already exists
|
||||
EmptyErr = Email cannot be empty
|
||||
EmailInvalid = Email is invalid
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = Empty parameters for emailForm: %v
|
||||
InvalidReceivers = Invalid Email receivers: %s
|
||||
UnableGetModifyRule = Unable to get the email modify rule.
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = Please sign in first
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = Get init score failed, error: %%w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||
PasswordWrong = Ldap user name or password incorrect
|
||||
ServerExisted = Ldap server exist
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = The application: %s does not exist
|
||||
AppNotEnableSignUp = 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
|
||||
AccountDoNotExist = The account does not exist
|
||||
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||
LoginFirst = Please login first
|
||||
LoginFail = Failed to login in: %s
|
||||
NoPermission = You don't have the permission to do this
|
||||
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||
ProviderCanNotSignUp = 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
|
||||
SessionOutdated = Session outdated, please login again
|
||||
SignOutFirst = Please sign out first before signing in
|
||||
UserDoNotExist = The user: %s/%s doesn't exist
|
||||
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||
UnsupportedPasswordType = unsupported password type: %s
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = Organization does not exist
|
||||
Immutable = The %s is immutable.
|
||||
OnlyAdmin = Only admin can modify the %s.
|
||||
UnknownModifyRule = Unknown modify rule %s.
|
||||
|
||||
[ParameterErr]
|
||||
OrgMissingErr = Parameter organization is missing
|
||||
Missing = Missing parameter
|
||||
UnknownType = Unknown type
|
||||
Wrong = Wrong parameter
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = Code has not been sent yet!
|
||||
CodeTimeOut = You should verify your code in %d min!
|
||||
ExistedErr = Phone already exists
|
||||
EmptyErr = Phone cannot be empty
|
||||
InvalidReceivers = Invalid phone receivers: %s
|
||||
NumberInvalid = Phone number is invalid
|
||||
NoPrefix = %s No phone prefix
|
||||
PhoneCheckResult = Phone: %s
|
||||
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = This provider can't be unlinked
|
||||
CategoryNotSAML = provider %s's category is not SAML
|
||||
DoNotExist = the provider: %s does not exist
|
||||
InvalidProvider = Invalid captcha provider.
|
||||
LinkFirstErr = Please link first
|
||||
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||
ProviderNotSupported = The provider type: %s is not supported
|
||||
ProviderNotFound = The provider: %s is not found
|
||||
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = You are not authorized to access this resource
|
||||
UserIsNil = User is nil for tag: /"avatar/"
|
||||
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = New password cannot contain blank space.
|
||||
LessThanSixCharacters = New password must have at least 6 characters
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||
SignOutFirst = Please sign out first before signing up
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = Empty clientId or clientSecret
|
||||
InvalidToken = Invalid token
|
||||
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||
InvalidClientId = Invalid client_id
|
||||
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = Affiliation cannot be blank
|
||||
DisplayNameBlankErr = DisplayName cannot be blank
|
||||
DisplayNameInvalid = DisplayName is not valid real name
|
||||
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||
DoNotExist = The user: %s doesn't exist
|
||||
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||
DoNotExistSignUp = the user does not exist, please sign up first
|
||||
FirstNameBlankErr = FirstName cannot be blank
|
||||
FailToImportUsers = Failed to import users
|
||||
LastNameBlankErr = LastName cannot be blank
|
||||
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||
NameStartWithADigitErr = Username cannot start with a digit
|
||||
NameIsEmailErr = Username cannot be an email address
|
||||
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||
NameExistedErr = Username already exists
|
||||
NameEmptyErr = Empty username.
|
||||
NameTooLang = Username is too long (maximum is 39 characters).
|
||||
NameFormatErr = 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.
|
||||
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||
InvalidInformation = Invalid information
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = Application %s not found
|
||||
AppNotFoundForUserID = No application is found for userId: %s
|
||||
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||
HasNoProviders = This application has no providers
|
||||
HasNoProvidersOfType = This application has no providers of type
|
||||
InvalidID = Invalid application id
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = State expected: %s, but got: %s
|
||||
ChallengeMethodErr = Challenge method should be S256
|
||||
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||
NotHuman = Turing test failed.
|
||||
Unauthorized = Unauthorized operation
|
||||
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = Service %s and %s do not match
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = Email already exists
|
||||
EmptyErr = Email cannot be empty
|
||||
EmailInvalid = Email is invalid
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = Empty parameters for emailForm: %v
|
||||
InvalidReceivers = Invalid Email receivers: %s
|
||||
UnableGetModifyRule = Unable to get the email modify rule.
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = Please sign in first
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = Get init score failed, error: %%w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||
PasswordWrong = Ldap user name or password incorrect
|
||||
ServerExisted = Ldap server exist
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = The application: %s does not exist
|
||||
AppNotEnableSignUp = 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
|
||||
AccountDoNotExist = The account does not exist
|
||||
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||
LoginFirst = Please login first
|
||||
LoginFail = Failed to login in: %s
|
||||
NoPermission = You don't have the permission to do this
|
||||
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||
ProviderCanNotSignUp = 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
|
||||
SessionOutdated = Session outdated, please login again
|
||||
SignOutFirst = Please sign out first before signing in
|
||||
UserDoNotExist = The user: %s/%s doesn't exist
|
||||
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||
UnsupportedPasswordType = unsupported password type: %s
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = Organization does not exist
|
||||
Immutable = The %s is immutable.
|
||||
OnlyAdmin = Only admin can modify the %s.
|
||||
UnknownModifyRule = Unknown modify rule %s.
|
||||
|
||||
[ParameterErr]
|
||||
OrgMissingErr = Parameter organization is missing
|
||||
Missing = Missing parameter
|
||||
UnknownType = Unknown type
|
||||
Wrong = Wrong parameter
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = Code has not been sent yet!
|
||||
CodeTimeOut = You should verify your code in %d min!
|
||||
ExistedErr = Phone already exists
|
||||
EmptyErr = Phone cannot be empty
|
||||
InvalidReceivers = Invalid phone receivers: %s
|
||||
NumberInvalid = Phone number is invalid
|
||||
NoPrefix = %s No phone prefix
|
||||
PhoneCheckResult = Phone: %s
|
||||
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = This provider can't be unlinked
|
||||
CategoryNotSAML = provider %s's category is not SAML
|
||||
DoNotExist = the provider: %s does not exist
|
||||
InvalidProvider = Invalid captcha provider.
|
||||
LinkFirstErr = Please link first
|
||||
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||
ProviderNotSupported = The provider type: %s is not supported
|
||||
ProviderNotFound = The provider: %s is not found
|
||||
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = You are not authorized to access this resource
|
||||
UserIsNil = User is nil for tag: /"avatar/"
|
||||
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = New password cannot contain blank space.
|
||||
LessThanSixCharacters = New password must have at least 6 characters
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||
SignOutFirst = Please sign out first before signing up
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = Empty clientId or clientSecret
|
||||
InvalidToken = Invalid token
|
||||
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||
InvalidClientId = Invalid client_id
|
||||
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = Affiliation cannot be blank
|
||||
DisplayNameBlankErr = DisplayName cannot be blank
|
||||
DisplayNameInvalid = DisplayName is not valid real name
|
||||
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||
DoNotExist = The user: %s doesn't exist
|
||||
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||
DoNotExistSignUp = the user does not exist, please sign up first
|
||||
FirstNameBlankErr = FirstName cannot be blank
|
||||
FailToImportUsers = Failed to import users
|
||||
LastNameBlankErr = LastName cannot be blank
|
||||
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||
NameStartWithADigitErr = Username cannot start with a digit
|
||||
NameIsEmailErr = Username cannot be an email address
|
||||
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||
NameExistedErr = Username already exists
|
||||
NameEmptyErr = Empty username.
|
||||
NameTooLang = Username is too long (maximum is 39 characters).
|
||||
NameFormatErr = 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.
|
||||
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||
InvalidInformation = Invalid information
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = Application %s not found
|
||||
AppNotFoundForUserID = No application is found for userId: %s
|
||||
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||
HasNoProviders = This application has no providers
|
||||
HasNoProvidersOfType = This application has no providers of type
|
||||
InvalidID = Invalid application id
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = State expected: %s, but got: %s
|
||||
ChallengeMethodErr = Challenge method should be S256
|
||||
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||
NotHuman = Turing test failed.
|
||||
Unauthorized = Unauthorized operation
|
||||
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = Service %s and %s do not match
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = Email already exists
|
||||
EmptyErr = Email cannot be empty
|
||||
EmailInvalid = Email is invalid
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = Empty parameters for emailForm: %v
|
||||
InvalidReceivers = Invalid Email receivers: %s
|
||||
UnableGetModifyRule = Unable to get the email modify rule.
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = Please sign in first
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = Get init score failed, error: %%w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||
PasswordWrong = Ldap user name or password incorrect
|
||||
ServerExisted = Ldap server exist
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = The application: %s does not exist
|
||||
AppNotEnableSignUp = 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
|
||||
AccountDoNotExist = The account does not exist
|
||||
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||
LoginFirst = Please login first
|
||||
LoginFail = Failed to login in: %s
|
||||
NoPermission = You don't have the permission to do this
|
||||
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||
ProviderCanNotSignUp = 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
|
||||
SessionOutdated = Session outdated, please login again
|
||||
SignOutFirst = Please sign out first before signing in
|
||||
UserDoNotExist = The user: %s/%s doesn't exist
|
||||
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||
UnsupportedPasswordType = unsupported password type: %s
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = Organization does not exist
|
||||
Immutable = The %s is immutable.
|
||||
OnlyAdmin = Only admin can modify the %s.
|
||||
UnknownModifyRule = Unknown modify rule %s.
|
||||
|
||||
[ParameterErr]
|
||||
OrgMissingErr = Parameter organization is missing
|
||||
Missing = Missing parameter
|
||||
UnknownType = Unknown type
|
||||
Wrong = Wrong parameter
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = Code has not been sent yet!
|
||||
CodeTimeOut = You should verify your code in %d min!
|
||||
ExistedErr = Phone already exists
|
||||
EmptyErr = Phone cannot be empty
|
||||
InvalidReceivers = Invalid phone receivers: %s
|
||||
NumberInvalid = Phone number is invalid
|
||||
NoPrefix = %s No phone prefix
|
||||
PhoneCheckResult = Phone: %s
|
||||
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = This provider can't be unlinked
|
||||
CategoryNotSAML = provider %s's category is not SAML
|
||||
DoNotExist = the provider: %s does not exist
|
||||
InvalidProvider = Invalid captcha provider.
|
||||
LinkFirstErr = Please link first
|
||||
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||
ProviderNotSupported = The provider type: %s is not supported
|
||||
ProviderNotFound = The provider: %s is not found
|
||||
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = You are not authorized to access this resource
|
||||
UserIsNil = User is nil for tag: /"avatar/"
|
||||
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = New password cannot contain blank space.
|
||||
LessThanSixCharacters = New password must have at least 6 characters
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||
SignOutFirst = Please sign out first before signing up
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = Empty clientId or clientSecret
|
||||
InvalidToken = Invalid token
|
||||
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||
InvalidClientId = Invalid client_id
|
||||
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = Affiliation cannot be blank
|
||||
DisplayNameBlankErr = DisplayName cannot be blank
|
||||
DisplayNameInvalid = DisplayName is not valid real name
|
||||
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||
DoNotExist = The user: %s doesn't exist
|
||||
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||
DoNotExistSignUp = the user does not exist, please sign up first
|
||||
FirstNameBlankErr = FirstName cannot be blank
|
||||
FailToImportUsers = Failed to import users
|
||||
LastNameBlankErr = LastName cannot be blank
|
||||
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||
NameStartWithADigitErr = Username cannot start with a digit
|
||||
NameIsEmailErr = Username cannot be an email address
|
||||
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||
NameExistedErr = Username already exists
|
||||
NameEmptyErr = Empty username.
|
||||
NameTooLang = Username is too long (maximum is 39 characters).
|
||||
NameFormatErr = 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.
|
||||
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||
InvalidInformation = Invalid information
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = Application %s not found
|
||||
AppNotFoundForUserID = No application is found for userId: %s
|
||||
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||
HasNoProviders = This application has no providers
|
||||
HasNoProvidersOfType = This application has no providers of type
|
||||
InvalidID = Invalid application id
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = State expected: %s, but got: %s
|
||||
ChallengeMethodErr = Challenge method should be S256
|
||||
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||
NotHuman = Turing test failed.
|
||||
Unauthorized = Unauthorized operation
|
||||
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = Service %s and %s do not match
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = Email already exists
|
||||
EmptyErr = Email cannot be empty
|
||||
EmailInvalid = Email is invalid
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = Empty parameters for emailForm: %v
|
||||
InvalidReceivers = Invalid Email receivers: %s
|
||||
UnableGetModifyRule = Unable to get the email modify rule.
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = Please sign in first
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = Get init score failed, error: %%w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||
PasswordWrong = Ldap user name or password incorrect
|
||||
ServerExisted = Ldap server exist
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = The application: %s does not exist
|
||||
AppNotEnableSignUp = 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
|
||||
AccountDoNotExist = The account does not exist
|
||||
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||
LoginFirst = Please login first
|
||||
LoginFail = Failed to login in: %s
|
||||
NoPermission = You don't have the permission to do this
|
||||
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||
ProviderCanNotSignUp = 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
|
||||
SessionOutdated = Session outdated, please login again
|
||||
SignOutFirst = Please sign out first before signing in
|
||||
UserDoNotExist = The user: %s/%s doesn't exist
|
||||
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||
UnsupportedPasswordType = unsupported password type: %s
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = Organization does not exist
|
||||
Immutable = The %s is immutable.
|
||||
OnlyAdmin = Only admin can modify the %s.
|
||||
UnknownModifyRule = Unknown modify rule %s.
|
||||
|
||||
[ParameterErr]
|
||||
OrgMissingErr = Parameter organization is missing
|
||||
Missing = Missing parameter
|
||||
UnknownType = Unknown type
|
||||
Wrong = Wrong parameter
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = Code has not been sent yet!
|
||||
CodeTimeOut = You should verify your code in %d min!
|
||||
ExistedErr = Phone already exists
|
||||
EmptyErr = Phone cannot be empty
|
||||
InvalidReceivers = Invalid phone receivers: %s
|
||||
NumberInvalid = Phone number is invalid
|
||||
NoPrefix = %s No phone prefix
|
||||
PhoneCheckResult = Phone: %s
|
||||
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = This provider can't be unlinked
|
||||
CategoryNotSAML = provider %s's category is not SAML
|
||||
DoNotExist = the provider: %s does not exist
|
||||
InvalidProvider = Invalid captcha provider.
|
||||
LinkFirstErr = Please link first
|
||||
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||
ProviderNotSupported = The provider type: %s is not supported
|
||||
ProviderNotFound = The provider: %s is not found
|
||||
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = You are not authorized to access this resource
|
||||
UserIsNil = User is nil for tag: /"avatar/"
|
||||
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = New password cannot contain blank space.
|
||||
LessThanSixCharacters = New password must have at least 6 characters
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||
SignOutFirst = Please sign out first before signing up
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = Empty clientId or clientSecret
|
||||
InvalidToken = Invalid token
|
||||
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||
InvalidClientId = Invalid client_id
|
||||
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = Affiliation cannot be blank
|
||||
DisplayNameBlankErr = DisplayName cannot be blank
|
||||
DisplayNameInvalid = DisplayName is not valid real name
|
||||
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||
DoNotExist = The user: %s doesn't exist
|
||||
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||
DoNotExistSignUp = the user does not exist, please sign up first
|
||||
FirstNameBlankErr = FirstName cannot be blank
|
||||
FailToImportUsers = Failed to import users
|
||||
LastNameBlankErr = LastName cannot be blank
|
||||
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||
NameStartWithADigitErr = Username cannot start with a digit
|
||||
NameIsEmailErr = Username cannot be an email address
|
||||
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||
NameExistedErr = Username already exists
|
||||
NameEmptyErr = Empty username.
|
||||
NameTooLang = Username is too long (maximum is 39 characters).
|
||||
NameFormatErr = 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.
|
||||
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||
InvalidInformation = Invalid information
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = Application %s not found
|
||||
AppNotFoundForUserID = No application is found for userId: %s
|
||||
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||
HasNoProviders = This application has no providers
|
||||
HasNoProvidersOfType = This application has no providers of type
|
||||
InvalidID = Invalid application id
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = State expected: %s, but got: %s
|
||||
ChallengeMethodErr = Challenge method should be S256
|
||||
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||
NotHuman = Turing test failed.
|
||||
Unauthorized = Unauthorized operation
|
||||
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = Service %s and %s do not match
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = Email already exists
|
||||
EmptyErr = Email cannot be empty
|
||||
EmailInvalid = Email is invalid
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = Empty parameters for emailForm: %v
|
||||
InvalidReceivers = Invalid Email receivers: %s
|
||||
UnableGetModifyRule = Unable to get the email modify rule.
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = Please sign in first
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = Get init score failed, error: %%w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||
PasswordWrong = Ldap user name or password incorrect
|
||||
ServerExisted = Ldap server exist
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = The application: %s does not exist
|
||||
AppNotEnableSignUp = 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
|
||||
AccountDoNotExist = The account does not exist
|
||||
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||
LoginFirst = Please login first
|
||||
LoginFail = Failed to login in: %s
|
||||
NoPermission = You don't have the permission to do this
|
||||
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||
ProviderCanNotSignUp = 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
|
||||
SessionOutdated = Session outdated, please login again
|
||||
SignOutFirst = Please sign out first before signing in
|
||||
UserDoNotExist = The user: %s/%s doesn't exist
|
||||
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||
UnsupportedPasswordType = unsupported password type: %s
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = Organization does not exist
|
||||
Immutable = The %s is immutable.
|
||||
OnlyAdmin = Only admin can modify the %s.
|
||||
UnknownModifyRule = Unknown modify rule %s.
|
||||
|
||||
[ParameterErr]
|
||||
OrgMissingErr = Parameter organization is missing
|
||||
Missing = Missing parameter
|
||||
UnknownType = Unknown type
|
||||
Wrong = Wrong parameter
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = Code has not been sent yet!
|
||||
CodeTimeOut = You should verify your code in %d min!
|
||||
ExistedErr = Phone already exists
|
||||
EmptyErr = Phone cannot be empty
|
||||
InvalidReceivers = Invalid phone receivers: %s
|
||||
NumberInvalid = Phone number is invalid
|
||||
NoPrefix = %s No phone prefix
|
||||
PhoneCheckResult = Phone: %s
|
||||
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = This provider can't be unlinked
|
||||
CategoryNotSAML = provider %s's category is not SAML
|
||||
DoNotExist = the provider: %s does not exist
|
||||
InvalidProvider = Invalid captcha provider.
|
||||
LinkFirstErr = Please link first
|
||||
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||
ProviderNotSupported = The provider type: %s is not supported
|
||||
ProviderNotFound = The provider: %s is not found
|
||||
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = You are not authorized to access this resource
|
||||
UserIsNil = User is nil for tag: /"avatar/"
|
||||
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = New password cannot contain blank space.
|
||||
LessThanSixCharacters = New password must have at least 6 characters
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||
SignOutFirst = Please sign out first before signing up
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = Empty clientId or clientSecret
|
||||
InvalidToken = Invalid token
|
||||
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||
InvalidClientId = Invalid client_id
|
||||
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = Affiliation cannot be blank
|
||||
DisplayNameBlankErr = DisplayName cannot be blank
|
||||
DisplayNameInvalid = DisplayName is not valid real name
|
||||
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||
DoNotExist = The user: %s doesn't exist
|
||||
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||
DoNotExistSignUp = the user does not exist, please sign up first
|
||||
FirstNameBlankErr = FirstName cannot be blank
|
||||
FailToImportUsers = Failed to import users
|
||||
LastNameBlankErr = LastName cannot be blank
|
||||
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||
NameStartWithADigitErr = Username cannot start with a digit
|
||||
NameIsEmailErr = Username cannot be an email address
|
||||
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||
NameExistedErr = Username already exists
|
||||
NameEmptyErr = Empty username.
|
||||
NameTooLang = Username is too long (maximum is 39 characters).
|
||||
NameFormatErr = 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.
|
||||
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||
InvalidInformation = Invalid information
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = Application %s not found
|
||||
AppNotFoundForUserID = No application is found for userId: %s
|
||||
GrantTypeNotSupport = Grant_type: %s is not supported in this application
|
||||
HasNoProviders = This application has no providers
|
||||
HasNoProvidersOfType = This application has no providers of type
|
||||
InvalidID = Invalid application id
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = State expected: %s, but got: %s
|
||||
ChallengeMethodErr = Challenge method should be S256
|
||||
CanNotUnlinkUsers = You are not the global admin, you can't unlink other users
|
||||
CanNotLinkMySelf = You can't unlink yourself, you are not a member of any application
|
||||
CallWebAuthnSigninBegin = Please call WebAuthnSigninBegin first
|
||||
NotHuman = Turing test failed.
|
||||
Unauthorized = Unauthorized operation
|
||||
WrongPasswordManyTimes = WrongPasswordManyTimes
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = Service %s and %s do not match
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = Email already exists
|
||||
EmptyErr = Email cannot be empty
|
||||
EmailInvalid = Email is invalid
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = Empty parameters for emailForm: %v
|
||||
InvalidReceivers = Invalid Email receivers: %s
|
||||
UnableGetModifyRule = Unable to get the email modify rule.
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = Please sign in first
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = Get init score failed, error: %%w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = Multiple accounts with same uid, please check your ldap server
|
||||
PasswordWrong = Ldap user name or password incorrect
|
||||
ServerExisted = Ldap server exist
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = The application: %s does not exist
|
||||
AppNotEnableSignUp = 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
|
||||
AccountDoNotExist = The account does not exist
|
||||
InvalidUserInformation = Failed to create user, user information is invalid: %s
|
||||
LoginFirst = Please login first
|
||||
LoginFail = Failed to login in: %s
|
||||
NoPermission = You don't have the permission to do this
|
||||
OldUser = The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)
|
||||
ProviderCanNotSignUp = 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
|
||||
SessionOutdated = Session outdated, please login again
|
||||
SignOutFirst = Please sign out first before signing in
|
||||
UserDoNotExist = The user: %s/%s doesn't exist
|
||||
UserIsForbidden = The user is forbidden to sign in, please contact the administrator
|
||||
UnknownAuthentication = Unknown authentication type (not password or provider), form = %s
|
||||
UnsupportedPasswordType = unsupported password type: %s
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = Organization does not exist
|
||||
Immutable = The %s is immutable.
|
||||
OnlyAdmin = Only admin can modify the %s.
|
||||
UnknownModifyRule = Unknown modify rule %s.
|
||||
|
||||
[ParameterErr]
|
||||
OrgMissingErr = Parameter organization is missing
|
||||
Missing = Missing parameter
|
||||
UnknownType = Unknown type
|
||||
Wrong = Wrong parameter
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = Code has not been sent yet!
|
||||
CodeTimeOut = You should verify your code in %d min!
|
||||
ExistedErr = Phone already exists
|
||||
EmptyErr = Phone cannot be empty
|
||||
InvalidReceivers = Invalid phone receivers: %s
|
||||
NumberInvalid = Phone number is invalid
|
||||
NoPrefix = %s No phone prefix
|
||||
PhoneCheckResult = Phone: %s
|
||||
UnableGetModifyRule = Unable to get the phone modify rule.
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = This provider can't be unlinked
|
||||
CategoryNotSAML = provider %s's category is not SAML
|
||||
DoNotExist = the provider: %s does not exist
|
||||
InvalidProvider = Invalid captcha provider.
|
||||
LinkFirstErr = Please link first
|
||||
ProviderNotEnabled = The provider: %s is not enabled for the application
|
||||
ProviderNotSupported = The provider type: %s is not supported
|
||||
ProviderNotFound = The provider: %s is not found
|
||||
ProviderNotFoundForCategory = No provider for category: %s is found for application: %s
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = You are not authorized to access this resource
|
||||
UserIsNil = User is nil for tag: /"avatar/"
|
||||
UsernameOrFilePathEmpty = Username or fullFilePath is empty: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = New password cannot contain blank space.
|
||||
LessThanSixCharacters = New password must have at least 6 characters
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = The application does not allow to sign up new account
|
||||
SignOutFirst = Please sign out first before signing up
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = The objectKey: %s is not allowed
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = Empty clientId or clientSecret
|
||||
InvalidToken = Invalid token
|
||||
InvalidAppOrWrongClientSecret = Invalid application or wrong clientSecret
|
||||
InvalidClientId = Invalid client_id
|
||||
RedirectURIDoNotExist = Redirect URI: %s doesn't exist in the allowed Redirect URI list
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = Affiliation cannot be blank
|
||||
DisplayNameBlankErr = DisplayName cannot be blank
|
||||
DisplayNameInvalid = DisplayName is not valid real name
|
||||
DisplayNameCanNotBeEmpty = Display name cannot be empty
|
||||
DoNotExist = The user: %s doesn't exist
|
||||
DoNotExistInOrg = The user: %s/%s doesn't exist
|
||||
DoNotExistSignUp = the user does not exist, please sign up first
|
||||
FirstNameBlankErr = FirstName cannot be blank
|
||||
FailToImportUsers = Failed to import users
|
||||
LastNameBlankErr = LastName cannot be blank
|
||||
NameLessThanTwoCharacters = Username must have at least 2 characters
|
||||
NameStartWithADigitErr = Username cannot start with a digit
|
||||
NameIsEmailErr = Username cannot be an email address
|
||||
NameCantainWhitSpaceErr = Username cannot contain white spaces
|
||||
NameExistedErr = Username already exists
|
||||
NameEmptyErr = Empty username.
|
||||
NameTooLang = Username is too long (maximum is 39 characters).
|
||||
NameFormatErr = 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.
|
||||
PasswordLessThanSixCharacters = Password must have at least 6 characters
|
||||
InvalidInformation = Invalid information
|
||||
|
@ -1,137 +0,0 @@
|
||||
[ApplicationErr]
|
||||
AppNotFound = 应用 %%s 未找到
|
||||
AppNotFoundForUserID = 找不到该用户的应用程序 %s
|
||||
GrantTypeNotSupport = 此应用中不支持此授权类型
|
||||
HasNoProviders = 该应用无提供商
|
||||
HasNoProvidersOfType = 应用没有该类型的提供商
|
||||
InvalidID = 无效的Application ID
|
||||
|
||||
[AuthErr]
|
||||
AuthStateWrong = 期望状态位: %s, 实际状态为: %s
|
||||
ChallengeMethodErr = Challenge 方法应该为 S256
|
||||
CanNotUnlinkUsers = 您不是全局管理员,无法取消链接其他用户
|
||||
CanNotLinkMySelf = 您无法取消链接,您不是任何应用程序的成员
|
||||
CallWebAuthnSigninBegin = 请先调用WebAuthnSigninBegin
|
||||
NotHuman = 真人验证失败
|
||||
Unauthorized = 未授权的操作
|
||||
WrongPasswordManyTimes = 输入密码错误次数已达上限,请在 %d 分 %d 秒后重试
|
||||
|
||||
[CasErr]
|
||||
ServiceDoNotMatch = 服务 %s 与 %s 不匹配
|
||||
|
||||
[EmailErr]
|
||||
ExistedErr = 该邮箱已存在
|
||||
EmptyErr = 邮箱不可为空
|
||||
EmailInvalid = 无效邮箱
|
||||
EmailCheckResult = Email: %s
|
||||
EmptyParam = 邮件参数为空: %v
|
||||
InvalidReceivers = 无效的邮箱接收者: %%s
|
||||
UnableGetModifyRule = 无法得到Email修改规则
|
||||
|
||||
[EnforcerErr]
|
||||
SignInFirst = 请先登录
|
||||
|
||||
[InitErr]
|
||||
InitScoreFailed = 初始化分数失败: %w
|
||||
|
||||
[LdapErr]
|
||||
MultipleAccounts = 多个帐户具有相同的uid,请检查您的 ldap 服务器
|
||||
PasswordWrong = Ldap密码错误
|
||||
ServerExisted = Ldap服务器已存在
|
||||
|
||||
[LoginErr]
|
||||
AppDoNotExist = 应用不存在: %s
|
||||
AppNotEnableSignUp = 提供商账户: %s 与用户名: %s (%s) 不存在且 不允许注册新账户, 请联系IT支持
|
||||
AccountDoNotExist = 账户不存在
|
||||
InvalidUserInformation = 创建用户失败,用户信息无效: %%s
|
||||
LoginFirst = 请先登录
|
||||
LoginFail = 无法登录: %s
|
||||
NoPermission = 您没有权限执行此操作
|
||||
OldUser = 提供商账户: %s 与用户名: %s (%s) 已经与其他账户绑定: %s (%s)
|
||||
ProviderCanNotSignUp = 提供商账户: %s 与用户名: %s (%s) 不存在且 不允许通过 %s 注册新账户, 请使用其他方式注册
|
||||
SignOutFirst = 请在登录前登出
|
||||
SessionOutdated = Session已过期,请重新登陆
|
||||
UserDoNotExist = 用户不存在: %s/%s
|
||||
UserIsForbidden = 该用户被禁止登陆,请联系管理员
|
||||
UnknownAuthentication = 未知的认证类型 (非密码或提供商认证), form = %s
|
||||
UnsupportedPasswordType = 不支持此密码类型
|
||||
|
||||
[OrgErr]
|
||||
DoNotExist = 组织不存在
|
||||
Immutable = %s是不可变的
|
||||
OnlyAdmin = 只有管理员用户有此权限
|
||||
UnknownModifyRule = 未知的修改规则
|
||||
|
||||
[ParameterErr]
|
||||
Missing = 参数丢失
|
||||
OrgMissingErr = Organization参数丢失
|
||||
UnknownType = 未知类型
|
||||
Wrong = 参数错误
|
||||
|
||||
[PhoneErr]
|
||||
CodeNotSent = 验证码还未发送
|
||||
CodeTimeOut = 验证码过期
|
||||
ExistedErr = 该电话已存在
|
||||
EmptyErr = 电话不可为空
|
||||
InvalidReceivers = 无效的电话接收者: %s
|
||||
NumberInvalid = 无效电话
|
||||
PhoneCheckResult = 电话: %s
|
||||
UnableGetModifyRule = 无法得到电话修改规则
|
||||
NoPrefix = %s 无此电话前缀
|
||||
|
||||
[ProviderErr]
|
||||
CanNotBeUnlinked = 该提供商不可被链接
|
||||
InvalidProvider = 无效的验证码提供商
|
||||
LinkFirstErr = 请先绑定
|
||||
ProviderNotEnabled = 提供商: %s 未被启用
|
||||
ProviderNotSupported = 不支持该类型的提供商: %s
|
||||
ProviderNotFound = 该提供商未找到: %s
|
||||
ProviderNotFoundForCategory = 该类型的提供商: %s 在应用中未找到: %s
|
||||
DoNotExist = 提供商: %s 不存在
|
||||
CategoryNotSAML = 提供商 %s类型不是SAML
|
||||
|
||||
[ResourceErr]
|
||||
NotAuthorized = 您无权获取此资源
|
||||
UserIsNil = 用户头像标签为空
|
||||
UsernameOrFilePathEmpty = username或FilePath为空: username = %s, fullFilePath = %s
|
||||
|
||||
[SetPasswordErr]
|
||||
CanNotContainBlank = 新密码不可以包含空客
|
||||
LessThanSixCharacters = 新密码至少为6位
|
||||
|
||||
[SignUpErr]
|
||||
DoNotAllowSignUp = 该应用不允许注册新账户
|
||||
SignOutFirst = 请在登陆前登出
|
||||
|
||||
[TokenErr]
|
||||
EmptyClientID = clientId或clientSecret为空
|
||||
InvalidAppOrWrongClientSecret = 无效应用或错误的clientSecret
|
||||
InvalidToken = 无效token
|
||||
InvalidClientId = 无效的ClientId
|
||||
RedirectURIDoNotExist = 重定向 URI:%s 在可列表中未找到
|
||||
|
||||
[UserErr]
|
||||
AffiliationBlankErr = 联系方式不可为空
|
||||
DisplayNameBlankErr = 展示名称不可为空
|
||||
DisplayNameInvalid = 展示名称无效
|
||||
DisplayNameCanNotBeEmpty = 展示名称不可为空
|
||||
DoNotExist = 用户不存在: %s
|
||||
DoNotExistInOrg = 用户不存在: %s/%s
|
||||
FirstNameBlankErr = 名不可以为空
|
||||
FailToImportUsers = 导入用户失败
|
||||
LastNameBlankErr = 姓不可以为空
|
||||
NameLessThanTwoCharacters = 用户名至少要有2个字符
|
||||
NameStartWithADigitErr = 用户名禁止使用数字作为第一个字符
|
||||
NameIsEmailErr = 用户名不可以是邮箱地址
|
||||
NameCantainWhitSpaceErr = 用户名不可以包含空格
|
||||
NameExistedErr = 用户名已存在
|
||||
NameEmptyErr = 用户名不可为空
|
||||
NameTooLang = 用户名过长(最大长度为39个字符)
|
||||
NameFormatErr = 用户名只能包含字母数字字符、下划线或连字符,不能有连续的连字符或下划线,也不能以连字符或下划线开头或结尾
|
||||
PasswordLessThanSixCharacters = 密码至少为6字符
|
||||
DoNotExistSignUp = 用户不存在,请先注册
|
||||
InvalidInformation = 无效信息
|
||||
|
||||
[StorageErr]
|
||||
ObjectKeyNotAllowed = object key :%s 不被允许
|
||||
|
146
i18n/locales/de/data.json
Normal file
146
i18n/locales/de/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "Email: %s",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Invalid information": "Invalid information",
|
||||
"Phone: %s": "Phone: %s",
|
||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s No phone prefix",
|
||||
"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 type: %s is not supported": "The provider type: %s is not supported",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||
},
|
||||
"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",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
|
||||
"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 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",
|
||||
"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"
|
||||
},
|
||||
"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.",
|
||||
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||
},
|
||||
"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!",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"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 parameter": "Wrong parameter",
|
||||
"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"
|
||||
}
|
||||
}
|
146
i18n/locales/en/data.json
Normal file
146
i18n/locales/en/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "Email: %s",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Invalid information": "Invalid information",
|
||||
"Phone: %s": "Phone: %s",
|
||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s No phone prefix",
|
||||
"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 type: %s is not supported": "The provider type: %s is not supported",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||
},
|
||||
"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",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
|
||||
"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 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",
|
||||
"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"
|
||||
},
|
||||
"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.",
|
||||
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||
},
|
||||
"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!",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"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 parameter": "Wrong parameter",
|
||||
"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"
|
||||
}
|
||||
}
|
146
i18n/locales/es/data.json
Normal file
146
i18n/locales/es/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "Email: %s",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Invalid information": "Invalid information",
|
||||
"Phone: %s": "Phone: %s",
|
||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s No phone prefix",
|
||||
"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 type: %s is not supported": "The provider type: %s is not supported",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||
},
|
||||
"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",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
|
||||
"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 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",
|
||||
"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"
|
||||
},
|
||||
"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.",
|
||||
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||
},
|
||||
"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!",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"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 parameter": "Wrong parameter",
|
||||
"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"
|
||||
}
|
||||
}
|
146
i18n/locales/fr/data.json
Normal file
146
i18n/locales/fr/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "Email: %s",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Invalid information": "Invalid information",
|
||||
"Phone: %s": "Phone: %s",
|
||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s No phone prefix",
|
||||
"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 type: %s is not supported": "The provider type: %s is not supported",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||
},
|
||||
"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",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
|
||||
"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 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",
|
||||
"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"
|
||||
},
|
||||
"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.",
|
||||
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||
},
|
||||
"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!",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"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 parameter": "Wrong parameter",
|
||||
"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"
|
||||
}
|
||||
}
|
146
i18n/locales/ja/data.json
Normal file
146
i18n/locales/ja/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "Email: %s",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Invalid information": "Invalid information",
|
||||
"Phone: %s": "Phone: %s",
|
||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s No phone prefix",
|
||||
"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 type: %s is not supported": "The provider type: %s is not supported",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||
},
|
||||
"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",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
|
||||
"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 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",
|
||||
"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"
|
||||
},
|
||||
"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.",
|
||||
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||
},
|
||||
"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!",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"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 parameter": "Wrong parameter",
|
||||
"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"
|
||||
}
|
||||
}
|
146
i18n/locales/ko/data.json
Normal file
146
i18n/locales/ko/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "Email: %s",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Invalid information": "Invalid information",
|
||||
"Phone: %s": "Phone: %s",
|
||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s No phone prefix",
|
||||
"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 type: %s is not supported": "The provider type: %s is not supported",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||
},
|
||||
"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",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
|
||||
"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 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",
|
||||
"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"
|
||||
},
|
||||
"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.",
|
||||
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||
},
|
||||
"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!",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"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 parameter": "Wrong parameter",
|
||||
"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"
|
||||
}
|
||||
}
|
146
i18n/locales/ru/data.json
Normal file
146
i18n/locales/ru/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "Email: %s",
|
||||
"Get init score failed, error: %w": "Get init score failed, error: %w",
|
||||
"Invalid information": "Invalid information",
|
||||
"Phone: %s": "Phone: %s",
|
||||
"Please sign out first before signing in": "Please sign out first before signing in",
|
||||
"Please sign out first before signing up": "Please sign out first before signing up",
|
||||
"The application does not allow to sign up new account": "The application does not allow to sign up new account"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s No phone prefix",
|
||||
"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 type: %s is not supported": "The provider type: %s is not supported",
|
||||
"The provider: %s is not enabled for the application": "The provider: %s is not enabled for the application",
|
||||
"The user is forbidden to sign in, please contact the administrator": "The user is forbidden to sign in, please contact the administrator",
|
||||
"Turing test failed.": "Turing test failed.",
|
||||
"Unauthorized operation": "Unauthorized operation",
|
||||
"Unknown authentication type (not password or provider), form = %s": "Unknown authentication type (not password or provider), form = %s"
|
||||
},
|
||||
"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",
|
||||
"LastName cannot be blank": "LastName cannot be blank",
|
||||
"Ldap user name or password incorrect": "Ldap user name or password incorrect",
|
||||
"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 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",
|
||||
"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"
|
||||
},
|
||||
"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.",
|
||||
"New password must have at least 6 characters": "New password must have at least 6 characters"
|
||||
},
|
||||
"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!",
|
||||
"Email is invalid": "Email is invalid",
|
||||
"Invalid captcha provider.": "Invalid captcha provider.",
|
||||
"Organization does not exist": "Organization does not exist",
|
||||
"Phone number is invalid": "Phone number is invalid",
|
||||
"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 parameter": "Wrong parameter",
|
||||
"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"
|
||||
}
|
||||
}
|
146
i18n/locales/zh/data.json
Normal file
146
i18n/locales/zh/data.json
Normal file
@ -0,0 +1,146 @@
|
||||
{
|
||||
"account": {
|
||||
"Email: %s": "邮件: %s",
|
||||
"Get init score failed, error: %w": "初始化分数失败: %w",
|
||||
"Invalid information": "无效信息",
|
||||
"Phone: %s": "手机号: %s",
|
||||
"Please sign out first before signing in": "请在登录前先退出登录",
|
||||
"Please sign out first before signing up": "请在注册前先退出登录",
|
||||
"The application does not allow to sign up new account": "该应用不允许注册新用户"
|
||||
},
|
||||
"auth": {
|
||||
"%s No phone prefix": "%s 无此手机号前缀",
|
||||
"Challenge method should be S256": "Challenge 方法应该为 S256",
|
||||
"Failed to create user, user information is invalid: %s": "创建用户失败,用户信息无效: %s",
|
||||
"Failed to login in: %s": "登录失败: %s",
|
||||
"Invalid token": "无效token",
|
||||
"State expected: %s, but got: %s": "期望状态为: %s, 实际状态为: %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": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许通过 %s 注册新账户, 请使用其他方式注册",
|
||||
"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": "提供商账户: %s 与用户名: %s (%s) 不存在且 不允许注册新账户, 请联系IT支持",
|
||||
"The account for provider: %s and username: %s (%s) is already linked to another account: %s (%s)": "提供商账户: %s 与用户名: %s (%s) 已经与其他账户绑定: %s (%s)",
|
||||
"The application: %s does not exist": "应用 %s 不存在",
|
||||
"The login method: login with password is not enabled for the application": "该应用禁止采用密码登录方式",
|
||||
"The provider type: %s is not supported": "不支持该类型的提供商: %s",
|
||||
"The provider: %s is not enabled for the application": "该应用的提供商: %s 未被启用",
|
||||
"The user is forbidden to sign in, please contact the administrator": "该用户被禁止登录,请联系管理员",
|
||||
"Turing test failed.": "人机验证失败",
|
||||
"Unauthorized operation": "未授权的操作",
|
||||
"Unknown authentication type (not password or provider), form = %s": "未知的认证类型(非密码或第三方提供商):%s"
|
||||
},
|
||||
"cas": {
|
||||
"Service %s and %s do not match": "服务 %s 与 %s 不匹配"
|
||||
},
|
||||
"check": {
|
||||
"Affiliation cannot be blank": "工作单位不可为空",
|
||||
"DisplayName cannot be blank": "显示名称不可为空",
|
||||
"DisplayName is not valid real name": "显示名称必须是真实姓名",
|
||||
"Email already exists": "该邮箱已存在",
|
||||
"Email cannot be empty": "邮箱不可为空",
|
||||
"Email is invalid": "无效邮箱",
|
||||
"Empty username.": "用户名不可为空",
|
||||
"FirstName cannot be blank": "名不可以为空",
|
||||
"LastName cannot be blank": "姓不可以为空",
|
||||
"Ldap user name or password incorrect": "LDAP密码错误",
|
||||
"Multiple accounts with same uid, please check your ldap server": "多个帐户具有相同的uid,请检查您的 LDAP 服务器",
|
||||
"Organization does not exist": "组织不存在",
|
||||
"Password must have at least 6 characters": "新密码至少为6位",
|
||||
"Phone already exists": "该手机号已存在",
|
||||
"Phone cannot be empty": "手机号不可为空",
|
||||
"Phone number is invalid": "无效手机号",
|
||||
"Session outdated, please login again": "会话已过期,请重新登录",
|
||||
"The user is forbidden to sign in, please contact the administrator": "该用户被禁止登录,请联系管理员",
|
||||
"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 cannot be an email address": "用户名不可以是邮箱地址",
|
||||
"Username cannot contain white spaces": "用户名禁止包含空格",
|
||||
"Username cannot start with a digit": "用户名禁止使用数字开头",
|
||||
"Username is too long (maximum is 39 characters).": "用户名过长(最大允许长度为39个字符)",
|
||||
"Username must have at least 2 characters": "用户名至少要有2个字符",
|
||||
"You have entered the wrong password or code too many times, please wait for %d minutes and try again": "密码错误次数已达上限,请在 %d 分后重试",
|
||||
"password or code is incorrect, you have %d remaining chances": "密码错误,您还有 %d 次尝试的机会",
|
||||
"unsupported password type: %s": "不支持的密码类型: %s"
|
||||
},
|
||||
"general": {
|
||||
"Missing parameter": "缺少参数",
|
||||
"Please login first": "请先登录",
|
||||
"The user: %s doesn't exist": "用户: %s 不存在"
|
||||
},
|
||||
"ldap": {
|
||||
"Ldap server exist": "LDAP服务器已存在"
|
||||
},
|
||||
"link": {
|
||||
"Please link first": "请先绑定",
|
||||
"This application has no providers": "该应用无可用的提供商",
|
||||
"This application has no providers of type": "应用没有该类型的提供商",
|
||||
"This provider can't be unlinked": "该提供商被禁止解绑",
|
||||
"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": "您无法自行解绑,您不是任何应用程序的成员"
|
||||
},
|
||||
"organization": {
|
||||
"Only admin can modify the %s.": "仅允许管理员可以修改 %s",
|
||||
"The %s is immutable.": "%s 是不可变的",
|
||||
"Unknown modify rule %s.": "未知的修改规则: %s"
|
||||
},
|
||||
"provider": {
|
||||
"Invalid application id": "无效的应用ID",
|
||||
"the provider: %s does not exist": "提供商: %s 不存在"
|
||||
},
|
||||
"resource": {
|
||||
"User is nil for tag: avatar": "上传头像时用户为空",
|
||||
"Username or fullFilePath is empty: username = %s, fullFilePath = %s": "username或fullFilePath为空: username = %s, fullFilePath = %s"
|
||||
},
|
||||
"saml": {
|
||||
"Application %s not found": "未找到应用: %s"
|
||||
},
|
||||
"saml_sp": {
|
||||
"provider %s's category is not SAML": "提供商: %s 不是SAML类型"
|
||||
},
|
||||
"service": {
|
||||
"Empty parameters for emailForm: %v": "邮件参数为空: %v",
|
||||
"Invalid Email receivers: %s": " 无效的邮箱收件人: %s",
|
||||
"Invalid phone receivers: %s": "无效的手机短信收信人: %s"
|
||||
},
|
||||
"storage": {
|
||||
"The objectKey: %s is not allowed": "objectKey: %s 被禁止",
|
||||
"The provider type: %s is not supported": "不支持的提供商类型: %s"
|
||||
},
|
||||
"token": {
|
||||
"Empty clientId or clientSecret": "clientId或clientSecret为空",
|
||||
"Grant_type: %s is not supported in this application": "该应用不支持Grant_type: %s",
|
||||
"Invalid application or wrong clientSecret": "无效应用或错误的clientSecret",
|
||||
"Invalid client_id": "无效的ClientId",
|
||||
"Redirect URI: %s doesn't exist in the allowed Redirect URI list": "重定向 URI:%s 在许可跳转列表中未找到",
|
||||
"Token not found, invalid accessToken": "未查询到对应token, accessToken无效"
|
||||
},
|
||||
"user": {
|
||||
"Display name cannot be empty": "显示名称不可为空",
|
||||
"New password cannot contain blank space.": "新密码不可以包含空格",
|
||||
"New password must have at least 6 characters": "新密码至少需要6位字符"
|
||||
},
|
||||
"user_upload": {
|
||||
"Failed to import users": "导入用户失败"
|
||||
},
|
||||
"util": {
|
||||
"No application is found for userId: %s": "未找到用户: %s 的应用",
|
||||
"No provider for category: %s is found for application: %s": "未找到类别为: %s 的提供商来满足应用: %s",
|
||||
"The provider: %s is not found": "未找到提供商: %s"
|
||||
},
|
||||
"verification": {
|
||||
"Code has not been sent yet!": "验证码还未发送",
|
||||
"Email is invalid": "非法的邮箱",
|
||||
"Invalid captcha provider.": "非法的验证码提供商",
|
||||
"Organization does not exist": "组织不存在",
|
||||
"Phone number is invalid": "非法的手机号码",
|
||||
"Turing test failed.": "验证码还未发送",
|
||||
"Unable to get the email modify rule.": "无法获取邮箱修改规则",
|
||||
"Unable to get the phone modify rule.": "无法获取手机号修改规则",
|
||||
"Unknown type": "未知类型",
|
||||
"Wrong parameter": "参数错误",
|
||||
"You should verify your code in %d min!": "请在 %d 分钟内输入正确验证码",
|
||||
"the user does not exist, please sign up first": "用户不存在,请先注册"
|
||||
},
|
||||
"webauthn": {
|
||||
"Found no credentials for this user": "该用户没有 WebAuthn 凭据",
|
||||
"Please call WebAuthnSigninBegin first": "请先调用 WebAuthnSigninBegin"
|
||||
}
|
||||
}
|
49
i18n/util.go
49
i18n/util.go
@ -17,27 +17,26 @@ package i18n
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
//go:embed languages/*.ini
|
||||
//go:embed locales/*/data.json
|
||||
var f embed.FS
|
||||
|
||||
var (
|
||||
langMapConfig = make(map[string]*ini.File)
|
||||
isNotFirstLoad = make(map[string]bool)
|
||||
)
|
||||
var langMap = make(map[string]map[string]map[string]string) // for example : langMap[en][account][Invalid information] = Invalid information
|
||||
|
||||
func getI18nFilePath(language string) string {
|
||||
return fmt.Sprintf("../web/src/locales/%s/data.json", language)
|
||||
func getI18nFilePath(category string, language string) string {
|
||||
if category == "backend" {
|
||||
return fmt.Sprintf("../i18n/locales/%s/data.json", language)
|
||||
} else {
|
||||
return fmt.Sprintf("../web/src/locales/%s/data.json", language)
|
||||
}
|
||||
}
|
||||
|
||||
func readI18nFile(language string) *I18nData {
|
||||
s := util.ReadStringFromPath(getI18nFilePath(language))
|
||||
func readI18nFile(category string, language string) *I18nData {
|
||||
s := util.ReadStringFromPath(getI18nFilePath(category, language))
|
||||
|
||||
data := &I18nData{}
|
||||
err := util.JsonToStruct(s, data)
|
||||
@ -47,13 +46,13 @@ func readI18nFile(language string) *I18nData {
|
||||
return data
|
||||
}
|
||||
|
||||
func writeI18nFile(language string, data *I18nData) {
|
||||
func writeI18nFile(category string, language string, data *I18nData) {
|
||||
s := util.StructToJsonFormatted(data)
|
||||
s = strings.ReplaceAll(s, "\\u0026", "&")
|
||||
s += "\n"
|
||||
println(s)
|
||||
|
||||
util.WriteStringToPath(s, getI18nFilePath(language))
|
||||
util.WriteStringToPath(s, getI18nFilePath(category, language))
|
||||
}
|
||||
|
||||
func applyData(data1 *I18nData, data2 *I18nData) {
|
||||
@ -75,18 +74,20 @@ func applyData(data1 *I18nData, data2 *I18nData) {
|
||||
}
|
||||
|
||||
func Translate(lang string, error string) string {
|
||||
parts := strings.Split(error, ".")
|
||||
if !strings.Contains(error, ".") || len(parts) != 2 {
|
||||
log.Println("Invalid Error Name")
|
||||
return ""
|
||||
parts := strings.SplitN(error, ":", 2)
|
||||
if !strings.Contains(error, ":") || len(parts) != 2 {
|
||||
return "Translate Error: " + error
|
||||
}
|
||||
|
||||
if isNotFirstLoad[lang] {
|
||||
return langMapConfig[lang].Section(parts[0]).Key(parts[1]).String()
|
||||
if langMap[lang] != nil {
|
||||
return langMap[lang][parts[0]][parts[1]]
|
||||
} else {
|
||||
file, _ := f.ReadFile("languages/locale_" + lang + ".ini")
|
||||
langMapConfig[lang], _ = ini.Load(file)
|
||||
isNotFirstLoad[lang] = true
|
||||
return langMapConfig[lang].Section(parts[0]).Key(parts[1]).String()
|
||||
file, _ := f.ReadFile("locales/" + lang + "/data.json")
|
||||
data := I18nData{}
|
||||
err := util.JsonToStruct(string(file), &data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
langMap[lang] = data
|
||||
return langMap[lang][parts[0]][parts[1]]
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,11 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@ -118,13 +118,14 @@ func (idp *AdfsIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
keyset, err := jwk.Parse(resp.Body)
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
keyset, err := jwk.ParseKey(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tokenSrc := []byte(token.AccessToken)
|
||||
publicKey, _ := keyset.Keys[0].Materialize()
|
||||
idToken, _ := jwt.Parse(bytes.NewReader(tokenSrc), jwt.WithVerify(jwa.RS256, publicKey))
|
||||
publicKey, _ := keyset.PublicKey()
|
||||
idToken, _ := jwt.Parse(tokenSrc, jwt.WithVerify(jwa.RS256, publicKey))
|
||||
sid, _ := idToken.Get("sid")
|
||||
upn, _ := idToken.Get("upn")
|
||||
name, _ := idToken.Get("unique_name")
|
||||
|
@ -256,6 +256,8 @@ func (idp *DingTalkIdProvider) isUserInOrg(unionId string) (bool, error) {
|
||||
}
|
||||
if data.ErrCode == 60121 {
|
||||
return false, fmt.Errorf("the user is not found in the organization where clientId and clientSecret belong")
|
||||
} else if data.ErrCode != 0 {
|
||||
return false, fmt.Errorf(data.ErrMessage)
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
245
idp/goth.go
245
idp/goth.go
@ -22,35 +22,64 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/casdoor/goth"
|
||||
"github.com/casdoor/goth/providers/amazon"
|
||||
"github.com/casdoor/goth/providers/apple"
|
||||
"github.com/casdoor/goth/providers/azuread"
|
||||
"github.com/casdoor/goth/providers/bitbucket"
|
||||
"github.com/casdoor/goth/providers/digitalocean"
|
||||
"github.com/casdoor/goth/providers/discord"
|
||||
"github.com/casdoor/goth/providers/dropbox"
|
||||
"github.com/casdoor/goth/providers/facebook"
|
||||
"github.com/casdoor/goth/providers/gitea"
|
||||
"github.com/casdoor/goth/providers/github"
|
||||
"github.com/casdoor/goth/providers/gitlab"
|
||||
"github.com/casdoor/goth/providers/google"
|
||||
"github.com/casdoor/goth/providers/heroku"
|
||||
"github.com/casdoor/goth/providers/instagram"
|
||||
"github.com/casdoor/goth/providers/kakao"
|
||||
"github.com/casdoor/goth/providers/line"
|
||||
"github.com/casdoor/goth/providers/linkedin"
|
||||
"github.com/casdoor/goth/providers/microsoftonline"
|
||||
"github.com/casdoor/goth/providers/paypal"
|
||||
"github.com/casdoor/goth/providers/salesforce"
|
||||
"github.com/casdoor/goth/providers/shopify"
|
||||
"github.com/casdoor/goth/providers/slack"
|
||||
"github.com/casdoor/goth/providers/steam"
|
||||
"github.com/casdoor/goth/providers/tumblr"
|
||||
"github.com/casdoor/goth/providers/twitter"
|
||||
"github.com/casdoor/goth/providers/yahoo"
|
||||
"github.com/casdoor/goth/providers/yandex"
|
||||
"github.com/casdoor/goth/providers/zoom"
|
||||
"github.com/markbates/goth"
|
||||
"github.com/markbates/goth/providers/amazon"
|
||||
"github.com/markbates/goth/providers/apple"
|
||||
"github.com/markbates/goth/providers/auth0"
|
||||
"github.com/markbates/goth/providers/azureadv2"
|
||||
"github.com/markbates/goth/providers/battlenet"
|
||||
"github.com/markbates/goth/providers/bitbucket"
|
||||
"github.com/markbates/goth/providers/box"
|
||||
"github.com/markbates/goth/providers/cloudfoundry"
|
||||
"github.com/markbates/goth/providers/dailymotion"
|
||||
"github.com/markbates/goth/providers/deezer"
|
||||
"github.com/markbates/goth/providers/digitalocean"
|
||||
"github.com/markbates/goth/providers/discord"
|
||||
"github.com/markbates/goth/providers/dropbox"
|
||||
"github.com/markbates/goth/providers/eveonline"
|
||||
"github.com/markbates/goth/providers/facebook"
|
||||
"github.com/markbates/goth/providers/fitbit"
|
||||
"github.com/markbates/goth/providers/gitea"
|
||||
"github.com/markbates/goth/providers/github"
|
||||
"github.com/markbates/goth/providers/gitlab"
|
||||
"github.com/markbates/goth/providers/google"
|
||||
"github.com/markbates/goth/providers/heroku"
|
||||
"github.com/markbates/goth/providers/influxcloud"
|
||||
"github.com/markbates/goth/providers/instagram"
|
||||
"github.com/markbates/goth/providers/intercom"
|
||||
"github.com/markbates/goth/providers/kakao"
|
||||
"github.com/markbates/goth/providers/lastfm"
|
||||
"github.com/markbates/goth/providers/line"
|
||||
"github.com/markbates/goth/providers/linkedin"
|
||||
"github.com/markbates/goth/providers/mailru"
|
||||
"github.com/markbates/goth/providers/meetup"
|
||||
"github.com/markbates/goth/providers/microsoftonline"
|
||||
"github.com/markbates/goth/providers/naver"
|
||||
"github.com/markbates/goth/providers/nextcloud"
|
||||
"github.com/markbates/goth/providers/onedrive"
|
||||
"github.com/markbates/goth/providers/oura"
|
||||
"github.com/markbates/goth/providers/patreon"
|
||||
"github.com/markbates/goth/providers/paypal"
|
||||
"github.com/markbates/goth/providers/salesforce"
|
||||
"github.com/markbates/goth/providers/shopify"
|
||||
"github.com/markbates/goth/providers/slack"
|
||||
"github.com/markbates/goth/providers/soundcloud"
|
||||
"github.com/markbates/goth/providers/spotify"
|
||||
"github.com/markbates/goth/providers/steam"
|
||||
"github.com/markbates/goth/providers/strava"
|
||||
"github.com/markbates/goth/providers/stripe"
|
||||
"github.com/markbates/goth/providers/tiktok"
|
||||
"github.com/markbates/goth/providers/tumblr"
|
||||
"github.com/markbates/goth/providers/twitch"
|
||||
"github.com/markbates/goth/providers/twitterv2"
|
||||
"github.com/markbates/goth/providers/typetalk"
|
||||
"github.com/markbates/goth/providers/uber"
|
||||
"github.com/markbates/goth/providers/wepay"
|
||||
"github.com/markbates/goth/providers/xero"
|
||||
"github.com/markbates/goth/providers/yahoo"
|
||||
"github.com/markbates/goth/providers/yammer"
|
||||
"github.com/markbates/goth/providers/yandex"
|
||||
"github.com/markbates/goth/providers/zoom"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
@ -74,14 +103,44 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
}
|
||||
case "AzureAD":
|
||||
idp = GothIdProvider{
|
||||
Provider: azuread.New(clientId, clientSecret, redirectUrl, nil),
|
||||
Session: &azuread.Session{},
|
||||
Provider: azureadv2.New(clientId, clientSecret, redirectUrl, azureadv2.ProviderOptions{Tenant: "common"}),
|
||||
Session: &azureadv2.Session{},
|
||||
}
|
||||
case "Auth0":
|
||||
idp = GothIdProvider{
|
||||
Provider: auth0.New(clientId, clientSecret, redirectUrl, "casdoor.auth0.com"),
|
||||
Session: &auth0.Session{},
|
||||
}
|
||||
case "BattleNet":
|
||||
idp = GothIdProvider{
|
||||
Provider: battlenet.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &battlenet.Session{},
|
||||
}
|
||||
case "Bitbucket":
|
||||
idp = GothIdProvider{
|
||||
Provider: bitbucket.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &bitbucket.Session{},
|
||||
}
|
||||
case "Box":
|
||||
idp = GothIdProvider{
|
||||
Provider: box.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &box.Session{},
|
||||
}
|
||||
case "CloudFoundry":
|
||||
idp = GothIdProvider{
|
||||
Provider: cloudfoundry.New("", clientId, clientSecret, redirectUrl),
|
||||
Session: &cloudfoundry.Session{},
|
||||
}
|
||||
case "Dailymotion":
|
||||
idp = GothIdProvider{
|
||||
Provider: dailymotion.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &dailymotion.Session{},
|
||||
}
|
||||
case "Deezer":
|
||||
idp = GothIdProvider{
|
||||
Provider: deezer.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &deezer.Session{},
|
||||
}
|
||||
case "DigitalOcean":
|
||||
idp = GothIdProvider{
|
||||
Provider: digitalocean.New(clientId, clientSecret, redirectUrl),
|
||||
@ -97,6 +156,16 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
Provider: dropbox.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &dropbox.Session{},
|
||||
}
|
||||
case "EveOnline":
|
||||
idp = GothIdProvider{
|
||||
Provider: eveonline.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &eveonline.Session{},
|
||||
}
|
||||
case "Fitbit":
|
||||
idp = GothIdProvider{
|
||||
Provider: fitbit.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &fitbit.Session{},
|
||||
}
|
||||
case "Facebook":
|
||||
idp = GothIdProvider{
|
||||
Provider: facebook.New(clientId, clientSecret, redirectUrl),
|
||||
@ -127,16 +196,31 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
Provider: heroku.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &heroku.Session{},
|
||||
}
|
||||
case "InfluxCloud":
|
||||
idp = GothIdProvider{
|
||||
Provider: influxcloud.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &influxcloud.Session{},
|
||||
}
|
||||
case "Instagram":
|
||||
idp = GothIdProvider{
|
||||
Provider: instagram.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &instagram.Session{},
|
||||
}
|
||||
case "Intercom":
|
||||
idp = GothIdProvider{
|
||||
Provider: intercom.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &intercom.Session{},
|
||||
}
|
||||
case "Kakao":
|
||||
idp = GothIdProvider{
|
||||
Provider: kakao.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &kakao.Session{},
|
||||
}
|
||||
case "Lastfm":
|
||||
idp = GothIdProvider{
|
||||
Provider: lastfm.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &lastfm.Session{},
|
||||
}
|
||||
case "Linkedin":
|
||||
idp = GothIdProvider{
|
||||
Provider: linkedin.New(clientId, clientSecret, redirectUrl),
|
||||
@ -147,11 +231,46 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
Provider: line.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &line.Session{},
|
||||
}
|
||||
case "Mailru":
|
||||
idp = GothIdProvider{
|
||||
Provider: mailru.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &mailru.Session{},
|
||||
}
|
||||
case "Meetup":
|
||||
idp = GothIdProvider{
|
||||
Provider: meetup.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &meetup.Session{},
|
||||
}
|
||||
case "MicrosoftOnline":
|
||||
idp = GothIdProvider{
|
||||
Provider: microsoftonline.New(clientId, clientSecret, redirectUrl),
|
||||
Session: µsoftonline.Session{},
|
||||
}
|
||||
case "Naver":
|
||||
idp = GothIdProvider{
|
||||
Provider: naver.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &naver.Session{},
|
||||
}
|
||||
case "Nextcloud":
|
||||
idp = GothIdProvider{
|
||||
Provider: nextcloud.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &nextcloud.Session{},
|
||||
}
|
||||
case "OneDrive":
|
||||
idp = GothIdProvider{
|
||||
Provider: onedrive.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &onedrive.Session{},
|
||||
}
|
||||
case "Oura":
|
||||
idp = GothIdProvider{
|
||||
Provider: oura.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &oura.Session{},
|
||||
}
|
||||
case "Patreon":
|
||||
idp = GothIdProvider{
|
||||
Provider: patreon.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &patreon.Session{},
|
||||
}
|
||||
case "Paypal":
|
||||
idp = GothIdProvider{
|
||||
Provider: paypal.New(clientId, clientSecret, redirectUrl),
|
||||
@ -172,26 +291,81 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
Provider: slack.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &slack.Session{},
|
||||
}
|
||||
case "Soundcloud":
|
||||
idp = GothIdProvider{
|
||||
Provider: soundcloud.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &soundcloud.Session{},
|
||||
}
|
||||
case "Spotify":
|
||||
idp = GothIdProvider{
|
||||
Provider: spotify.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &spotify.Session{},
|
||||
}
|
||||
case "Steam":
|
||||
idp = GothIdProvider{
|
||||
Provider: steam.New(clientSecret, redirectUrl),
|
||||
Session: &steam.Session{},
|
||||
}
|
||||
case "Strava":
|
||||
idp = GothIdProvider{
|
||||
Provider: strava.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &strava.Session{},
|
||||
}
|
||||
case "Stripe":
|
||||
idp = GothIdProvider{
|
||||
Provider: stripe.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &stripe.Session{},
|
||||
}
|
||||
case "TikTok":
|
||||
idp = GothIdProvider{
|
||||
Provider: tiktok.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &tiktok.Session{},
|
||||
}
|
||||
case "Tumblr":
|
||||
idp = GothIdProvider{
|
||||
Provider: tumblr.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &tumblr.Session{},
|
||||
}
|
||||
case "Twitch":
|
||||
idp = GothIdProvider{
|
||||
Provider: twitch.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &twitch.Session{},
|
||||
}
|
||||
case "Twitter":
|
||||
idp = GothIdProvider{
|
||||
Provider: twitter.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &twitter.Session{},
|
||||
Provider: twitterv2.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &twitterv2.Session{},
|
||||
}
|
||||
case "Typetalk":
|
||||
idp = GothIdProvider{
|
||||
Provider: typetalk.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &typetalk.Session{},
|
||||
}
|
||||
case "Uber":
|
||||
idp = GothIdProvider{
|
||||
Provider: uber.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &uber.Session{},
|
||||
}
|
||||
case "Wepay":
|
||||
idp = GothIdProvider{
|
||||
Provider: wepay.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &wepay.Session{},
|
||||
}
|
||||
case "Xero":
|
||||
idp = GothIdProvider{
|
||||
Provider: xero.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &xero.Session{},
|
||||
}
|
||||
case "Yahoo":
|
||||
idp = GothIdProvider{
|
||||
Provider: yahoo.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &yahoo.Session{},
|
||||
}
|
||||
case "Yammer":
|
||||
idp = GothIdProvider{
|
||||
Provider: yammer.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &yammer.Session{},
|
||||
}
|
||||
case "Yandex":
|
||||
idp = GothIdProvider{
|
||||
Provider: yandex.New(clientId, clientSecret, redirectUrl),
|
||||
@ -202,6 +376,8 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
Provider: zoom.New(clientId, clientSecret, redirectUrl),
|
||||
Session: &zoom.Session{},
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
return &idp
|
||||
@ -230,6 +406,9 @@ func (idp *GothIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
// to call the function to obtain accessToken
|
||||
value = url.Values{}
|
||||
value.Add("code", code)
|
||||
if idp.Provider.Name() == "twitterv2" || idp.Provider.Name() == "fitbit" {
|
||||
value.Add("oauth_verifier", "casdoor-verifier")
|
||||
}
|
||||
}
|
||||
accessToken, err := idp.Session.Authorize(idp.Provider, value)
|
||||
if err != nil {
|
||||
|
@ -98,7 +98,61 @@ func GetIdProvider(typ string, subType string, clientId string, clientSecret str
|
||||
return nil
|
||||
}
|
||||
|
||||
var gothList = []string{"Apple", "AzureAd", "Slack", "Steam"}
|
||||
var gothList = []string{
|
||||
"Apple",
|
||||
"AzureAD",
|
||||
"Slack",
|
||||
"Steam",
|
||||
"Line",
|
||||
"Amazon",
|
||||
"Auth0",
|
||||
"BattleNet",
|
||||
"Bitbucket",
|
||||
"Box",
|
||||
"CloudFoundry",
|
||||
"Dailymotion",
|
||||
"Deezer",
|
||||
"DigitalOcean",
|
||||
"Discord",
|
||||
"Dropbox",
|
||||
"EveOnline",
|
||||
"Fitbit",
|
||||
"Gitea",
|
||||
"Heroku",
|
||||
"InfluxCloud",
|
||||
"Instagram",
|
||||
"Intercom",
|
||||
"Kakao",
|
||||
"Lastfm",
|
||||
"Mailru",
|
||||
"Meetup",
|
||||
"MicrosoftOnline",
|
||||
"Naver",
|
||||
"Nextcloud",
|
||||
"OneDrive",
|
||||
"Oura",
|
||||
"Patreon",
|
||||
"Paypal",
|
||||
"SalesForce",
|
||||
"Shopify",
|
||||
"Soundcloud",
|
||||
"Spotify",
|
||||
"Strava",
|
||||
"Stripe",
|
||||
"TikTok",
|
||||
"Tumblr",
|
||||
"Twitch",
|
||||
"Twitter",
|
||||
"Typetalk",
|
||||
"Uber",
|
||||
"VK",
|
||||
"Wepay",
|
||||
"Xero",
|
||||
"Yahoo",
|
||||
"Yammer",
|
||||
"Yandex",
|
||||
"Zoom",
|
||||
}
|
||||
|
||||
func isGothSupport(provider string) bool {
|
||||
for _, value := range gothList {
|
||||
|
@ -156,5 +156,187 @@
|
||||
"autoSync": 0,
|
||||
"lastSync": ""
|
||||
}
|
||||
],
|
||||
"models": [
|
||||
{
|
||||
"owner": "",
|
||||
"name": "",
|
||||
"modelText": "",
|
||||
"displayName": ""
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"actions": [
|
||||
""
|
||||
],
|
||||
"displayName": "",
|
||||
"effect": "",
|
||||
"isEnabled": true,
|
||||
"model": "",
|
||||
"name": "",
|
||||
"owner": "",
|
||||
"resourceType": "",
|
||||
"resources": [
|
||||
""
|
||||
],
|
||||
"roles": [
|
||||
""
|
||||
],
|
||||
"users": [
|
||||
""
|
||||
]
|
||||
}
|
||||
],
|
||||
"payments": [
|
||||
{
|
||||
"currency": "",
|
||||
"detail": "",
|
||||
"displayName": "",
|
||||
"invoiceRemark": "",
|
||||
"invoiceTaxId": "",
|
||||
"invoiceTitle": "",
|
||||
"invoiceType": "",
|
||||
"invoiceUrl": "",
|
||||
"message": "",
|
||||
"name": "",
|
||||
"organization": "",
|
||||
"owner": "",
|
||||
"payUrl": "",
|
||||
"personEmail": "",
|
||||
"personIdCard": "",
|
||||
"personName": "",
|
||||
"personPhone": "",
|
||||
"price": 0,
|
||||
"productDisplayName": "",
|
||||
"productName": "",
|
||||
"provider": "",
|
||||
"returnUrl": "",
|
||||
"state": "",
|
||||
"tag": "",
|
||||
"type": "",
|
||||
"user": ""
|
||||
}
|
||||
],
|
||||
"products": [
|
||||
{
|
||||
"currency": "",
|
||||
"detail": "",
|
||||
"displayName": "",
|
||||
"image": "",
|
||||
"name": "",
|
||||
"owner": "",
|
||||
"price": 0,
|
||||
"providers": [
|
||||
""
|
||||
],
|
||||
"quantity": 0,
|
||||
"returnUrl": "",
|
||||
"sold": 0,
|
||||
"state": "",
|
||||
"tag": ""
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"owner": "",
|
||||
"name": "",
|
||||
"user": "",
|
||||
"provider": "",
|
||||
"application": "",
|
||||
"tag": "",
|
||||
"parent": "",
|
||||
"fileName": "",
|
||||
"fileType": "",
|
||||
"fileFormat": "",
|
||||
"url": "",
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"displayName": "",
|
||||
"isEnabled": true,
|
||||
"name": "",
|
||||
"owner": "",
|
||||
"roles": [
|
||||
""
|
||||
],
|
||||
"users": [
|
||||
""
|
||||
]
|
||||
}
|
||||
],
|
||||
"syncers": [
|
||||
{
|
||||
"affiliationTable": "",
|
||||
"avatarBaseUrl": "",
|
||||
"database": "",
|
||||
"databaseType": "",
|
||||
"errorText": "",
|
||||
"host": "",
|
||||
"isEnabled": true,
|
||||
"name": "",
|
||||
"organization": "",
|
||||
"owner": "",
|
||||
"password": "",
|
||||
"port": 0,
|
||||
"syncInterval": 0,
|
||||
"table": "",
|
||||
"tableColumns": [
|
||||
{
|
||||
"casdoorName": "",
|
||||
"isHashed": true,
|
||||
"name": "",
|
||||
"type": "",
|
||||
"values": [
|
||||
""
|
||||
]
|
||||
}
|
||||
],
|
||||
"tablePrimaryKey": "",
|
||||
"type": "",
|
||||
"user": ""
|
||||
}
|
||||
],
|
||||
"tokens": [
|
||||
{
|
||||
"accessToken": "",
|
||||
"application": "",
|
||||
"code": "",
|
||||
"codeChallenge": "",
|
||||
"codeExpireIn": 0,
|
||||
"codeIsUsed": true,
|
||||
"createdTime": "",
|
||||
"expiresIn": 0,
|
||||
"name": "",
|
||||
"organization": "",
|
||||
"owner": "",
|
||||
"refreshToken": "",
|
||||
"scope": "",
|
||||
"tokenType": "",
|
||||
"user": ""
|
||||
}
|
||||
],
|
||||
"webhooks": [
|
||||
{
|
||||
"contentType": "",
|
||||
"events": [
|
||||
""
|
||||
],
|
||||
"headers": [
|
||||
{
|
||||
"name": "",
|
||||
"value": ""
|
||||
}
|
||||
],
|
||||
"isEnabled": true,
|
||||
"isUserExtended": true,
|
||||
"method": "",
|
||||
"name": "",
|
||||
"organization": "",
|
||||
"owner": "",
|
||||
"url": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -25,10 +25,10 @@ import (
|
||||
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
||||
_ "github.com/go-sql-driver/mysql" // db = mysql
|
||||
_ "github.com/lib/pq" // db = postgres
|
||||
"xorm.io/xorm/migrate"
|
||||
//_ "github.com/mattn/go-sqlite3" // db = sqlite3
|
||||
_ "modernc.org/sqlite" // db = sqlite
|
||||
"xorm.io/core"
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/migrate"
|
||||
)
|
||||
|
||||
var adapter *Adapter
|
||||
@ -222,6 +222,11 @@ func (a *Adapter) createTable() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = a.Engine.Sync2(new(Session))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func GetSession(owner string, offset, limit int, field, value, sortField, sortOrder string) *xorm.Session {
|
||||
|
@ -16,7 +16,6 @@ package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
@ -51,28 +50,31 @@ type Application struct {
|
||||
EnableCodeSignin bool `json:"enableCodeSignin"`
|
||||
EnableSamlCompress bool `json:"enableSamlCompress"`
|
||||
EnableWebAuthn bool `json:"enableWebAuthn"`
|
||||
EnableLinkWithEmail bool `json:"enableLinkWithEmail"`
|
||||
SamlReplyUrl string `xorm:"varchar(100)" json:"samlReplyUrl"`
|
||||
Providers []*ProviderItem `xorm:"mediumtext" json:"providers"`
|
||||
SignupItems []*SignupItem `xorm:"varchar(1000)" json:"signupItems"`
|
||||
GrantTypes []string `xorm:"varchar(1000)" json:"grantTypes"`
|
||||
OrganizationObj *Organization `xorm:"-" json:"organizationObj"`
|
||||
|
||||
ClientId string `xorm:"varchar(100)" json:"clientId"`
|
||||
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
|
||||
RedirectUris []string `xorm:"varchar(1000)" json:"redirectUris"`
|
||||
TokenFormat string `xorm:"varchar(100)" json:"tokenFormat"`
|
||||
ExpireInHours int `json:"expireInHours"`
|
||||
RefreshExpireInHours int `json:"refreshExpireInHours"`
|
||||
SignupUrl string `xorm:"varchar(200)" json:"signupUrl"`
|
||||
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
|
||||
ForgetUrl string `xorm:"varchar(200)" json:"forgetUrl"`
|
||||
AffiliationUrl string `xorm:"varchar(100)" json:"affiliationUrl"`
|
||||
TermsOfUse string `xorm:"varchar(100)" json:"termsOfUse"`
|
||||
SignupHtml string `xorm:"mediumtext" json:"signupHtml"`
|
||||
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
|
||||
FormCss string `xorm:"text" json:"formCss"`
|
||||
FormOffset int `json:"formOffset"`
|
||||
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
|
||||
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
|
||||
ClientId string `xorm:"varchar(100)" json:"clientId"`
|
||||
ClientSecret string `xorm:"varchar(100)" json:"clientSecret"`
|
||||
RedirectUris []string `xorm:"varchar(1000)" json:"redirectUris"`
|
||||
TokenFormat string `xorm:"varchar(100)" json:"tokenFormat"`
|
||||
ExpireInHours int `json:"expireInHours"`
|
||||
RefreshExpireInHours int `json:"refreshExpireInHours"`
|
||||
SignupUrl string `xorm:"varchar(200)" json:"signupUrl"`
|
||||
SigninUrl string `xorm:"varchar(200)" json:"signinUrl"`
|
||||
ForgetUrl string `xorm:"varchar(200)" json:"forgetUrl"`
|
||||
AffiliationUrl string `xorm:"varchar(100)" json:"affiliationUrl"`
|
||||
TermsOfUse string `xorm:"varchar(100)" json:"termsOfUse"`
|
||||
SignupHtml string `xorm:"mediumtext" json:"signupHtml"`
|
||||
SigninHtml string `xorm:"mediumtext" json:"signinHtml"`
|
||||
ThemeData *ThemeData `xorm:"json" json:"themeData"`
|
||||
FormCss string `xorm:"text" json:"formCss"`
|
||||
FormOffset int `json:"formOffset"`
|
||||
FormSideHtml string `xorm:"mediumtext" json:"formSideHtml"`
|
||||
FormBackgroundUrl string `xorm:"varchar(200)" json:"formBackgroundUrl"`
|
||||
}
|
||||
|
||||
func GetApplicationCount(owner, field, value string) int {
|
||||
@ -85,6 +87,16 @@ func GetApplicationCount(owner, field, value string) int {
|
||||
return int(count)
|
||||
}
|
||||
|
||||
func GetOrganizationApplicationCount(owner, Organization, field, value string) int {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
count, err := session.Count(&Application{Organization: Organization})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return int(count)
|
||||
}
|
||||
|
||||
func GetApplications(owner string) []*Application {
|
||||
applications := []*Application{}
|
||||
err := adapter.Engine.Desc("created_time").Find(&applications, &Application{Owner: owner})
|
||||
@ -95,8 +107,18 @@ func GetApplications(owner string) []*Application {
|
||||
return applications
|
||||
}
|
||||
|
||||
func GetPaginationApplications(owner string, offset, limit int, field, value, sortField, sortOrder string) []*Application {
|
||||
func GetOrganizationApplications(owner string, organization string) []*Application {
|
||||
applications := []*Application{}
|
||||
err := adapter.Engine.Desc("created_time").Find(&applications, &Application{Owner: owner, Organization: organization})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return applications
|
||||
}
|
||||
|
||||
func GetPaginationApplications(owner string, offset, limit int, field, value, sortField, sortOrder string) []*Application {
|
||||
var applications []*Application
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&applications)
|
||||
if err != nil {
|
||||
@ -106,9 +128,10 @@ func GetPaginationApplications(owner string, offset, limit int, field, value, so
|
||||
return applications
|
||||
}
|
||||
|
||||
func GetApplicationsByOrganizationName(owner string, organization string) []*Application {
|
||||
func GetPaginationOrganizationApplications(owner, organization string, offset, limit int, field, value, sortField, sortOrder string) []*Application {
|
||||
applications := []*Application{}
|
||||
err := adapter.Engine.Desc("created_time").Find(&applications, &Application{Owner: owner, Organization: organization})
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&applications, &Application{Owner: owner, Organization: organization})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -132,7 +155,7 @@ func getProviderMap(owner string) map[string]*Provider {
|
||||
}
|
||||
|
||||
func extendApplicationWithProviders(application *Application) {
|
||||
m := getProviderMap(application.Owner)
|
||||
m := getProviderMap(application.Organization)
|
||||
for _, providerItem := range application.Providers {
|
||||
if provider, ok := m[providerItem.Name]; ok {
|
||||
providerItem.Provider = provider
|
||||
@ -265,7 +288,8 @@ func GetMaskedApplications(applications []*Application, userId string) []*Applic
|
||||
|
||||
func UpdateApplication(id string, application *Application) bool {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
if getApplication(owner, name) == nil {
|
||||
oldApplication := getApplication(owner, name)
|
||||
if oldApplication == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -280,6 +304,10 @@ func UpdateApplication(id string, application *Application) bool {
|
||||
}
|
||||
}
|
||||
|
||||
if oldApplication.ClientId != application.ClientId && GetApplicationByClientId(application.ClientId) != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, providerItem := range application.Providers {
|
||||
providerItem.Provider = nil
|
||||
}
|
||||
@ -303,6 +331,9 @@ func AddApplication(application *Application) bool {
|
||||
if application.ClientSecret == "" {
|
||||
application.ClientSecret = util.GenerateClientSecret()
|
||||
}
|
||||
if GetApplicationByClientId(application.ClientId) != nil {
|
||||
return false
|
||||
}
|
||||
for _, providerItem := range application.Providers {
|
||||
providerItem.Provider = nil
|
||||
}
|
||||
@ -332,56 +363,30 @@ func (application *Application) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", application.Owner, application.Name)
|
||||
}
|
||||
|
||||
func CheckRedirectUriValid(application *Application, redirectUri string) bool {
|
||||
validUri := false
|
||||
for _, tmpUri := range application.RedirectUris {
|
||||
tmpUriRegex := regexp.MustCompile(tmpUri)
|
||||
if tmpUriRegex.MatchString(redirectUri) || strings.Contains(redirectUri, tmpUri) {
|
||||
validUri = true
|
||||
func (application *Application) IsRedirectUriValid(redirectUri string) bool {
|
||||
isValid := false
|
||||
for _, targetUri := range application.RedirectUris {
|
||||
targetUriRegex := regexp.MustCompile(targetUri)
|
||||
if targetUriRegex.MatchString(redirectUri) || strings.Contains(redirectUri, targetUri) {
|
||||
isValid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return validUri
|
||||
return isValid
|
||||
}
|
||||
|
||||
func IsAllowOrigin(origin string) bool {
|
||||
allowOrigin := false
|
||||
originUrl, err := url.Parse(origin)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
rows, err := adapter.Engine.Cols("redirect_uris").Rows(&Application{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
application := Application{}
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&application)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, tmpRedirectUri := range application.RedirectUris {
|
||||
u1, err := url.Parse(tmpRedirectUri)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if u1.Scheme == originUrl.Scheme && u1.Host == originUrl.Host {
|
||||
allowOrigin = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if allowOrigin {
|
||||
break
|
||||
func IsOriginAllowed(origin string) bool {
|
||||
applications := GetApplications("")
|
||||
for _, application := range applications {
|
||||
if application.IsRedirectUriValid(origin) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return allowOrigin
|
||||
return false
|
||||
}
|
||||
|
||||
func getApplicationMap(organization string) map[string]*Application {
|
||||
applications := GetApplicationsByOrganizationName("admin", organization)
|
||||
applications := GetOrganizationApplications("admin", organization)
|
||||
|
||||
applicationMap := make(map[string]*Application)
|
||||
for _, application := range applications {
|
||||
|
@ -15,7 +15,7 @@
|
||||
package object
|
||||
|
||||
func (application *Application) GetProviderByCategory(category string) *Provider {
|
||||
providers := GetProviders(application.Owner)
|
||||
providers := GetProviders(application.Organization)
|
||||
m := map[string]*Provider{}
|
||||
for _, provider := range providers {
|
||||
if provider.Category != category {
|
||||
|
@ -60,7 +60,7 @@ func getPermanentAvatarUrl(organization string, username string, url string, upl
|
||||
}
|
||||
|
||||
fullFilePath := fmt.Sprintf("/avatar/%s/%s.png", organization, username)
|
||||
uploadedFileUrl, _ := getUploadFileUrl(defaultStorageProvider, fullFilePath, false)
|
||||
uploadedFileUrl, _ := GetUploadFileUrl(defaultStorageProvider, fullFilePath, false)
|
||||
|
||||
if upload {
|
||||
DownloadAndUpload(url, fullFilePath)
|
||||
|
@ -148,34 +148,7 @@ func (casbinAdapter *CasbinAdapter) getTable() string {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
func initEnforcer(modelObj *Model, casbinAdapter *CasbinAdapter) (*casbin.Enforcer, error) {
|
||||
// init Adapter
|
||||
if casbinAdapter.Adapter == nil {
|
||||
var dataSourceName string
|
||||
@ -191,20 +164,60 @@ func SyncPolicies(casbinAdapter *CasbinAdapter) []*xormadapter.CasbinRule {
|
||||
dataSourceName = strings.ReplaceAll(dataSourceName, "dbi.", "db.")
|
||||
}
|
||||
|
||||
casbinAdapter.Adapter, _ = xormadapter.NewAdapterByEngineWithTableName(NewAdapter(casbinAdapter.DatabaseType, dataSourceName, casbinAdapter.Database).Engine, casbinAdapter.getTable(), "")
|
||||
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
|
||||
modelObj := getModel(casbinAdapter.Owner, casbinAdapter.Model)
|
||||
m, err := model.NewModelFromString(modelObj.ModelText)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// init Enforcer
|
||||
enforcer, err := casbin.NewEnforcer(m, casbinAdapter.Adapter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
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 := getModel(casbinAdapter.Owner, casbinAdapter.Model)
|
||||
enforcer, err := initEnforcer(modelObj, casbinAdapter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
policies := matrixToCasbinRules("p", enforcer.GetPolicy())
|
||||
@ -212,5 +225,48 @@ func SyncPolicies(casbinAdapter *CasbinAdapter) []*xormadapter.CasbinRule {
|
||||
policies = append(policies, matrixToCasbinRules("g", enforcer.GetGroupingPolicy())...)
|
||||
}
|
||||
|
||||
return policies
|
||||
return policies, nil
|
||||
}
|
||||
|
||||
func UpdatePolicy(oldPolicy, newPolicy []string, casbinAdapter *CasbinAdapter) (bool, error) {
|
||||
modelObj := getModel(casbinAdapter.Owner, casbinAdapter.Model)
|
||||
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 := getModel(casbinAdapter.Owner, casbinAdapter.Model)
|
||||
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 := getModel(casbinAdapter.Owner, casbinAdapter.Model)
|
||||
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
|
||||
}
|
||||
|
110
object/check.go
110
object/check.go
@ -44,87 +44,87 @@ func init() {
|
||||
|
||||
func CheckUserSignup(application *Application, organization *Organization, username string, password string, displayName string, firstName string, lastName string, email string, phone string, affiliation string, lang string) string {
|
||||
if organization == nil {
|
||||
return i18n.Translate(lang, "OrgErr.DoNotExist")
|
||||
return i18n.Translate(lang, "check:Organization does not exist")
|
||||
}
|
||||
|
||||
if application.IsSignupItemVisible("Username") {
|
||||
if len(username) <= 1 {
|
||||
return i18n.Translate(lang, "UserErr.NameLessThanTwoCharacters")
|
||||
return i18n.Translate(lang, "check:Username must have at least 2 characters")
|
||||
}
|
||||
if unicode.IsDigit(rune(username[0])) {
|
||||
return i18n.Translate(lang, "UserErr.NameStartWithADigitErr")
|
||||
return i18n.Translate(lang, "check:Username cannot start with a digit")
|
||||
}
|
||||
if util.IsEmailValid(username) {
|
||||
return i18n.Translate(lang, "UserErr.NameIsEmailErr")
|
||||
return i18n.Translate(lang, "check:Username cannot be an email address")
|
||||
}
|
||||
if reWhiteSpace.MatchString(username) {
|
||||
return i18n.Translate(lang, "UserErr.NameCantainWhitSpaceErr")
|
||||
return i18n.Translate(lang, "check:Username cannot contain white spaces")
|
||||
}
|
||||
msg := CheckUsername(username, lang)
|
||||
if msg != "" {
|
||||
|
||||
if msg := CheckUsername(username, lang); msg != "" {
|
||||
return msg
|
||||
}
|
||||
|
||||
if HasUserByField(organization.Name, "name", username) {
|
||||
return i18n.Translate(lang, "UserErr.NameExistedErr")
|
||||
return i18n.Translate(lang, "check:Username already exists")
|
||||
}
|
||||
if HasUserByField(organization.Name, "email", email) {
|
||||
return i18n.Translate(lang, "EmailErr.ExistedErr")
|
||||
return i18n.Translate(lang, "check:Email already exists")
|
||||
}
|
||||
if HasUserByField(organization.Name, "phone", phone) {
|
||||
return i18n.Translate(lang, "PhoneErr.ExistedErr")
|
||||
return i18n.Translate(lang, "check:Phone already exists")
|
||||
}
|
||||
}
|
||||
|
||||
if len(password) <= 5 {
|
||||
return i18n.Translate(lang, "UserErr.PasswordLessThanSixCharacters")
|
||||
return i18n.Translate(lang, "check:Password must have at least 6 characters")
|
||||
}
|
||||
|
||||
if application.IsSignupItemVisible("Email") {
|
||||
if email == "" {
|
||||
if application.IsSignupItemRequired("Email") {
|
||||
return i18n.Translate(lang, "EmailErr.EmptyErr")
|
||||
return i18n.Translate(lang, "check:Email cannot be empty")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
if HasUserByField(organization.Name, "email", email) {
|
||||
return i18n.Translate(lang, "EmailErr.ExistedErr")
|
||||
return i18n.Translate(lang, "check:Email already exists")
|
||||
} else if !util.IsEmailValid(email) {
|
||||
return i18n.Translate(lang, "EmailErr.EmailInvalid")
|
||||
return i18n.Translate(lang, "check:Email is invalid")
|
||||
}
|
||||
}
|
||||
|
||||
if application.IsSignupItemVisible("Phone") {
|
||||
if phone == "" {
|
||||
if application.IsSignupItemRequired("Phone") {
|
||||
return i18n.Translate(lang, "PhoneErr.EmptyErr")
|
||||
return i18n.Translate(lang, "check:Phone cannot be empty")
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
if HasUserByField(organization.Name, "phone", phone) {
|
||||
return i18n.Translate(lang, "PhoneErr.ExistedErr")
|
||||
return i18n.Translate(lang, "check:Phone already exists")
|
||||
} else if organization.PhonePrefix == "86" && !util.IsPhoneCnValid(phone) {
|
||||
return i18n.Translate(lang, "PhoneErr.NumberInvalid")
|
||||
return i18n.Translate(lang, "check:Phone number is invalid")
|
||||
}
|
||||
}
|
||||
|
||||
if application.IsSignupItemVisible("Display name") {
|
||||
if application.GetSignupItemRule("Display name") == "First, last" && (firstName != "" || lastName != "") {
|
||||
if firstName == "" {
|
||||
return i18n.Translate(lang, "UserErr.FirstNameBlankErr")
|
||||
return i18n.Translate(lang, "check:FirstName cannot be blank")
|
||||
} else if lastName == "" {
|
||||
return i18n.Translate(lang, "UserErr.LastNameBlankErr")
|
||||
return i18n.Translate(lang, "check:LastName cannot be blank")
|
||||
}
|
||||
} else {
|
||||
if displayName == "" {
|
||||
return i18n.Translate(lang, "UserErr.DisplayNameBlankErr")
|
||||
return i18n.Translate(lang, "check:DisplayName cannot be blank")
|
||||
} else if application.GetSignupItemRule("Display name") == "Real name" {
|
||||
if !isValidRealName(displayName) {
|
||||
return i18n.Translate(lang, "UserErr.DisplayNameInvalid")
|
||||
return i18n.Translate(lang, "check:DisplayName is not valid real name")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,7 +132,7 @@ func CheckUserSignup(application *Application, organization *Organization, usern
|
||||
|
||||
if application.IsSignupItemVisible("Affiliation") {
|
||||
if affiliation == "" {
|
||||
return i18n.Translate(lang, "UserErr.AffiliationBlankErr")
|
||||
return i18n.Translate(lang, "check:Affiliation cannot be blank")
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,11 +143,11 @@ func checkSigninErrorTimes(user *User, lang string) string {
|
||||
if user.SigninWrongTimes >= SigninWrongTimesLimit {
|
||||
lastSignWrongTime, _ := time.Parse(time.RFC3339, user.LastSigninWrongTime)
|
||||
passedTime := time.Now().UTC().Sub(lastSignWrongTime)
|
||||
seconds := int(LastSignWrongTimeDuration.Seconds() - passedTime.Seconds())
|
||||
minutes := int(LastSignWrongTimeDuration.Minutes() - passedTime.Minutes())
|
||||
|
||||
// deny the login if the error times is greater than the limit and the last login time is less than the duration
|
||||
if seconds > 0 {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "AuthErr.WrongPasswordManyTimes"), seconds/60, seconds%60)
|
||||
if minutes > 0 {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "check:You have entered the wrong password or code too many times, please wait for %d minutes and try again"), minutes)
|
||||
}
|
||||
|
||||
// reset the error times
|
||||
@ -167,7 +167,7 @@ func CheckPassword(user *User, password string, lang string) string {
|
||||
|
||||
organization := GetOrganizationByUser(user)
|
||||
if organization == nil {
|
||||
return i18n.Translate(lang, "OrgErr.DoNotExist")
|
||||
return i18n.Translate(lang, "check:Organization does not exist")
|
||||
}
|
||||
|
||||
credManager := cred.GetCredManager(organization.PasswordType)
|
||||
@ -184,9 +184,9 @@ func CheckPassword(user *User, password string, lang string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
return recordSigninErrorInfo(user)
|
||||
return recordSigninErrorInfo(user, lang)
|
||||
} else {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "LoginErr.UnsupportedPasswordType"), organization.PasswordType)
|
||||
return fmt.Sprintf(i18n.Translate(lang, "check:unsupported password type: %s"), organization.PasswordType)
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ func checkLdapUserPassword(user *User, password string, lang string) (*User, str
|
||||
if len(searchResult.Entries) == 0 {
|
||||
continue
|
||||
} else if len(searchResult.Entries) > 1 {
|
||||
return nil, i18n.Translate(lang, "LdapErr.MultipleAccounts")
|
||||
return nil, i18n.Translate(lang, "check:Multiple accounts with same uid, please check your ldap server")
|
||||
}
|
||||
|
||||
dn := searchResult.Entries[0].DN
|
||||
@ -221,7 +221,7 @@ func checkLdapUserPassword(user *User, password string, lang string) (*User, str
|
||||
}
|
||||
|
||||
if !ldapLoginSuccess {
|
||||
return nil, i18n.Translate(lang, "LdapErr.PasswordWrong")
|
||||
return nil, i18n.Translate(lang, "check:Ldap user name or password incorrect")
|
||||
}
|
||||
return user, ""
|
||||
}
|
||||
@ -229,11 +229,11 @@ func checkLdapUserPassword(user *User, password string, lang string) (*User, str
|
||||
func CheckUserPassword(organization string, username string, password string, lang string) (*User, string) {
|
||||
user := GetUserByFields(organization, username)
|
||||
if user == nil || user.IsDeleted == true {
|
||||
return nil, i18n.Translate(lang, "UserErr.DoNotExistSignUp")
|
||||
return nil, fmt.Sprintf(i18n.Translate(lang, "general:The user: %s doesn't exist"), util.GetId(organization, username))
|
||||
}
|
||||
|
||||
if user.IsForbidden {
|
||||
return nil, i18n.Translate(lang, "LoginErr.UserIsForbidden")
|
||||
return nil, i18n.Translate(lang, "check:The user is forbidden to sign in, please contact the administrator")
|
||||
}
|
||||
|
||||
if user.Ldap != "" {
|
||||
@ -254,13 +254,13 @@ func filterField(field string) bool {
|
||||
|
||||
func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, lang string) (bool, error) {
|
||||
if requestUserId == "" {
|
||||
return false, fmt.Errorf(i18n.Translate(lang, "LoginErr.LoginFirst"))
|
||||
return false, fmt.Errorf(i18n.Translate(lang, "general:Please login first"))
|
||||
}
|
||||
|
||||
if userId != "" {
|
||||
targetUser := GetUser(userId)
|
||||
if targetUser == nil {
|
||||
return false, fmt.Errorf(i18n.Translate(lang, "UserErr.DoNotExist"), userId)
|
||||
return false, fmt.Errorf(i18n.Translate(lang, "general:The user: %s doesn't exist"), userId)
|
||||
}
|
||||
|
||||
userOwner = targetUser.Owner
|
||||
@ -272,7 +272,7 @@ func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, l
|
||||
} else {
|
||||
requestUser := GetUser(requestUserId)
|
||||
if requestUser == nil {
|
||||
return false, fmt.Errorf(i18n.Translate(lang, "LoginErr.SessionOutdated"))
|
||||
return false, fmt.Errorf(i18n.Translate(lang, "check:Session outdated, please login again"))
|
||||
}
|
||||
if requestUser.IsGlobalAdmin {
|
||||
hasPermission = true
|
||||
@ -287,7 +287,7 @@ func CheckUserPermission(requestUserId, userId, userOwner string, strict bool, l
|
||||
}
|
||||
}
|
||||
|
||||
return hasPermission, fmt.Errorf(i18n.Translate(lang, "LoginErr.NoPermission"))
|
||||
return hasPermission, fmt.Errorf(i18n.Translate(lang, "auth:Unauthorized operation"))
|
||||
}
|
||||
|
||||
func CheckAccessPermission(userId string, application *Application) (bool, error) {
|
||||
@ -313,8 +313,9 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
||||
return true, err
|
||||
}
|
||||
enforcer := getEnforcer(permission)
|
||||
allowed, err = enforcer.Enforce(userId, application.Name, "read")
|
||||
break
|
||||
if allowed, err = enforcer.Enforce(userId, application.Name, "read"); allowed {
|
||||
return allowed, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return allowed, err
|
||||
@ -322,9 +323,9 @@ func CheckAccessPermission(userId string, application *Application) (bool, error
|
||||
|
||||
func CheckUsername(username string, lang string) string {
|
||||
if username == "" {
|
||||
return i18n.Translate(lang, "UserErr.NameEmptyErr")
|
||||
return i18n.Translate(lang, "check:Empty username.")
|
||||
} else if len(username) > 39 {
|
||||
return i18n.Translate(lang, "UserErr.NameTooLang")
|
||||
return i18n.Translate(lang, "check:Username is too long (maximum is 39 characters).")
|
||||
}
|
||||
|
||||
exclude, _ := regexp.Compile("^[\u0021-\u007E]+$")
|
||||
@ -335,7 +336,34 @@ func CheckUsername(username string, lang string) string {
|
||||
// https://stackoverflow.com/questions/58726546/github-username-convention-using-regex
|
||||
re, _ := regexp.Compile("^[a-zA-Z0-9]+((?:-[a-zA-Z0-9]+)|(?:_[a-zA-Z0-9]+))*$")
|
||||
if !re.MatchString(username) {
|
||||
return i18n.Translate(lang, "UserErr.NameFormatErr")
|
||||
return i18n.Translate(lang, "check: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.")
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func CheckUpdateUser(oldUser *User, user *User, lang string) string {
|
||||
if user.DisplayName == "" {
|
||||
return i18n.Translate(lang, "user:Display name cannot be empty")
|
||||
}
|
||||
|
||||
if oldUser.Name != user.Name {
|
||||
if msg := CheckUsername(user.Name, lang); msg != "" {
|
||||
return msg
|
||||
}
|
||||
if HasUserByField(user.Owner, "name", user.Name) {
|
||||
return i18n.Translate(lang, "check:Username already exists")
|
||||
}
|
||||
}
|
||||
if oldUser.Email != user.Email {
|
||||
if HasUserByField(user.Name, "email", user.Email) {
|
||||
return i18n.Translate(lang, "check:Email already exists")
|
||||
}
|
||||
}
|
||||
if oldUser.Phone != user.Phone {
|
||||
if HasUserByField(user.Owner, "phone", user.Phone) {
|
||||
return i18n.Translate(lang, "check:Phone already exists")
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
|
@ -18,6 +18,8 @@ import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/i18n"
|
||||
)
|
||||
|
||||
var reRealName *regexp.Regexp
|
||||
@ -43,7 +45,7 @@ func resetUserSigninErrorTimes(user *User) {
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, user.IsGlobalAdmin)
|
||||
}
|
||||
|
||||
func recordSigninErrorInfo(user *User) string {
|
||||
func recordSigninErrorInfo(user *User, lang string) string {
|
||||
// increase failed login count
|
||||
user.SigninWrongTimes++
|
||||
|
||||
@ -56,9 +58,9 @@ func recordSigninErrorInfo(user *User) string {
|
||||
UpdateUser(user.GetId(), user, []string{"signin_wrong_times", "last_signin_wrong_time"}, user.IsGlobalAdmin)
|
||||
leftChances := SigninWrongTimesLimit - user.SigninWrongTimes
|
||||
if leftChances > 0 {
|
||||
return fmt.Sprintf("password is incorrect, you have %d remaining chances", leftChances)
|
||||
return fmt.Sprintf(i18n.Translate(lang, "check:password or code is incorrect, you have %d remaining chances"), leftChances)
|
||||
}
|
||||
|
||||
// don't show the chance error message if the user has no chance left
|
||||
return fmt.Sprintf("You have entered the wrong password too many times, please wait for %d minutes and try again", int(LastSignWrongTimeDuration.Minutes()))
|
||||
return fmt.Sprintf(i18n.Translate(lang, "check:You have entered the wrong password or code too many times, please wait for %d minutes and try again"), int(LastSignWrongTimeDuration.Minutes()))
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ func initBuiltInOrganization() bool {
|
||||
PhonePrefix: "86",
|
||||
DefaultAvatar: fmt.Sprintf("%s/img/casbin.svg", conf.GetConfigString("staticBaseUrl")),
|
||||
Tags: []string{},
|
||||
Languages: []string{"en", "zh", "es", "fr", "de", "ja", "ko", "ru"},
|
||||
InitScore: 2000,
|
||||
AccountItems: []*AccountItem{
|
||||
{Name: "Organization", Visible: true, ViewRule: "Public", ModifyRule: "Admin"},
|
||||
{Name: "ID", Visible: true, ViewRule: "Public", ModifyRule: "Immutable"},
|
||||
@ -157,7 +159,7 @@ func initBuiltInApplication() {
|
||||
},
|
||||
RedirectUris: []string{},
|
||||
ExpireInHours: 168,
|
||||
FormOffset: 8,
|
||||
FormOffset: 2,
|
||||
}
|
||||
AddApplication(application)
|
||||
}
|
||||
@ -221,7 +223,7 @@ func initBuiltInLdap() {
|
||||
}
|
||||
|
||||
func initBuiltInProvider() {
|
||||
provider := GetProvider("admin/provider_captcha_default")
|
||||
provider := GetProvider(util.GetId("admin", "provider_captcha_default"))
|
||||
if provider != nil {
|
||||
return
|
||||
}
|
||||
|
@ -23,6 +23,15 @@ type InitData struct {
|
||||
Certs []*Cert `json:"certs"`
|
||||
Providers []*Provider `json:"providers"`
|
||||
Ldaps []*Ldap `json:"ldaps"`
|
||||
Models []*Model `json:"models"`
|
||||
Permissions []*Permission `json:"permissions"`
|
||||
Payments []*Payment `json:"payments"`
|
||||
Products []*Product `json:"products"`
|
||||
Resources []*Resource `json:"resources"`
|
||||
Roles []*Role `json:"roles"`
|
||||
Syncers []*Syncer `json:"syncers"`
|
||||
Tokens []*Token `json:"tokens"`
|
||||
Webhooks []*Webhook `json:"webhooks"`
|
||||
}
|
||||
|
||||
func InitFromFile() {
|
||||
@ -46,6 +55,33 @@ func InitFromFile() {
|
||||
for _, ldap := range initData.Ldaps {
|
||||
initDefinedLdap(ldap)
|
||||
}
|
||||
for _, model := range initData.Models {
|
||||
initDefinedModel(model)
|
||||
}
|
||||
for _, permission := range initData.Permissions {
|
||||
initDefinedPermission(permission)
|
||||
}
|
||||
for _, payment := range initData.Payments {
|
||||
initDefinedPayment(payment)
|
||||
}
|
||||
for _, product := range initData.Products {
|
||||
initDefinedProduct(product)
|
||||
}
|
||||
for _, resource := range initData.Resources {
|
||||
initDefinedResource(resource)
|
||||
}
|
||||
for _, role := range initData.Roles {
|
||||
initDefinedRole(role)
|
||||
}
|
||||
for _, syncer := range initData.Syncers {
|
||||
initDefinedSyncer(syncer)
|
||||
}
|
||||
for _, token := range initData.Tokens {
|
||||
initDefinedToken(token)
|
||||
}
|
||||
for _, webhook := range initData.Webhooks {
|
||||
initDefinedWebhook(webhook)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +99,15 @@ func readInitDataFromFile(filePath string) *InitData {
|
||||
Certs: []*Cert{},
|
||||
Providers: []*Provider{},
|
||||
Ldaps: []*Ldap{},
|
||||
Models: []*Model{},
|
||||
Permissions: []*Permission{},
|
||||
Payments: []*Payment{},
|
||||
Products: []*Product{},
|
||||
Resources: []*Resource{},
|
||||
Roles: []*Role{},
|
||||
Syncers: []*Syncer{},
|
||||
Tokens: []*Token{},
|
||||
Webhooks: []*Webhook{},
|
||||
}
|
||||
err := util.JsonToStruct(s, data)
|
||||
if err != nil {
|
||||
@ -89,6 +134,41 @@ func readInitDataFromFile(filePath string) *InitData {
|
||||
application.RedirectUris = []string{}
|
||||
}
|
||||
}
|
||||
for _, permission := range data.Permissions {
|
||||
if permission.Actions == nil {
|
||||
permission.Actions = []string{}
|
||||
}
|
||||
if permission.Resources == nil {
|
||||
permission.Resources = []string{}
|
||||
}
|
||||
if permission.Roles == nil {
|
||||
permission.Roles = []string{}
|
||||
}
|
||||
if permission.Users == nil {
|
||||
permission.Users = []string{}
|
||||
}
|
||||
}
|
||||
for _, role := range data.Roles {
|
||||
if role.Roles == nil {
|
||||
role.Roles = []string{}
|
||||
}
|
||||
if role.Users == nil {
|
||||
role.Users = []string{}
|
||||
}
|
||||
}
|
||||
for _, syncer := range data.Syncers {
|
||||
if syncer.TableColumns == nil {
|
||||
syncer.TableColumns = []*TableColumn{}
|
||||
}
|
||||
}
|
||||
for _, webhook := range data.Webhooks {
|
||||
if webhook.Events == nil {
|
||||
webhook.Events = []string{}
|
||||
}
|
||||
if webhook.Headers == nil {
|
||||
webhook.Headers = []*Header{}
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
@ -168,9 +248,90 @@ func initDefinedLdap(ldap *Ldap) {
|
||||
}
|
||||
|
||||
func initDefinedProvider(provider *Provider) {
|
||||
existed := GetProvider(provider.GetId())
|
||||
existed := GetProvider(util.GetId("admin", provider.Name))
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
AddProvider(provider)
|
||||
}
|
||||
|
||||
func initDefinedModel(model *Model) {
|
||||
existed := GetModel(model.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
model.CreatedTime = util.GetCurrentTime()
|
||||
AddModel(model)
|
||||
}
|
||||
|
||||
func initDefinedPermission(permission *Permission) {
|
||||
existed := GetPermission(permission.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
permission.CreatedTime = util.GetCurrentTime()
|
||||
AddPermission(permission)
|
||||
}
|
||||
|
||||
func initDefinedPayment(payment *Payment) {
|
||||
existed := GetPayment(payment.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
payment.CreatedTime = util.GetCurrentTime()
|
||||
AddPayment(payment)
|
||||
}
|
||||
|
||||
func initDefinedProduct(product *Product) {
|
||||
existed := GetProduct(product.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
product.CreatedTime = util.GetCurrentTime()
|
||||
AddProduct(product)
|
||||
}
|
||||
|
||||
func initDefinedResource(resource *Resource) {
|
||||
existed := GetResource(resource.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
resource.CreatedTime = util.GetCurrentTime()
|
||||
AddResource(resource)
|
||||
}
|
||||
|
||||
func initDefinedRole(role *Role) {
|
||||
existed := GetRole(role.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
role.CreatedTime = util.GetCurrentTime()
|
||||
AddRole(role)
|
||||
}
|
||||
|
||||
func initDefinedSyncer(syncer *Syncer) {
|
||||
existed := GetSyncer(syncer.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
syncer.CreatedTime = util.GetCurrentTime()
|
||||
AddSyncer(syncer)
|
||||
}
|
||||
|
||||
func initDefinedToken(token *Token) {
|
||||
existed := GetToken(token.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
token.CreatedTime = util.GetCurrentTime()
|
||||
AddToken(token)
|
||||
}
|
||||
|
||||
func initDefinedWebhook(webhook *Webhook) {
|
||||
existed := GetWebhook(webhook.GetId())
|
||||
if existed != nil {
|
||||
return
|
||||
}
|
||||
webhook.CreatedTime = util.GetCurrentTime()
|
||||
AddWebhook(webhook)
|
||||
}
|
||||
|
@ -68,14 +68,14 @@ func getModel(owner string, name string) *Model {
|
||||
return nil
|
||||
}
|
||||
|
||||
model := Model{Owner: owner, Name: name}
|
||||
existed, err := adapter.Engine.Get(&model)
|
||||
m := Model{Owner: owner, Name: name}
|
||||
existed, err := adapter.Engine.Get(&m)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if existed {
|
||||
return &model
|
||||
return &m
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
@ -86,6 +86,17 @@ func GetModel(id string) *Model {
|
||||
return getModel(owner, name)
|
||||
}
|
||||
|
||||
func UpdateModelWithCheck(id string, modelObj *Model) error {
|
||||
// check model grammar
|
||||
_, err := model.NewModelFromString(modelObj.ModelText)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
UpdateModel(id, modelObj)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UpdateModel(id string, modelObj *Model) bool {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
if getModel(owner, name) == nil {
|
||||
@ -98,11 +109,6 @@ func UpdateModel(id string, modelObj *Model) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
// check model grammar
|
||||
_, err := model.NewModelFromString(modelObj.ModelText)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(modelObj)
|
||||
if err != nil {
|
||||
@ -152,3 +158,7 @@ func modelChangeTrigger(oldName string, newName string) error {
|
||||
|
||||
return session.Commit()
|
||||
}
|
||||
|
||||
func HasRoleDefinition(m model.Model) bool {
|
||||
return m["g"] != nil
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ type OidcDiscovery struct {
|
||||
ClaimsSupported []string `json:"claims_supported"`
|
||||
RequestParameterSupported bool `json:"request_parameter_supported"`
|
||||
RequestObjectSigningAlgValuesSupported []string `json:"request_object_signing_alg_values_supported"`
|
||||
EndSessionEndpoint string `json:"end_session_endpoint"`
|
||||
}
|
||||
|
||||
func getOriginFromHost(host string) (string, string) {
|
||||
@ -76,7 +77,7 @@ func GetOidcDiscovery(host string) OidcDiscovery {
|
||||
JwksUri: fmt.Sprintf("%s/.well-known/jwks", originBackend),
|
||||
IntrospectionEndpoint: fmt.Sprintf("%s/api/login/oauth/introspect", originBackend),
|
||||
ResponseTypesSupported: []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none"},
|
||||
ResponseModesSupported: []string{"login", "code", "link"},
|
||||
ResponseModesSupported: []string{"query", "fragment", "login", "code", "link"},
|
||||
GrantTypesSupported: []string{"password", "authorization_code"},
|
||||
SubjectTypesSupported: []string{"public"},
|
||||
IdTokenSigningAlgValuesSupported: []string{"RS256"},
|
||||
@ -84,6 +85,7 @@ func GetOidcDiscovery(host string) OidcDiscovery {
|
||||
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"},
|
||||
RequestParameterSupported: true,
|
||||
RequestObjectSigningAlgValuesSupported: []string{"HS256", "HS384", "HS512"},
|
||||
EndSessionEndpoint: fmt.Sprintf("%s/api/logout", originBackend),
|
||||
}
|
||||
|
||||
return oidcDiscovery
|
||||
|
@ -31,23 +31,34 @@ type AccountItem struct {
|
||||
ModifyRule string `json:"modifyRule"`
|
||||
}
|
||||
|
||||
type ThemeData struct {
|
||||
ThemeType string `xorm:"varchar(30)" json:"themeType"`
|
||||
ColorPrimary string `xorm:"varchar(10)" json:"colorPrimary"`
|
||||
BorderRadius int `xorm:"int" json:"borderRadius"`
|
||||
IsCompact bool `xorm:"bool" json:"isCompact"`
|
||||
IsEnabled bool `xorm:"bool" json:"isEnabled"`
|
||||
}
|
||||
|
||||
type Organization 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"`
|
||||
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
WebsiteUrl string `xorm:"varchar(100)" json:"websiteUrl"`
|
||||
Favicon string `xorm:"varchar(100)" json:"favicon"`
|
||||
PasswordType string `xorm:"varchar(100)" json:"passwordType"`
|
||||
PasswordSalt string `xorm:"varchar(100)" json:"passwordSalt"`
|
||||
PhonePrefix string `xorm:"varchar(10)" json:"phonePrefix"`
|
||||
DefaultAvatar string `xorm:"varchar(100)" json:"defaultAvatar"`
|
||||
DefaultApplication string `xorm:"varchar(100)" json:"defaultApplication"`
|
||||
Tags []string `xorm:"mediumtext" json:"tags"`
|
||||
MasterPassword string `xorm:"varchar(100)" json:"masterPassword"`
|
||||
EnableSoftDeletion bool `json:"enableSoftDeletion"`
|
||||
IsProfilePublic bool `json:"isProfilePublic"`
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
WebsiteUrl string `xorm:"varchar(100)" json:"websiteUrl"`
|
||||
Favicon string `xorm:"varchar(100)" json:"favicon"`
|
||||
PasswordType string `xorm:"varchar(100)" json:"passwordType"`
|
||||
PasswordSalt string `xorm:"varchar(100)" json:"passwordSalt"`
|
||||
PhonePrefix string `xorm:"varchar(10)" json:"phonePrefix"`
|
||||
DefaultAvatar string `xorm:"varchar(100)" json:"defaultAvatar"`
|
||||
DefaultApplication string `xorm:"varchar(100)" json:"defaultApplication"`
|
||||
Tags []string `xorm:"mediumtext" json:"tags"`
|
||||
Languages []string `xorm:"varchar(255)" json:"languages"`
|
||||
ThemeData *ThemeData `xorm:"json" json:"themeData"`
|
||||
MasterPassword string `xorm:"varchar(100)" json:"masterPassword"`
|
||||
InitScore int `json:"initScore"`
|
||||
EnableSoftDeletion bool `json:"enableSoftDeletion"`
|
||||
IsProfilePublic bool `json:"isProfilePublic"`
|
||||
|
||||
AccountItems []*AccountItem `xorm:"varchar(3000)" json:"accountItems"`
|
||||
}
|
||||
@ -202,15 +213,15 @@ func GetAccountItemByName(name string, organization *Organization) *AccountItem
|
||||
func CheckAccountItemModifyRule(accountItem *AccountItem, user *User, lang string) (bool, string) {
|
||||
switch accountItem.ModifyRule {
|
||||
case "Admin":
|
||||
if !(user.IsAdmin || user.IsGlobalAdmin) {
|
||||
return false, fmt.Sprintf(i18n.Translate(lang, "OrgErr.OnlyAdmin"), accountItem.Name)
|
||||
if user == nil || !user.IsAdmin && !user.IsGlobalAdmin {
|
||||
return false, fmt.Sprintf(i18n.Translate(lang, "organization:Only admin can modify the %s."), accountItem.Name)
|
||||
}
|
||||
case "Immutable":
|
||||
return false, fmt.Sprintf(i18n.Translate(lang, "OrgErr.Immutable"), accountItem.Name)
|
||||
return false, fmt.Sprintf(i18n.Translate(lang, "organization:The %s is immutable."), accountItem.Name)
|
||||
case "Self":
|
||||
break
|
||||
default:
|
||||
return false, fmt.Sprintf(i18n.Translate(lang, "OrgErr.UnknownModifyRule"), accountItem.ModifyRule)
|
||||
return false, fmt.Sprintf(i18n.Translate(lang, "organization:Unknown modify rule %s."), accountItem.ModifyRule)
|
||||
}
|
||||
return true, ""
|
||||
}
|
||||
@ -222,7 +233,12 @@ func GetDefaultApplication(id string) (*Application, error) {
|
||||
}
|
||||
|
||||
if organization.DefaultApplication != "" {
|
||||
return getApplication("admin", organization.DefaultApplication), fmt.Errorf("The default application: %s does not exist", organization.DefaultApplication)
|
||||
defaultApplication := getApplication("admin", organization.DefaultApplication)
|
||||
if defaultApplication == nil {
|
||||
return nil, fmt.Errorf("The default application: %s does not exist", organization.DefaultApplication)
|
||||
} else {
|
||||
return defaultApplication, nil
|
||||
}
|
||||
}
|
||||
|
||||
applications := []*Application{}
|
||||
|
@ -35,7 +35,7 @@ type Payment struct {
|
||||
ProductName string `xorm:"varchar(100)" json:"productName"`
|
||||
ProductDisplayName string `xorm:"varchar(100)" json:"productDisplayName"`
|
||||
|
||||
Detail string `xorm:"varchar(100)" json:"detail"`
|
||||
Detail string `xorm:"varchar(255)" json:"detail"`
|
||||
Tag string `xorm:"varchar(100)" json:"tag"`
|
||||
Currency string `xorm:"varchar(100)" json:"currency"`
|
||||
Price float64 `json:"price"`
|
||||
|
@ -57,6 +57,40 @@ type PermissionRule struct {
|
||||
Id string `xorm:"varchar(100) index not null default ''" json:"id"`
|
||||
}
|
||||
|
||||
const (
|
||||
builtInAvailableField = 5 // Casdoor built-in adapter, use V5 to filter permission, so has 5 available field
|
||||
builtInAdapter = "permission_rule"
|
||||
)
|
||||
|
||||
func (p *Permission) GetId() string {
|
||||
return util.GetId(p.Owner, p.Name)
|
||||
}
|
||||
|
||||
func (p *PermissionRule) GetRequest(adapterName string, permissionId string) ([]interface{}, error) {
|
||||
request := []interface{}{p.V0, p.V1, p.V2}
|
||||
|
||||
if p.V3 != "" {
|
||||
request = append(request, p.V3)
|
||||
}
|
||||
|
||||
if p.V4 != "" {
|
||||
request = append(request, p.V4)
|
||||
}
|
||||
|
||||
if adapterName == builtInAdapter {
|
||||
if p.V5 != "" {
|
||||
return nil, fmt.Errorf("too many parameters. The maximum parameter number cannot exceed %d", builtInAvailableField)
|
||||
}
|
||||
request = append(request, permissionId)
|
||||
return request, nil
|
||||
} else {
|
||||
if p.V5 != "" {
|
||||
request = append(request, p.V5)
|
||||
}
|
||||
return request, nil
|
||||
}
|
||||
}
|
||||
|
||||
func GetPermissionCount(owner, field, value string) int {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
count, err := session.Count(&Permission{})
|
||||
@ -111,7 +145,33 @@ func GetPermission(id string) *Permission {
|
||||
return getPermission(owner, name)
|
||||
}
|
||||
|
||||
// checkPermissionValid verifies if the permission is valid
|
||||
func checkPermissionValid(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
enforcer.EnableAutoSave(false)
|
||||
|
||||
policies := getPolicies(permission)
|
||||
_, err := enforcer.AddPolicies(policies)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if !HasRoleDefinition(enforcer.GetModel()) {
|
||||
permission.Roles = []string{}
|
||||
return
|
||||
}
|
||||
|
||||
groupingPolicies := getGroupingPolicies(permission)
|
||||
if len(groupingPolicies) > 0 {
|
||||
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func UpdatePermission(id string, permission *Permission) bool {
|
||||
checkPermissionValid(permission)
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
oldPermission := getPermission(owner, name)
|
||||
if oldPermission == nil {
|
||||
@ -124,6 +184,7 @@ func UpdatePermission(id string, permission *Permission) bool {
|
||||
}
|
||||
|
||||
if affected != 0 {
|
||||
removeGroupingPolicies(oldPermission)
|
||||
removePolicies(oldPermission)
|
||||
if oldPermission.Adapter != "" && oldPermission.Adapter != permission.Adapter {
|
||||
isEmpty, _ := adapter.Engine.IsTableEmpty(oldPermission.Adapter)
|
||||
@ -134,6 +195,7 @@ func UpdatePermission(id string, permission *Permission) bool {
|
||||
}
|
||||
}
|
||||
}
|
||||
addGroupingPolicies(permission)
|
||||
addPolicies(permission)
|
||||
}
|
||||
|
||||
@ -147,6 +209,7 @@ func AddPermission(permission *Permission) bool {
|
||||
}
|
||||
|
||||
if affected != 0 {
|
||||
addGroupingPolicies(permission)
|
||||
addPolicies(permission)
|
||||
}
|
||||
|
||||
@ -160,6 +223,7 @@ func DeletePermission(permission *Permission) bool {
|
||||
}
|
||||
|
||||
if affected != 0 {
|
||||
removeGroupingPolicies(permission)
|
||||
removePolicies(permission)
|
||||
if permission.Adapter != "" && permission.Adapter != "permission_rule" {
|
||||
isEmpty, _ := adapter.Engine.IsTableEmpty(permission.Adapter)
|
||||
@ -175,10 +239,6 @@ func DeletePermission(permission *Permission) bool {
|
||||
return affected != 0
|
||||
}
|
||||
|
||||
func (permission *Permission) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", permission.Owner, permission.Name)
|
||||
}
|
||||
|
||||
func GetPermissionsByUser(userId string) []*Permission {
|
||||
permissions := []*Permission{}
|
||||
err := adapter.Engine.Where("users like ?", "%"+userId+"%").Find(&permissions)
|
||||
@ -249,3 +309,12 @@ func ContainsAsterisk(userId string, users []string) bool {
|
||||
|
||||
return containsAsterisk
|
||||
}
|
||||
|
||||
func GetMaskedPermissions(permissions []*Permission) []*Permission {
|
||||
for _, permission := range permissions {
|
||||
permission.Users = nil
|
||||
permission.Submitter = ""
|
||||
}
|
||||
|
||||
return permissions
|
||||
}
|
||||
|
@ -15,9 +15,11 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/casbin/casbin/v2/config"
|
||||
"github.com/casbin/casbin/v2/model"
|
||||
xormadapter "github.com/casbin/xorm-adapter/v3"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
@ -29,105 +31,125 @@ func getEnforcer(permission *Permission) *casbin.Enforcer {
|
||||
tableName = permission.Adapter
|
||||
}
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
adapter, err := xormadapter.NewAdapterWithTableName(conf.GetConfigString("driverName"), conf.GetConfigDataSourceName()+conf.GetConfigString("dbName"), tableName, tableNamePrefix, true)
|
||||
driverName := conf.GetConfigString("driverName")
|
||||
dataSourceName := conf.GetConfigRealDataSourceName(driverName)
|
||||
adapter, err := xormadapter.NewAdapterWithTableName(driverName, dataSourceName, tableName, tableNamePrefix, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
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 = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
|
||||
permissionModel := getModel(permission.Owner, permission.Model)
|
||||
m := model.Model{}
|
||||
if permissionModel != nil {
|
||||
modelText = permissionModel.ModelText
|
||||
m, err = GetBuiltInModel(permissionModel.ModelText)
|
||||
} else {
|
||||
m, err = GetBuiltInModel("")
|
||||
}
|
||||
m, err := model.NewModelFromString(modelText)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
policyFilter := xormadapter.Filter{}
|
||||
|
||||
if !HasRoleDefinition(m) {
|
||||
policyFilter.Ptype = []string{"p"}
|
||||
err = adapter.LoadFilteredPolicy(m, policyFilter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
enforcer, err := casbin.NewEnforcer(m, adapter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// load Policy with a specific Permission
|
||||
policyFilter.V5 = []string{permission.GetId()}
|
||||
err = enforcer.LoadFilteredPolicy(policyFilter)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return enforcer
|
||||
}
|
||||
|
||||
func getPolicies(permission *Permission) ([][]string, [][]string) {
|
||||
func getPolicies(permission *Permission) [][]string {
|
||||
var policies [][]string
|
||||
var groupingPolicies [][]string
|
||||
|
||||
permissionId := permission.GetId()
|
||||
domainExist := len(permission.Domains) > 0
|
||||
|
||||
for _, user := range permission.Users {
|
||||
for _, resource := range permission.Resources {
|
||||
for _, action := range permission.Actions {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
policies = append(policies, []string{user, domain, resource, strings.ToLower(action)})
|
||||
policies = append(policies, []string{user, domain, resource, strings.ToLower(action), "", permissionId})
|
||||
}
|
||||
} else {
|
||||
policies = append(policies, []string{user, resource, strings.ToLower(action)})
|
||||
policies = append(policies, []string{user, resource, strings.ToLower(action), "", "", permissionId})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, role := range permission.Roles {
|
||||
roleObj := GetRole(role)
|
||||
for _, subUser := range roleObj.Users {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
groupingPolicies = append(groupingPolicies, []string{subUser, domain, role})
|
||||
}
|
||||
} else {
|
||||
groupingPolicies = append(groupingPolicies, []string{subUser, role})
|
||||
}
|
||||
}
|
||||
for _, subRole := range roleObj.Roles {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
groupingPolicies = append(groupingPolicies, []string{subRole, domain, role})
|
||||
}
|
||||
} else {
|
||||
groupingPolicies = append(groupingPolicies, []string{subRole, role})
|
||||
}
|
||||
}
|
||||
for _, resource := range permission.Resources {
|
||||
for _, action := range permission.Actions {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
policies = append(policies, []string{role, domain, resource, strings.ToLower(action)})
|
||||
policies = append(policies, []string{role, domain, resource, strings.ToLower(action), "", permissionId})
|
||||
}
|
||||
} else {
|
||||
policies = append(policies, []string{role, resource, strings.ToLower(action)})
|
||||
policies = append(policies, []string{role, resource, strings.ToLower(action), "", "", permissionId})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return policies, groupingPolicies
|
||||
|
||||
return policies
|
||||
}
|
||||
|
||||
func getGroupingPolicies(permission *Permission) [][]string {
|
||||
var groupingPolicies [][]string
|
||||
|
||||
domainExist := len(permission.Domains) > 0
|
||||
permissionId := permission.GetId()
|
||||
|
||||
for _, role := range permission.Roles {
|
||||
roleObj := GetRole(role)
|
||||
if roleObj == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, subUser := range roleObj.Users {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
groupingPolicies = append(groupingPolicies, []string{subUser, domain, role, "", "", permissionId})
|
||||
}
|
||||
} else {
|
||||
groupingPolicies = append(groupingPolicies, []string{subUser, role, "", "", "", permissionId})
|
||||
}
|
||||
}
|
||||
|
||||
for _, subRole := range roleObj.Roles {
|
||||
if domainExist {
|
||||
for _, domain := range permission.Domains {
|
||||
groupingPolicies = append(groupingPolicies, []string{subRole, domain, role, "", "", permissionId})
|
||||
}
|
||||
} else {
|
||||
groupingPolicies = append(groupingPolicies, []string{subRole, role, "", "", "", permissionId})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return groupingPolicies
|
||||
}
|
||||
|
||||
func addPolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
policies, groupingPolicies := getPolicies(permission)
|
||||
|
||||
if len(groupingPolicies) > 0 {
|
||||
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
policies := getPolicies(permission)
|
||||
|
||||
_, err := enforcer.AddPolicies(policies)
|
||||
if err != nil {
|
||||
@ -135,9 +157,21 @@ func addPolicies(permission *Permission) {
|
||||
}
|
||||
}
|
||||
|
||||
func removePolicies(permission *Permission) {
|
||||
func addGroupingPolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
policies, groupingPolicies := getPolicies(permission)
|
||||
groupingPolicies := getGroupingPolicies(permission)
|
||||
|
||||
if len(groupingPolicies) > 0 {
|
||||
_, err := enforcer.AddGroupingPolicies(groupingPolicies)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeGroupingPolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
groupingPolicies := getGroupingPolicies(permission)
|
||||
|
||||
if len(groupingPolicies) > 0 {
|
||||
_, err := enforcer.RemoveGroupingPolicies(groupingPolicies)
|
||||
@ -145,6 +179,11 @@ func removePolicies(permission *Permission) {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removePolicies(permission *Permission) {
|
||||
enforcer := getEnforcer(permission)
|
||||
policies := getPolicies(permission)
|
||||
|
||||
_, err := enforcer.RemovePolicies(policies)
|
||||
if err != nil {
|
||||
@ -152,20 +191,24 @@ func removePolicies(permission *Permission) {
|
||||
}
|
||||
}
|
||||
|
||||
func Enforce(userId string, permissionRule *PermissionRule) bool {
|
||||
func Enforce(permissionRule *PermissionRule) bool {
|
||||
permission := GetPermission(permissionRule.Id)
|
||||
enforcer := getEnforcer(permission)
|
||||
allow, err := enforcer.Enforce(userId, permissionRule.V1, permissionRule.V2)
|
||||
|
||||
request, _ := permissionRule.GetRequest(builtInAdapter, permissionRule.Id)
|
||||
|
||||
allow, err := enforcer.Enforce(request...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return allow
|
||||
}
|
||||
|
||||
func BatchEnforce(userId string, permissionRules []PermissionRule) []bool {
|
||||
func BatchEnforce(permissionRules []PermissionRule) []bool {
|
||||
var requests [][]interface{}
|
||||
for _, permissionRule := range permissionRules {
|
||||
requests = append(requests, []interface{}{userId, permissionRule.V1, permissionRule.V2})
|
||||
request, _ := permissionRule.GetRequest(builtInAdapter, permissionRule.Id)
|
||||
requests = append(requests, request)
|
||||
}
|
||||
permission := GetPermission(permissionRules[0].Id)
|
||||
enforcer := getEnforcer(permission)
|
||||
@ -210,3 +253,46 @@ func GetAllRoles(userId string) []string {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func GetBuiltInModel(modelText string) (model.Model, error) {
|
||||
if modelText == "" {
|
||||
modelText = `
|
||||
[request_definition]
|
||||
r = sub, obj, act
|
||||
|
||||
[policy_definition]
|
||||
p = sub, obj, act, "", "", permissionId
|
||||
|
||||
[role_definition]
|
||||
g = _, _
|
||||
|
||||
[policy_effect]
|
||||
e = some(where (p.eft == allow))
|
||||
|
||||
[matchers]
|
||||
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act`
|
||||
return model.NewModelFromString(modelText)
|
||||
} else {
|
||||
cfg, err := config.NewConfigFromText(modelText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// load [policy_definition]
|
||||
policyDefinition := strings.Split(cfg.String("policy_definition::p"), ",")
|
||||
fieldsNum := len(policyDefinition)
|
||||
if fieldsNum > builtInAvailableField {
|
||||
panic(fmt.Errorf("the maximum policy_definition field number cannot exceed %d", builtInAvailableField))
|
||||
}
|
||||
// filled empty field with "" and V5 with "permissionId"
|
||||
for i := builtInAvailableField - fieldsNum; i > 0; i-- {
|
||||
policyDefinition = append(policyDefinition, "")
|
||||
}
|
||||
policyDefinition = append(policyDefinition, "permissionId")
|
||||
|
||||
m, _ := model.NewModelFromString(modelText)
|
||||
m.AddDef("p", "p", strings.Join(policyDefinition, ","))
|
||||
|
||||
return m, err
|
||||
}
|
||||
}
|
||||
|
@ -27,15 +27,16 @@ type Product struct {
|
||||
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
|
||||
Image string `xorm:"varchar(100)" json:"image"`
|
||||
Detail string `xorm:"varchar(100)" json:"detail"`
|
||||
Tag string `xorm:"varchar(100)" json:"tag"`
|
||||
Currency string `xorm:"varchar(100)" json:"currency"`
|
||||
Price float64 `json:"price"`
|
||||
Quantity int `json:"quantity"`
|
||||
Sold int `json:"sold"`
|
||||
Providers []string `xorm:"varchar(100)" json:"providers"`
|
||||
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
|
||||
Image string `xorm:"varchar(100)" json:"image"`
|
||||
Detail string `xorm:"varchar(255)" json:"detail"`
|
||||
Description string `xorm:"varchar(100)" json:"description"`
|
||||
Tag string `xorm:"varchar(100)" json:"tag"`
|
||||
Currency string `xorm:"varchar(100)" json:"currency"`
|
||||
Price float64 `json:"price"`
|
||||
Quantity int `json:"quantity"`
|
||||
Sold int `json:"sold"`
|
||||
Providers []string `xorm:"varchar(100)" json:"providers"`
|
||||
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
|
||||
|
||||
State string `xorm:"varchar(100)" json:"state"`
|
||||
|
||||
@ -213,6 +214,10 @@ func BuyProduct(id string, providerName string, user *User, host string) (string
|
||||
}
|
||||
|
||||
func ExtendProductWithProviders(product *Product) {
|
||||
if product == nil {
|
||||
return
|
||||
}
|
||||
|
||||
product.ProviderObjs = []*Provider{}
|
||||
|
||||
m := getProviderMap(product.Owner)
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
|
||||
type Provider struct {
|
||||
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
||||
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||
Name string `xorm:"varchar(100) notnull pk unique" json:"name"`
|
||||
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
@ -93,8 +93,8 @@ func GetMaskedProviders(providers []*Provider) []*Provider {
|
||||
}
|
||||
|
||||
func GetProviderCount(owner, field, value string) int {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
count, err := session.Count(&Provider{})
|
||||
session := GetSession("", -1, -1, field, value, "", "")
|
||||
count, err := session.Where("owner = ? or owner = ? ", "admin", owner).Count(&Provider{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -114,7 +114,7 @@ func GetGlobalProviderCount(field, value string) int {
|
||||
|
||||
func GetProviders(owner string) []*Provider {
|
||||
providers := []*Provider{}
|
||||
err := adapter.Engine.Desc("created_time").Find(&providers, &Provider{Owner: owner})
|
||||
err := adapter.Engine.Where("owner = ? or owner = ? ", "admin", owner).Desc("created_time").Find(&providers, &Provider{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -133,9 +133,9 @@ func GetGlobalProviders() []*Provider {
|
||||
}
|
||||
|
||||
func GetPaginationProviders(owner string, offset, limit int, field, value, sortField, sortOrder string) []*Provider {
|
||||
var providers []*Provider
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&providers)
|
||||
providers := []*Provider{}
|
||||
session := GetSession("", offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Where("owner = ? or owner = ? ", "admin", owner).Find(&providers)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -144,7 +144,7 @@ func GetPaginationProviders(owner string, offset, limit int, field, value, sortF
|
||||
}
|
||||
|
||||
func GetPaginationGlobalProviders(offset, limit int, field, value, sortField, sortOrder string) []*Provider {
|
||||
var providers []*Provider
|
||||
providers := []*Provider{}
|
||||
session := GetSession("", offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&providers)
|
||||
if err != nil {
|
||||
@ -159,7 +159,7 @@ func getProvider(owner string, name string) *Provider {
|
||||
return nil
|
||||
}
|
||||
|
||||
provider := Provider{Owner: owner, Name: name}
|
||||
provider := Provider{Name: name}
|
||||
existed, err := adapter.Engine.Get(&provider)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -277,7 +277,7 @@ func GetCaptchaProviderByOwnerName(applicationId, lang string) (*Provider, error
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "ProviderErr.DoNotExist"), applicationId)
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "provider:the provider: %s does not exist"), applicationId)
|
||||
}
|
||||
|
||||
return &provider, nil
|
||||
@ -289,7 +289,7 @@ func GetCaptchaProviderByApplication(applicationId, isCurrentProvider, lang stri
|
||||
}
|
||||
application := GetApplication(applicationId)
|
||||
if application == nil || len(application.Providers) == 0 {
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "ApplicationErr.InvalidID"))
|
||||
return nil, fmt.Errorf(i18n.Translate(lang, "provider:Invalid application id"))
|
||||
}
|
||||
for _, provider := range application.Providers {
|
||||
if provider.Provider == nil {
|
||||
|
@ -15,7 +15,9 @@
|
||||
package object
|
||||
|
||||
type ProviderItem struct {
|
||||
Name string `json:"name"`
|
||||
Owner string `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
|
||||
CanSignUp bool `json:"canSignUp"`
|
||||
CanSignIn bool `json:"canSignIn"`
|
||||
CanUnlink bool `json:"canUnlink"`
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
|
||||
type Resource struct {
|
||||
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
||||
Name string `xorm:"varchar(250) notnull pk" json:"name"`
|
||||
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||
|
||||
User string `xorm:"varchar(100)" json:"user"`
|
||||
@ -31,12 +31,12 @@ type Resource struct {
|
||||
Application string `xorm:"varchar(100)" json:"application"`
|
||||
Tag string `xorm:"varchar(100)" json:"tag"`
|
||||
Parent string `xorm:"varchar(100)" json:"parent"`
|
||||
FileName string `xorm:"varchar(1000)" json:"fileName"`
|
||||
FileName string `xorm:"varchar(255)" json:"fileName"`
|
||||
FileType string `xorm:"varchar(100)" json:"fileType"`
|
||||
FileFormat string `xorm:"varchar(100)" json:"fileFormat"`
|
||||
FileSize int `json:"fileSize"`
|
||||
Url string `xorm:"varchar(1000)" json:"url"`
|
||||
Description string `xorm:"varchar(1000)" json:"description"`
|
||||
Url string `xorm:"varchar(255)" json:"url"`
|
||||
Description string `xorm:"varchar(255)" json:"description"`
|
||||
}
|
||||
|
||||
func GetResourceCount(owner, user, field, value string) int {
|
||||
|
@ -95,6 +95,12 @@ func UpdateRole(id string, role *Role) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
permissions := GetPermissionsByRole(id)
|
||||
for _, permission := range permissions {
|
||||
removeGroupingPolicies(permission)
|
||||
removePolicies(permission)
|
||||
}
|
||||
|
||||
if name != role.Name {
|
||||
err := roleChangeTrigger(name, role.Name)
|
||||
if err != nil {
|
||||
@ -107,6 +113,13 @@ func UpdateRole(id string, role *Role) bool {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
newRoleID := role.GetId()
|
||||
permissions = GetPermissionsByRole(newRoleID)
|
||||
for _, permission := range permissions {
|
||||
addGroupingPolicies(permission)
|
||||
addPolicies(permission)
|
||||
}
|
||||
|
||||
return affected != 0
|
||||
}
|
||||
|
||||
@ -120,6 +133,13 @@ func AddRole(role *Role) bool {
|
||||
}
|
||||
|
||||
func DeleteRole(role *Role) bool {
|
||||
roleId := role.GetId()
|
||||
permissions := GetPermissionsByRole(roleId)
|
||||
for _, permission := range permissions {
|
||||
permission.Roles = util.DeleteVal(permission.Roles, roleId)
|
||||
UpdatePermission(permission.GetId(), permission)
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{role.Owner, role.Name}).Delete(&Role{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -192,3 +212,11 @@ func roleChangeTrigger(oldName string, newName string) error {
|
||||
|
||||
return session.Commit()
|
||||
}
|
||||
|
||||
func GetMaskedRoles(roles []*Role) []*Role {
|
||||
for _, role := range roles {
|
||||
role.Users = nil
|
||||
}
|
||||
|
||||
return roles
|
||||
}
|
||||
|
@ -223,11 +223,14 @@ func GetSamlMeta(application *Application, host string) (*IdpEntityDescriptor, e
|
||||
|
||||
// GetSamlResponse generates a SAML2.0 response
|
||||
// parameter samlRequest is saml request in base64 format
|
||||
func GetSamlResponse(application *Application, user *User, samlRequest string, host string) (string, string, error) {
|
||||
func GetSamlResponse(application *Application, user *User, samlRequest string, host string) (string, string, string, error) {
|
||||
// request type
|
||||
method := "GET"
|
||||
|
||||
// base64 decode
|
||||
defated, err := base64.StdEncoding.DecodeString(samlRequest)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
}
|
||||
// decompress
|
||||
var buffer bytes.Buffer
|
||||
@ -236,12 +239,12 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
var authnRequest saml.AuthnRequest
|
||||
err = xml.Unmarshal(buffer.Bytes(), &authnRequest)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
}
|
||||
|
||||
// verify samlRequest
|
||||
if valid := CheckRedirectUriValid(application, authnRequest.Issuer.Url); !valid {
|
||||
return "", "", fmt.Errorf("err: invalid issuer url")
|
||||
if isValid := application.IsRedirectUriValid(authnRequest.Issuer.Url); !isValid {
|
||||
return "", "", method, fmt.Errorf("err: Issuer URI: %s doesn't exist in the allowed Redirect URI list", authnRequest.Issuer.Url)
|
||||
}
|
||||
|
||||
// get certificate string
|
||||
@ -251,6 +254,12 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
|
||||
// redirect Url (Assertion Consumer Url)
|
||||
if application.SamlReplyUrl != "" {
|
||||
method = "POST"
|
||||
authnRequest.AssertionConsumerServiceURL = application.SamlReplyUrl
|
||||
}
|
||||
|
||||
// build signedResponse
|
||||
samlResponse, _ := NewSamlResponse(user, originBackend, certificate, authnRequest.AssertionConsumerServiceURL, authnRequest.Issuer.Url, authnRequest.ID, application.RedirectUris)
|
||||
randomKeyStore := &X509Key{
|
||||
@ -270,7 +279,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
doc.SetRoot(samlResponse)
|
||||
xmlBytes, err := doc.WriteToBytes()
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
}
|
||||
|
||||
// compress
|
||||
@ -278,7 +287,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
flated := bytes.NewBuffer(nil)
|
||||
writer, err := flate.NewWriter(flated, flate.DefaultCompression)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("err: %s", err.Error())
|
||||
return "", "", method, fmt.Errorf("err: %s", err.Error())
|
||||
}
|
||||
writer.Write(xmlBytes)
|
||||
writer.Close()
|
||||
@ -286,7 +295,7 @@ func GetSamlResponse(application *Application, user *User, samlRequest string, h
|
||||
}
|
||||
// base64 encode
|
||||
res := base64.StdEncoding.EncodeToString(xmlBytes)
|
||||
return res, authnRequest.AssertionConsumerServiceURL, nil
|
||||
return res, authnRequest.AssertionConsumerServiceURL, method, nil
|
||||
}
|
||||
|
||||
// NewSamlResponse11 return a saml1.1 response(not 2.0)
|
||||
|
@ -45,7 +45,7 @@ func ParseSamlResponse(samlResponse string, providerType string) (string, error)
|
||||
func GenerateSamlLoginUrl(id, relayState, lang string) (string, string, error) {
|
||||
provider := GetProvider(id)
|
||||
if provider.Category != "SAML" {
|
||||
return "", "", fmt.Errorf(i18n.Translate(lang, "ProviderErr.CategoryNotSAML"), provider.Name)
|
||||
return "", "", fmt.Errorf(i18n.Translate(lang, "saml_sp:provider %s's category is not SAML"), provider.Name)
|
||||
}
|
||||
sp, err := buildSp(provider, "")
|
||||
if err != nil {
|
||||
|
130
object/session.go
Normal file
130
object/session.go
Normal file
@ -0,0 +1,130 @@
|
||||
// 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 (
|
||||
"github.com/beego/beego"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
type Session 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"`
|
||||
|
||||
SessionId []string `json:"sessionId"`
|
||||
}
|
||||
|
||||
func SetSession(id string, sessionId string) {
|
||||
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
|
||||
session := &Session{Owner: owner, Name: name}
|
||||
get, err := adapter.Engine.Get(session)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
session.SessionId = append(session.SessionId, sessionId)
|
||||
if get {
|
||||
_, err = adapter.Engine.ID(core.PK{owner, name}).Update(session)
|
||||
} else {
|
||||
session.CreatedTime = util.GetCurrentTime()
|
||||
_, err = adapter.Engine.Insert(session)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteSession(id string) bool {
|
||||
owner, name := util.GetOwnerAndNameFromIdNoCheck(id)
|
||||
|
||||
session := &Session{Owner: owner, Name: name}
|
||||
_, err := adapter.Engine.ID(core.PK{owner, name}).Get(session)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
DeleteBeegoSession(session.SessionId)
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).Delete(session)
|
||||
return affected != 0
|
||||
}
|
||||
|
||||
func DeleteSessionId(id string, sessionId string) bool {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
|
||||
session := &Session{Owner: owner, Name: name}
|
||||
_, err := adapter.Engine.ID(core.PK{owner, name}).Get(session)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
DeleteBeegoSession([]string{sessionId})
|
||||
session.SessionId = util.DeleteVal(session.SessionId, sessionId)
|
||||
|
||||
if len(session.SessionId) < 1 {
|
||||
affected, _ := adapter.Engine.ID(core.PK{owner, name}).Delete(session)
|
||||
return affected != 0
|
||||
} else {
|
||||
affected, _ := adapter.Engine.ID(core.PK{owner, name}).Update(session)
|
||||
return affected != 0
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteBeegoSession(sessionIds []string) {
|
||||
for _, sessionId := range sessionIds {
|
||||
err := beego.GlobalSessions.GetProvider().SessionDestroy(sessionId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetSessions(owner string) []*Session {
|
||||
sessions := []*Session{}
|
||||
var err error
|
||||
if owner != "" {
|
||||
err = adapter.Engine.Desc("created_time").Where("owner = ?", owner).Find(&sessions)
|
||||
} else {
|
||||
err = adapter.Engine.Desc("created_time").Find(&sessions)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return sessions
|
||||
}
|
||||
|
||||
func GetPaginationSessions(owner string, offset, limit int, field, value, sortField, sortOrder string) []*Session {
|
||||
sessions := []*Session{}
|
||||
session := GetSession(owner, offset, limit, field, value, sortField, sortOrder)
|
||||
err := session.Find(&sessions)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return sessions
|
||||
}
|
||||
|
||||
func GetSessionCount(owner, field, value string) int {
|
||||
session := GetSession(owner, -1, -1, field, value, "", "")
|
||||
count, err := session.Count(&Session{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return int(count)
|
||||
}
|
@ -54,7 +54,7 @@ func escapePath(path string) string {
|
||||
return res
|
||||
}
|
||||
|
||||
func getUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool) (string, string) {
|
||||
func GetUploadFileUrl(provider *Provider, fullFilePath string, hasTimestamp bool) (string, string) {
|
||||
escapedPath := util.UrlJoin(provider.PathPrefix, escapePath(fullFilePath))
|
||||
objectKey := util.UrlJoin(util.GetUrlPath(provider.Domain), escapedPath)
|
||||
|
||||
@ -93,7 +93,7 @@ func uploadFile(provider *Provider, fullFilePath string, fileBuffer *bytes.Buffe
|
||||
UpdateProvider(provider.GetId(), provider)
|
||||
}
|
||||
|
||||
fileUrl, objectKey := getUploadFileUrl(provider, fullFilePath, true)
|
||||
fileUrl, objectKey := GetUploadFileUrl(provider, fullFilePath, true)
|
||||
|
||||
_, err := storageProvider.Put(objectKey, fileBuffer)
|
||||
if err != nil {
|
||||
@ -130,13 +130,13 @@ func UploadFileSafe(provider *Provider, fullFilePath string, fileBuffer *bytes.B
|
||||
func DeleteFile(provider *Provider, objectKey string, lang string) error {
|
||||
// check fullFilePath is there security issue
|
||||
if strings.Contains(objectKey, "..") {
|
||||
return fmt.Errorf(i18n.Translate(lang, "StorageErr.ObjectKeyNotAllowed"), objectKey)
|
||||
return fmt.Errorf(i18n.Translate(lang, "storage:The objectKey: %s is not allowed"), objectKey)
|
||||
}
|
||||
|
||||
endpoint := getProviderEndpoint(provider)
|
||||
storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
|
||||
if storageProvider == nil {
|
||||
return fmt.Errorf(i18n.Translate(lang, "ProviderErr.ProviderNotSupported"), provider.Type)
|
||||
return fmt.Errorf(i18n.Translate(lang, "storage:The provider type: %s is not supported"), provider.Type)
|
||||
}
|
||||
|
||||
if provider.Domain == "" {
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/casdoor/casdoor/i18n"
|
||||
@ -28,7 +27,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
hourSeconds = 3600
|
||||
hourMinutes = 60
|
||||
InvalidRequest = "invalid_request"
|
||||
InvalidClient = "invalid_client"
|
||||
InvalidGrant = "invalid_grant"
|
||||
@ -169,6 +168,10 @@ func GetToken(id string) *Token {
|
||||
return getToken(owner, name)
|
||||
}
|
||||
|
||||
func (token *Token) GetId() string {
|
||||
return fmt.Sprintf("%s/%s", token.Owner, token.Name)
|
||||
}
|
||||
|
||||
func UpdateToken(id string, token *Token) bool {
|
||||
owner, name := util.GetOwnerAndNameFromId(id)
|
||||
if getToken(owner, name) == nil {
|
||||
@ -201,7 +204,7 @@ func DeleteToken(token *Token) bool {
|
||||
return affected != 0
|
||||
}
|
||||
|
||||
func DeleteTokenByAccessToken(accessToken string) (bool, *Application) {
|
||||
func ExpireTokenByAccessToken(accessToken string) (bool, *Application, *Token) {
|
||||
token := Token{AccessToken: accessToken}
|
||||
existed, err := adapter.Engine.Get(&token)
|
||||
if err != nil {
|
||||
@ -209,15 +212,17 @@ func DeleteTokenByAccessToken(accessToken string) (bool, *Application) {
|
||||
}
|
||||
|
||||
if !existed {
|
||||
return false, nil
|
||||
return false, nil, nil
|
||||
}
|
||||
application := getApplication(token.Owner, token.Application)
|
||||
affected, err := adapter.Engine.Where("access_token=?", accessToken).Delete(&Token{})
|
||||
|
||||
token.ExpiresIn = 0
|
||||
affected, err := adapter.Engine.ID(core.PK{token.Owner, token.Name}).Cols("expires_in").Update(&token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return affected != 0, application
|
||||
application := getApplication(token.Owner, token.Application)
|
||||
return affected != 0, application, &token
|
||||
}
|
||||
|
||||
func GetTokenByAccessToken(accessToken string) *Token {
|
||||
@ -241,23 +246,16 @@ func GetTokenByTokenAndApplication(token string, application string) *Token {
|
||||
|
||||
func CheckOAuthLogin(clientId string, responseType string, redirectUri string, scope string, state string, lang string) (string, *Application) {
|
||||
if responseType != "code" && responseType != "token" && responseType != "id_token" {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "ApplicationErr.GrantTypeNotSupport"), responseType), nil
|
||||
return fmt.Sprintf(i18n.Translate(lang, "token:Grant_type: %s is not supported in this application"), responseType), nil
|
||||
}
|
||||
|
||||
application := GetApplicationByClientId(clientId)
|
||||
if application == nil {
|
||||
return i18n.Translate(lang, "TokenErr.InvalidClientId"), nil
|
||||
return i18n.Translate(lang, "token:Invalid client_id"), nil
|
||||
}
|
||||
|
||||
validUri := false
|
||||
for _, tmpUri := range application.RedirectUris {
|
||||
if strings.Contains(redirectUri, tmpUri) {
|
||||
validUri = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !validUri {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "TokenErr.RedirectURIDoNotExist"), redirectUri), application
|
||||
if !application.IsRedirectUriValid(redirectUri) {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "token:Redirect URI: %s doesn't exist in the allowed Redirect URI list"), redirectUri), application
|
||||
}
|
||||
|
||||
// Mask application for /api/get-app-login
|
||||
@ -269,7 +267,7 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
||||
user := GetUser(userId)
|
||||
if user == nil {
|
||||
return &Code{
|
||||
Message: fmt.Sprintf("The user: %s doesn't exist", userId),
|
||||
Message: fmt.Sprintf("general:The user: %s doesn't exist", userId),
|
||||
Code: "",
|
||||
}
|
||||
}
|
||||
@ -308,7 +306,7 @@ func GetOAuthCode(userId string, clientId string, responseType string, redirectU
|
||||
Code: util.GenerateClientId(),
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
||||
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||
Scope: scope,
|
||||
TokenType: "Bearer",
|
||||
CodeChallenge: challenge,
|
||||
@ -442,7 +440,7 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
Code: util.GenerateClientId(),
|
||||
AccessToken: newAccessToken,
|
||||
RefreshToken: newRefreshToken,
|
||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
||||
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||
Scope: scope,
|
||||
TokenType: "Bearer",
|
||||
}
|
||||
@ -592,7 +590,7 @@ func GetPasswordToken(application *Application, username string, password string
|
||||
Code: util.GenerateClientId(),
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
||||
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||
Scope: scope,
|
||||
TokenType: "Bearer",
|
||||
CodeIsUsed: true,
|
||||
@ -632,7 +630,7 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
|
||||
User: nullUser.Name,
|
||||
Code: util.GenerateClientId(),
|
||||
AccessToken: accessToken,
|
||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
||||
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||
Scope: scope,
|
||||
TokenType: "Bearer",
|
||||
CodeIsUsed: true,
|
||||
@ -659,7 +657,7 @@ func GetTokenByUser(application *Application, user *User, scope string, host str
|
||||
Code: util.GenerateClientId(),
|
||||
AccessToken: accessToken,
|
||||
RefreshToken: refreshToken,
|
||||
ExpiresIn: application.ExpireInHours * hourSeconds,
|
||||
ExpiresIn: application.ExpireInHours * hourMinutes,
|
||||
Scope: scope,
|
||||
TokenType: "Bearer",
|
||||
CodeIsUsed: true,
|
||||
@ -678,7 +676,7 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
|
||||
ErrorDescription: "the application does not support wechat mini program",
|
||||
}
|
||||
}
|
||||
provider := GetProvider(util.GetId(mpProvider.Name))
|
||||
provider := GetProvider(util.GetId("admin", mpProvider.Name))
|
||||
mpIdp := idp.NewWeChatMiniProgramIdProvider(provider.ClientId, provider.ClientSecret)
|
||||
session, err := mpIdp.GetSessionByCode(code)
|
||||
if err != nil {
|
||||
|
@ -36,6 +36,60 @@ type UserShort struct {
|
||||
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||
}
|
||||
|
||||
type UserWithoutThirdIdp 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"`
|
||||
Id string `xorm:"varchar(100) index" json:"id"`
|
||||
Type string `xorm:"varchar(100)" json:"type"`
|
||||
Password string `xorm:"varchar(100)" json:"password"`
|
||||
PasswordSalt string `xorm:"varchar(100)" json:"passwordSalt"`
|
||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||
FirstName string `xorm:"varchar(100)" json:"firstName"`
|
||||
LastName string `xorm:"varchar(100)" json:"lastName"`
|
||||
Avatar string `xorm:"varchar(500)" json:"avatar"`
|
||||
PermanentAvatar string `xorm:"varchar(500)" json:"permanentAvatar"`
|
||||
Email string `xorm:"varchar(100) index" json:"email"`
|
||||
EmailVerified bool `json:"emailVerified"`
|
||||
Phone string `xorm:"varchar(100) index" json:"phone"`
|
||||
Location string `xorm:"varchar(100)" json:"location"`
|
||||
Address []string `json:"address"`
|
||||
Affiliation string `xorm:"varchar(100)" json:"affiliation"`
|
||||
Title string `xorm:"varchar(100)" json:"title"`
|
||||
IdCardType string `xorm:"varchar(100)" json:"idCardType"`
|
||||
IdCard string `xorm:"varchar(100) index" json:"idCard"`
|
||||
Homepage string `xorm:"varchar(100)" json:"homepage"`
|
||||
Bio string `xorm:"varchar(100)" json:"bio"`
|
||||
Tag string `xorm:"varchar(100)" json:"tag"`
|
||||
Region string `xorm:"varchar(100)" json:"region"`
|
||||
Language string `xorm:"varchar(100)" json:"language"`
|
||||
Gender string `xorm:"varchar(100)" json:"gender"`
|
||||
Birthday string `xorm:"varchar(100)" json:"birthday"`
|
||||
Education string `xorm:"varchar(100)" json:"education"`
|
||||
Score int `json:"score"`
|
||||
Karma int `json:"karma"`
|
||||
Ranking int `json:"ranking"`
|
||||
IsDefaultAvatar bool `json:"isDefaultAvatar"`
|
||||
IsOnline bool `json:"isOnline"`
|
||||
IsAdmin bool `json:"isAdmin"`
|
||||
IsGlobalAdmin bool `json:"isGlobalAdmin"`
|
||||
IsForbidden bool `json:"isForbidden"`
|
||||
IsDeleted bool `json:"isDeleted"`
|
||||
SignupApplication string `xorm:"varchar(100)" json:"signupApplication"`
|
||||
Hash string `xorm:"varchar(100)" json:"hash"`
|
||||
PreHash string `xorm:"varchar(100)" json:"preHash"`
|
||||
CreatedIp string `xorm:"varchar(100)" json:"createdIp"`
|
||||
LastSigninTime string `xorm:"varchar(100)" json:"lastSigninTime"`
|
||||
LastSigninIp string `xorm:"varchar(100)" json:"lastSigninIp"`
|
||||
Ldap string `xorm:"ldap varchar(100)" json:"ldap"`
|
||||
Properties map[string]string `json:"properties"`
|
||||
Roles []*Role `xorm:"-" json:"roles"`
|
||||
Permissions []*Permission `xorm:"-" json:"permissions"`
|
||||
LastSigninWrongTime string `xorm:"varchar(100)" json:"lastSigninWrongTime"`
|
||||
SigninWrongTimes int `json:"signinWrongTimes"`
|
||||
}
|
||||
|
||||
type ClaimsShort struct {
|
||||
*UserShort
|
||||
TokenType string `json:"tokenType,omitempty"`
|
||||
@ -44,6 +98,15 @@ type ClaimsShort struct {
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
type ClaimsWithoutThirdIdp struct {
|
||||
*UserWithoutThirdIdp
|
||||
TokenType string `json:"tokenType,omitempty"`
|
||||
Nonce string `json:"nonce,omitempty"`
|
||||
Tag string `json:"tag,omitempty"`
|
||||
Scope string `json:"scope,omitempty"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func getShortUser(user *User) *UserShort {
|
||||
res := &UserShort{
|
||||
Owner: user.Owner,
|
||||
@ -52,6 +115,69 @@ func getShortUser(user *User) *UserShort {
|
||||
return res
|
||||
}
|
||||
|
||||
func getUserWithoutThirdIdp(user *User) *UserWithoutThirdIdp {
|
||||
res := &UserWithoutThirdIdp{
|
||||
Owner: user.Owner,
|
||||
Name: user.Name,
|
||||
CreatedTime: user.CreatedTime,
|
||||
UpdatedTime: user.UpdatedTime,
|
||||
|
||||
Id: user.Id,
|
||||
Type: user.Type,
|
||||
Password: user.Password,
|
||||
PasswordSalt: user.PasswordSalt,
|
||||
DisplayName: user.DisplayName,
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
Avatar: user.Avatar,
|
||||
PermanentAvatar: user.PermanentAvatar,
|
||||
Email: user.Email,
|
||||
EmailVerified: user.EmailVerified,
|
||||
Phone: user.Phone,
|
||||
Location: user.Location,
|
||||
Address: user.Address,
|
||||
Affiliation: user.Affiliation,
|
||||
Title: user.Title,
|
||||
IdCardType: user.IdCardType,
|
||||
IdCard: user.IdCard,
|
||||
Homepage: user.Homepage,
|
||||
Bio: user.Bio,
|
||||
Tag: user.Tag,
|
||||
Region: user.Region,
|
||||
Language: user.Language,
|
||||
Gender: user.Gender,
|
||||
Birthday: user.Birthday,
|
||||
Education: user.Education,
|
||||
Score: user.Score,
|
||||
Karma: user.Karma,
|
||||
Ranking: user.Ranking,
|
||||
IsDefaultAvatar: user.IsDefaultAvatar,
|
||||
IsOnline: user.IsOnline,
|
||||
IsAdmin: user.IsAdmin,
|
||||
IsGlobalAdmin: user.IsGlobalAdmin,
|
||||
IsForbidden: user.IsForbidden,
|
||||
IsDeleted: user.IsDeleted,
|
||||
SignupApplication: user.SignupApplication,
|
||||
Hash: user.Hash,
|
||||
PreHash: user.PreHash,
|
||||
|
||||
CreatedIp: user.CreatedIp,
|
||||
LastSigninTime: user.LastSigninTime,
|
||||
LastSigninIp: user.LastSigninIp,
|
||||
|
||||
Ldap: user.Ldap,
|
||||
Properties: user.Properties,
|
||||
|
||||
Roles: user.Roles,
|
||||
Permissions: user.Permissions,
|
||||
|
||||
LastSigninWrongTime: user.LastSigninWrongTime,
|
||||
SigninWrongTimes: user.SigninWrongTimes,
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func getShortClaims(claims Claims) ClaimsShort {
|
||||
res := ClaimsShort{
|
||||
UserShort: getShortUser(claims.User),
|
||||
@ -63,12 +189,44 @@ func getShortClaims(claims Claims) ClaimsShort {
|
||||
return res
|
||||
}
|
||||
|
||||
func getClaimsWithoutThirdIdp(claims Claims) ClaimsWithoutThirdIdp {
|
||||
res := ClaimsWithoutThirdIdp{
|
||||
UserWithoutThirdIdp: getUserWithoutThirdIdp(claims.User),
|
||||
TokenType: claims.TokenType,
|
||||
Nonce: claims.Nonce,
|
||||
Tag: claims.Tag,
|
||||
Scope: claims.Scope,
|
||||
RegisteredClaims: claims.RegisteredClaims,
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func refineUser(user *User) *User {
|
||||
user.Password = ""
|
||||
|
||||
if user.Address == nil {
|
||||
user.Address = []string{}
|
||||
}
|
||||
if user.Properties == nil {
|
||||
user.Properties = map[string]string{}
|
||||
}
|
||||
if user.Roles == nil {
|
||||
user.Roles = []*Role{}
|
||||
}
|
||||
if user.Permissions == nil {
|
||||
user.Permissions = []*Permission{}
|
||||
}
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
func generateJwtToken(application *Application, user *User, nonce string, scope string, host string) (string, string, string, error) {
|
||||
nowTime := time.Now()
|
||||
expireTime := nowTime.Add(time.Duration(application.ExpireInHours) * time.Hour)
|
||||
refreshExpireTime := nowTime.Add(time.Duration(application.RefreshExpireInHours) * time.Hour)
|
||||
|
||||
user.Password = ""
|
||||
user = refineUser(user)
|
||||
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
|
||||
name := util.GenerateId()
|
||||
@ -104,10 +262,12 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
||||
claimsShort.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsShort)
|
||||
} else {
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
||||
claimsWithoutThirdIdp := getClaimsWithoutThirdIdp(claims)
|
||||
|
||||
token = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsWithoutThirdIdp)
|
||||
claims.ExpiresAt = jwt.NewNumericDate(refreshExpireTime)
|
||||
claims.TokenType = "refresh-token"
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
||||
refreshToken = jwt.NewWithClaims(jwt.SigningMethodRS256, claimsWithoutThirdIdp)
|
||||
}
|
||||
|
||||
cert := getCertByApplication(application)
|
||||
|
102
object/user.go
102
object/user.go
@ -78,31 +78,80 @@ type User struct {
|
||||
LastSigninTime string `xorm:"varchar(100)" json:"lastSigninTime"`
|
||||
LastSigninIp string `xorm:"varchar(100)" json:"lastSigninIp"`
|
||||
|
||||
GitHub string `xorm:"github varchar(100)" json:"github"`
|
||||
Google string `xorm:"varchar(100)" json:"google"`
|
||||
QQ string `xorm:"qq varchar(100)" json:"qq"`
|
||||
WeChat string `xorm:"wechat varchar(100)" json:"wechat"`
|
||||
Facebook string `xorm:"facebook varchar(100)" json:"facebook"`
|
||||
DingTalk string `xorm:"dingtalk varchar(100)" json:"dingtalk"`
|
||||
Weibo string `xorm:"weibo varchar(100)" json:"weibo"`
|
||||
Gitee string `xorm:"gitee varchar(100)" json:"gitee"`
|
||||
LinkedIn string `xorm:"linkedin varchar(100)" json:"linkedin"`
|
||||
Wecom string `xorm:"wecom varchar(100)" json:"wecom"`
|
||||
Lark string `xorm:"lark varchar(100)" json:"lark"`
|
||||
Gitlab string `xorm:"gitlab varchar(100)" json:"gitlab"`
|
||||
Adfs string `xorm:"adfs varchar(100)" json:"adfs"`
|
||||
Baidu string `xorm:"baidu varchar(100)" json:"baidu"`
|
||||
Alipay string `xorm:"alipay varchar(100)" json:"alipay"`
|
||||
Casdoor string `xorm:"casdoor varchar(100)" json:"casdoor"`
|
||||
Infoflow string `xorm:"infoflow varchar(100)" json:"infoflow"`
|
||||
Apple string `xorm:"apple varchar(100)" json:"apple"`
|
||||
AzureAD string `xorm:"azuread varchar(100)" json:"azuread"`
|
||||
Slack string `xorm:"slack varchar(100)" json:"slack"`
|
||||
Steam string `xorm:"steam varchar(100)" json:"steam"`
|
||||
Bilibili string `xorm:"bilibili varchar(100)" json:"bilibili"`
|
||||
Okta string `xorm:"okta varchar(100)" json:"okta"`
|
||||
Douyin string `xorm:"douyin varchar(100)" json:"douyin"`
|
||||
Custom string `xorm:"custom varchar(100)" json:"custom"`
|
||||
GitHub string `xorm:"github varchar(100)" json:"github"`
|
||||
Google string `xorm:"varchar(100)" json:"google"`
|
||||
QQ string `xorm:"qq varchar(100)" json:"qq"`
|
||||
WeChat string `xorm:"wechat varchar(100)" json:"wechat"`
|
||||
Facebook string `xorm:"facebook varchar(100)" json:"facebook"`
|
||||
DingTalk string `xorm:"dingtalk varchar(100)" json:"dingtalk"`
|
||||
Weibo string `xorm:"weibo varchar(100)" json:"weibo"`
|
||||
Gitee string `xorm:"gitee varchar(100)" json:"gitee"`
|
||||
LinkedIn string `xorm:"linkedin varchar(100)" json:"linkedin"`
|
||||
Wecom string `xorm:"wecom varchar(100)" json:"wecom"`
|
||||
Lark string `xorm:"lark varchar(100)" json:"lark"`
|
||||
Gitlab string `xorm:"gitlab varchar(100)" json:"gitlab"`
|
||||
Adfs string `xorm:"adfs varchar(100)" json:"adfs"`
|
||||
Baidu string `xorm:"baidu varchar(100)" json:"baidu"`
|
||||
Alipay string `xorm:"alipay varchar(100)" json:"alipay"`
|
||||
Casdoor string `xorm:"casdoor varchar(100)" json:"casdoor"`
|
||||
Infoflow string `xorm:"infoflow varchar(100)" json:"infoflow"`
|
||||
Apple string `xorm:"apple varchar(100)" json:"apple"`
|
||||
AzureAD string `xorm:"azuread varchar(100)" json:"azuread"`
|
||||
Slack string `xorm:"slack varchar(100)" json:"slack"`
|
||||
Steam string `xorm:"steam varchar(100)" json:"steam"`
|
||||
Bilibili string `xorm:"bilibili varchar(100)" json:"bilibili"`
|
||||
Okta string `xorm:"okta varchar(100)" json:"okta"`
|
||||
Douyin string `xorm:"douyin varchar(100)" json:"douyin"`
|
||||
Line string `xorm:"line varchar(100)" json:"line"`
|
||||
Amazon string `xorm:"amazon varchar(100)" json:"amazon"`
|
||||
Auth0 string `xorm:"auth0 varchar(100)" json:"auth0"`
|
||||
BattleNet string `xorm:"battlenet varchar(100)" json:"battlenet"`
|
||||
Bitbucket string `xorm:"bitbucket varchar(100)" json:"bitbucket"`
|
||||
Box string `xorm:"box varchar(100)" json:"box"`
|
||||
CloudFoundry string `xorm:"cloudfoundry varchar(100)" json:"cloudfoundry"`
|
||||
Dailymotion string `xorm:"dailymotion varchar(100)" json:"dailymotion"`
|
||||
Deezer string `xorm:"deezer varchar(100)" json:"deezer"`
|
||||
DigitalOcean string `xorm:"digitalocean varchar(100)" json:"digitalocean"`
|
||||
Discord string `xorm:"discord varchar(100)" json:"discord"`
|
||||
Dropbox string `xorm:"dropbox varchar(100)" json:"dropbox"`
|
||||
EveOnline string `xorm:"eveonline varchar(100)" json:"eveonline"`
|
||||
Fitbit string `xorm:"fitbit varchar(100)" json:"fitbit"`
|
||||
Gitea string `xorm:"gitea varchar(100)" json:"gitea"`
|
||||
Heroku string `xorm:"heroku varchar(100)" json:"heroku"`
|
||||
InfluxCloud string `xorm:"influxcloud varchar(100)" json:"influxcloud"`
|
||||
Instagram string `xorm:"instagram varchar(100)" json:"instagram"`
|
||||
Intercom string `xorm:"intercom varchar(100)" json:"intercom"`
|
||||
Kakao string `xorm:"kakao varchar(100)" json:"kakao"`
|
||||
Lastfm string `xorm:"lastfm varchar(100)" json:"lastfm"`
|
||||
Mailru string `xorm:"mailru varchar(100)" json:"mailru"`
|
||||
Meetup string `xorm:"meetup varchar(100)" json:"meetup"`
|
||||
MicrosoftOnline string `xorm:"microsoftonline varchar(100)" json:"microsoftonline"`
|
||||
Naver string `xorm:"naver varchar(100)" json:"naver"`
|
||||
Nextcloud string `xorm:"nextcloud varchar(100)" json:"nextcloud"`
|
||||
OneDrive string `xorm:"onedrive varchar(100)" json:"onedrive"`
|
||||
Oura string `xorm:"oura varchar(100)" json:"oura"`
|
||||
Patreon string `xorm:"patreon varchar(100)" json:"patreon"`
|
||||
Paypal string `xorm:"paypal varchar(100)" json:"paypal"`
|
||||
SalesForce string `xorm:"salesforce varchar(100)" json:"salesforce"`
|
||||
Shopify string `xorm:"shopify varchar(100)" json:"shopify"`
|
||||
Soundcloud string `xorm:"soundcloud varchar(100)" json:"soundcloud"`
|
||||
Spotify string `xorm:"spotify varchar(100)" json:"spotify"`
|
||||
Strava string `xorm:"strava varchar(100)" json:"strava"`
|
||||
Stripe string `xorm:"stripe varchar(100)" json:"stripe"`
|
||||
TikTok string `xorm:"tiktok varchar(100)" json:"tiktok"`
|
||||
Tumblr string `xorm:"tumblr varchar(100)" json:"tumblr"`
|
||||
Twitch string `xorm:"twitch varchar(100)" json:"twitch"`
|
||||
Twitter string `xorm:"twitter varchar(100)" json:"twitter"`
|
||||
Typetalk string `xorm:"typetalk varchar(100)" json:"typetalk"`
|
||||
Uber string `xorm:"uber varchar(100)" json:"uber"`
|
||||
VK string `xorm:"vk varchar(100)" json:"vk"`
|
||||
Wepay string `xorm:"wepay varchar(100)" json:"wepay"`
|
||||
Xero string `xorm:"xero varchar(100)" json:"xero"`
|
||||
Yahoo string `xorm:"yahoo varchar(100)" json:"yahoo"`
|
||||
Yammer string `xorm:"yammer varchar(100)" json:"yammer"`
|
||||
Yandex string `xorm:"yandex varchar(100)" json:"yandex"`
|
||||
Zoom string `xorm:"zoom varchar(100)" json:"zoom"`
|
||||
Custom string `xorm:"custom varchar(100)" json:"custom"`
|
||||
|
||||
WebauthnCredentials []webauthn.Credential `xorm:"webauthnCredentials blob" json:"webauthnCredentials"`
|
||||
|
||||
@ -528,6 +577,9 @@ func AddUsersInBatch(users []*User) bool {
|
||||
}
|
||||
|
||||
func DeleteUser(user *User) bool {
|
||||
// Forced offline the user first
|
||||
DeleteSession(user.GetId())
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{user.Owner, user.Name}).Delete(&User{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -26,6 +26,10 @@ import (
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
const (
|
||||
wrongCode = "wrongCode"
|
||||
)
|
||||
|
||||
type VerificationRecord struct {
|
||||
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
|
||||
Name string `xorm:"varchar(100) notnull pk" json:"name"`
|
||||
@ -153,7 +157,7 @@ func CheckVerificationCode(dest, code, lang string) string {
|
||||
record := getVerificationRecord(dest)
|
||||
|
||||
if record == nil {
|
||||
return i18n.Translate(lang, "PhoneErr.CodeNotSent")
|
||||
return i18n.Translate(lang, "verification:Code has not been sent yet!")
|
||||
}
|
||||
|
||||
timeout, err := conf.GetConfigInt64("verificationCodeTimeout")
|
||||
@ -163,11 +167,11 @@ func CheckVerificationCode(dest, code, lang string) string {
|
||||
|
||||
now := time.Now().Unix()
|
||||
if now-record.Time > timeout*60 {
|
||||
return fmt.Sprintf(i18n.Translate(lang, "PhoneErr.CodeTimeOut"), timeout)
|
||||
return fmt.Sprintf(i18n.Translate(lang, "verification:You should verify your code in %d min!"), timeout)
|
||||
}
|
||||
|
||||
if record.Code != code {
|
||||
return "Wrong code!"
|
||||
return wrongCode
|
||||
}
|
||||
|
||||
return ""
|
||||
@ -186,6 +190,24 @@ func DisableVerificationCode(dest string) {
|
||||
}
|
||||
}
|
||||
|
||||
func CheckSigninCode(user *User, dest, code, lang string) string {
|
||||
// check the login error times
|
||||
if msg := checkSigninErrorTimes(user, lang); msg != "" {
|
||||
return msg
|
||||
}
|
||||
|
||||
result := CheckVerificationCode(dest, code, lang)
|
||||
switch result {
|
||||
case "":
|
||||
resetUserSigninErrorTimes(user)
|
||||
return ""
|
||||
case wrongCode:
|
||||
return recordSigninErrorInfo(user, lang)
|
||||
default:
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
// From Casnode/object/validateCode.go line 116
|
||||
var stdNums = []byte("0123456789")
|
||||
|
||||
|
@ -37,7 +37,7 @@ type Webhook struct {
|
||||
Method string `xorm:"varchar(100)" json:"method"`
|
||||
ContentType string `xorm:"varchar(100)" json:"contentType"`
|
||||
Headers []*Header `xorm:"mediumtext" json:"headers"`
|
||||
Events []string `xorm:"varchar(100)" json:"events"`
|
||||
Events []string `xorm:"varchar(1000)" json:"events"`
|
||||
IsUserExtended bool `json:"isUserExtended"`
|
||||
IsEnabled bool `json:"isEnabled"`
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ func CorsFilter(ctx *context.Context) {
|
||||
originConf := conf.GetConfigString("origin")
|
||||
|
||||
if origin != "" && originConf != "" && origin != originConf {
|
||||
if object.IsAllowOrigin(origin) {
|
||||
if object.IsOriginAllowed(origin) {
|
||||
ctx.Output.Header(headerAllowOrigin, origin)
|
||||
ctx.Output.Header(headerAllowMethods, "POST, GET, OPTIONS")
|
||||
ctx.Output.Header(headerAllowHeaders, "Content-Type, Authorization")
|
||||
|
@ -82,6 +82,7 @@ func initAPI() {
|
||||
|
||||
beego.Router("/api/get-permissions", &controllers.ApiController{}, "GET:GetPermissions")
|
||||
beego.Router("/api/get-permissions-by-submitter", &controllers.ApiController{}, "GET:GetPermissionsBySubmitter")
|
||||
beego.Router("/api/get-permissions-by-role", &controllers.ApiController{}, "GET:GetPermissionsByRole")
|
||||
beego.Router("/api/get-permission", &controllers.ApiController{}, "GET:GetPermission")
|
||||
beego.Router("/api/update-permission", &controllers.ApiController{}, "POST:UpdatePermission")
|
||||
beego.Router("/api/add-permission", &controllers.ApiController{}, "POST:AddPermission")
|
||||
@ -105,6 +106,9 @@ func initAPI() {
|
||||
beego.Router("/api/add-adapter", &controllers.ApiController{}, "POST:AddCasbinAdapter")
|
||||
beego.Router("/api/delete-adapter", &controllers.ApiController{}, "POST:DeleteCasbinAdapter")
|
||||
beego.Router("/api/sync-policies", &controllers.ApiController{}, "GET:SyncPolicies")
|
||||
beego.Router("/api/update-policy", &controllers.ApiController{}, "POST:UpdatePolicy")
|
||||
beego.Router("/api/add-policy", &controllers.ApiController{}, "POST:AddPolicy")
|
||||
beego.Router("/api/remove-policy", &controllers.ApiController{}, "POST:RemovePolicy")
|
||||
|
||||
beego.Router("/api/set-password", &controllers.ApiController{}, "POST:SetPassword")
|
||||
beego.Router("/api/check-user-password", &controllers.ApiController{}, "POST:CheckUserPassword")
|
||||
@ -154,12 +158,13 @@ func initAPI() {
|
||||
beego.Router("/api/login/oauth/access_token", &controllers.ApiController{}, "POST:GetOAuthToken")
|
||||
beego.Router("/api/login/oauth/refresh_token", &controllers.ApiController{}, "POST:RefreshToken")
|
||||
beego.Router("/api/login/oauth/introspect", &controllers.ApiController{}, "POST:IntrospectToken")
|
||||
beego.Router("/api/login/oauth/logout", &controllers.ApiController{}, "GET:TokenLogout")
|
||||
|
||||
beego.Router("/api/get-records", &controllers.ApiController{}, "GET:GetRecords")
|
||||
beego.Router("/api/get-records-filter", &controllers.ApiController{}, "POST:GetRecordsByFilter")
|
||||
beego.Router("/api/add-record", &controllers.ApiController{}, "POST:AddRecord")
|
||||
|
||||
beego.Router("/api/get-sessions", &controllers.ApiController{}, "GET:GetSessions")
|
||||
beego.Router("/api/delete-session", &controllers.ApiController{}, "POST:DeleteSession")
|
||||
|
||||
beego.Router("/api/get-webhooks", &controllers.ApiController{}, "GET:GetWebhooks")
|
||||
beego.Router("/api/get-webhook", &controllers.ApiController{}, "GET:GetWebhook")
|
||||
beego.Router("/api/update-webhook", &controllers.ApiController{}, "POST:UpdateWebhook")
|
||||
|
@ -275,6 +275,34 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-record": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Record API"
|
||||
],
|
||||
"description": "add a record",
|
||||
"operationId": "ApiController.AddRecord",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "The details of the record",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Record"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/add-resource": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -431,6 +459,14 @@
|
||||
"operationId": "ApiController.GetCaptcha"
|
||||
}
|
||||
},
|
||||
"/api/api/get-webhook-event": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"GetWebhookEventType API"
|
||||
],
|
||||
"operationId": "ApiController.GetWebhookEventType"
|
||||
}
|
||||
},
|
||||
"/api/api/reset-email-or-phone": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -523,6 +559,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/api/webhook": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"HandleOfficialAccountEvent API"
|
||||
],
|
||||
"operationId": "ApiController.HandleOfficialAccountEvent"
|
||||
}
|
||||
},
|
||||
"/api/buy-product": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -840,6 +884,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/delete-session": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Delete session by userId",
|
||||
"operationId": "ApiController.DeleteSession",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "ID",
|
||||
"description": "The ID(owner/name) of user.",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/delete-syncer": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -1133,6 +1206,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-default-application": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Organization API"
|
||||
],
|
||||
"description": "get default application",
|
||||
"operationId": "ApiController.GetDefaultApplication",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "organization id",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-email-and-phone": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -1166,6 +1265,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-global-providers": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Provider API"
|
||||
],
|
||||
"description": "get Global providers",
|
||||
"operationId": "ApiController.GetGlobalProviders",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Provider"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-global-users": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -1459,6 +1578,55 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-permissions-by-role": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Permission API"
|
||||
],
|
||||
"description": "get permissions by role",
|
||||
"operationId": "ApiController.GetPermissionsByRole",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id of the role",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Permission"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-permissions-by-submitter": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Permission API"
|
||||
],
|
||||
"description": "get permissions by submitter",
|
||||
"operationId": "ApiController.GetPermissionsBySubmitter",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Permission"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-product": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -1631,6 +1799,20 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-release": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"System API"
|
||||
],
|
||||
"description": "get local github repo's latest release version info",
|
||||
"operationId": "ApiController.GitRepoVersion",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "{string} local latest version hash of casdoor"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-resource": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -1702,6 +1884,35 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-sessions": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Session API"
|
||||
],
|
||||
"description": "Get organization user sessions",
|
||||
"operationId": "ApiController.GetSessions",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "owner",
|
||||
"description": "The organization name",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-sorted-users": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -1799,6 +2010,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-system-info": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"System API"
|
||||
],
|
||||
"description": "get user's system info",
|
||||
"operationId": "ApiController.GetSystemInfo",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id of the user",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.SystemInfo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-token": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -2360,45 +2597,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/login/oauth/logout": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Token API"
|
||||
],
|
||||
"description": "delete token by AccessToken",
|
||||
"operationId": "ApiController.TokenLogout",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id_token_hint",
|
||||
"description": "id_token_hint",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "post_logout_redirect_uri",
|
||||
"description": "post_logout_redirect_uri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "state",
|
||||
"description": "state",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/login/oauth/refresh_token": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -2471,6 +2669,26 @@
|
||||
],
|
||||
"description": "logout the current user",
|
||||
"operationId": "ApiController.Logout",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id_token_hint",
|
||||
"description": "id_token_hint",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "post_logout_redirect_uri",
|
||||
"description": "post_logout_redirect_uri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "state",
|
||||
"description": "state",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
@ -2486,6 +2704,26 @@
|
||||
],
|
||||
"description": "logout the current user",
|
||||
"operationId": "ApiController.Logout",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id_token_hint",
|
||||
"description": "id_token_hint",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "post_logout_redirect_uri",
|
||||
"description": "post_logout_redirect_uri",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "state",
|
||||
"description": "state",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
@ -3267,11 +3505,11 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"2200.0xc0003f8480.false": {
|
||||
"2268.0xc0000f9650.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
"2235.0xc0003f84b0.false": {
|
||||
"2302.0xc0000f9680.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
@ -3316,6 +3554,15 @@
|
||||
"autoSignin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"captchaToken": {
|
||||
"type": "string"
|
||||
},
|
||||
"captchaType": {
|
||||
"type": "string"
|
||||
},
|
||||
"clientSecret": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3389,10 +3636,10 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/2200.0xc0003f8480.false"
|
||||
"$ref": "#/definitions/2268.0xc0000f9650.false"
|
||||
},
|
||||
"data2": {
|
||||
"$ref": "#/definitions/2235.0xc0003f84b0.false"
|
||||
"$ref": "#/definitions/2302.0xc0000f9680.false"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
@ -3491,9 +3738,15 @@
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"enableAutoSignin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enableCodeSignin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enableLinkWithEmail": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enablePassword": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@ -3516,6 +3769,19 @@
|
||||
"forgetUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"formBackgroundUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"formCss": {
|
||||
"type": "string"
|
||||
},
|
||||
"formOffset": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"formSideHtml": {
|
||||
"type": "string"
|
||||
},
|
||||
"grantTypes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -3556,6 +3822,9 @@
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"samlReplyUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"signinHtml": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3689,6 +3958,24 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.ManagedAccount": {
|
||||
"title": "ManagedAccount",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"application": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"signinUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.Model": {
|
||||
"title": "Model",
|
||||
"type": "object",
|
||||
@ -3726,6 +4013,9 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"end_session_endpoint": {
|
||||
"type": "string"
|
||||
},
|
||||
"grant_types_supported": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -3801,6 +4091,9 @@
|
||||
"createdTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"defaultApplication": {
|
||||
"type": "string"
|
||||
},
|
||||
"defaultAvatar": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3813,9 +4106,19 @@
|
||||
"favicon": {
|
||||
"type": "string"
|
||||
},
|
||||
"initScore": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"isProfilePublic": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"masterPassword": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3943,12 +4246,27 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"adapter": {
|
||||
"type": "string"
|
||||
},
|
||||
"approveTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"approver": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"domains": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"effect": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3979,6 +4297,12 @@
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"type": "string"
|
||||
},
|
||||
"submitter": {
|
||||
"type": "string"
|
||||
},
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -3997,6 +4321,9 @@
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"detail": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4016,6 +4343,12 @@
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"providerObjs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Provider"
|
||||
}
|
||||
},
|
||||
"providers": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -4090,6 +4423,9 @@
|
||||
"customUserInfoUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"disableSsl": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4126,6 +4462,9 @@
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"pathPrefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
@ -4133,6 +4472,9 @@
|
||||
"providerUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"receiver": {
|
||||
"type": "string"
|
||||
},
|
||||
"regionId": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4172,11 +4514,17 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"prompted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"provider": {
|
||||
"$ref": "#/definitions/object.Provider"
|
||||
},
|
||||
"rule": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -4233,6 +4581,12 @@
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"domains": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"isEnabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@ -4345,6 +4699,10 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.SystemInfo": {
|
||||
"title": "SystemInfo",
|
||||
"type": "object"
|
||||
},
|
||||
"object.TableColumn": {
|
||||
"title": "TableColumn",
|
||||
"type": "object",
|
||||
@ -4605,15 +4963,27 @@
|
||||
"lastSigninTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"lastSigninWrongTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"ldap": {
|
||||
"type": "string"
|
||||
},
|
||||
"line": {
|
||||
"type": "string"
|
||||
},
|
||||
"linkedin": {
|
||||
"type": "string"
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
},
|
||||
"managedAccounts": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.ManagedAccount"
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4669,6 +5039,10 @@
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"signinWrongTimes": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"signupApplication": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -4687,9 +5061,6 @@
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"unionId": {
|
||||
"type": "string"
|
||||
},
|
||||
"updatedTime": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -177,6 +177,24 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/add-record:
|
||||
post:
|
||||
tags:
|
||||
- Record API
|
||||
description: add a record
|
||||
operationId: ApiController.AddRecord
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
description: The details of the record
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Record'
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/add-resource:
|
||||
post:
|
||||
tags:
|
||||
@ -277,6 +295,11 @@ paths:
|
||||
tags:
|
||||
- Login API
|
||||
operationId: ApiController.GetCaptcha
|
||||
/api/api/get-webhook-event:
|
||||
get:
|
||||
tags:
|
||||
- GetWebhookEventType API
|
||||
operationId: ApiController.GetWebhookEventType
|
||||
/api/api/reset-email-or-phone:
|
||||
post:
|
||||
tags:
|
||||
@ -338,6 +361,11 @@ paths:
|
||||
description: object
|
||||
schema:
|
||||
$ref: '#/definitions/Response'
|
||||
/api/api/webhook:
|
||||
post:
|
||||
tags:
|
||||
- HandleOfficialAccountEvent API
|
||||
operationId: ApiController.HandleOfficialAccountEvent
|
||||
/api/buy-product:
|
||||
post:
|
||||
tags:
|
||||
@ -542,6 +570,25 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/delete-session:
|
||||
post:
|
||||
tags:
|
||||
- Session API
|
||||
description: Delete session by userId
|
||||
operationId: ApiController.DeleteSession
|
||||
parameters:
|
||||
- in: query
|
||||
name: ID
|
||||
description: The ID(owner/name) of user.
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
/api/delete-syncer:
|
||||
post:
|
||||
tags:
|
||||
@ -734,6 +781,23 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Cert'
|
||||
/api/get-default-application:
|
||||
get:
|
||||
tags:
|
||||
- Organization API
|
||||
description: get default application
|
||||
operationId: ApiController.GetDefaultApplication
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: organization id
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/Response'
|
||||
/api/get-email-and-phone:
|
||||
post:
|
||||
tags:
|
||||
@ -756,6 +820,19 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/get-global-providers:
|
||||
get:
|
||||
tags:
|
||||
- Provider API
|
||||
description: get Global providers
|
||||
operationId: ApiController.GetGlobalProviders
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Provider'
|
||||
/api/get-global-users:
|
||||
get:
|
||||
tags:
|
||||
@ -947,6 +1024,38 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Permission'
|
||||
/api/get-permissions-by-role:
|
||||
get:
|
||||
tags:
|
||||
- Permission API
|
||||
description: get permissions by role
|
||||
operationId: ApiController.GetPermissionsByRole
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id of the role
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Permission'
|
||||
/api/get-permissions-by-submitter:
|
||||
get:
|
||||
tags:
|
||||
- Permission API
|
||||
description: get permissions by submitter
|
||||
operationId: ApiController.GetPermissionsBySubmitter
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Permission'
|
||||
/api/get-product:
|
||||
get:
|
||||
tags:
|
||||
@ -1060,6 +1169,15 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/object.Record'
|
||||
/api/get-release:
|
||||
get:
|
||||
tags:
|
||||
- System API
|
||||
description: get local github repo's latest release version info
|
||||
operationId: ApiController.GitRepoVersion
|
||||
responses:
|
||||
"200":
|
||||
description: '{string} local latest version hash of casdoor'
|
||||
/api/get-resource:
|
||||
get:
|
||||
tags:
|
||||
@ -1106,6 +1224,25 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Role'
|
||||
/api/get-sessions:
|
||||
get:
|
||||
tags:
|
||||
- Session API
|
||||
description: Get organization user sessions
|
||||
operationId: ApiController.GetSessions
|
||||
parameters:
|
||||
- in: query
|
||||
name: owner
|
||||
description: The organization name
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
/api/get-sorted-users:
|
||||
get:
|
||||
tags:
|
||||
@ -1170,6 +1307,23 @@ paths:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Syncer'
|
||||
/api/get-system-info:
|
||||
get:
|
||||
tags:
|
||||
- System API
|
||||
description: get user's system info
|
||||
operationId: ApiController.GetSystemInfo
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id of the user
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/object.SystemInfo'
|
||||
/api/get-token:
|
||||
get:
|
||||
tags:
|
||||
@ -1544,32 +1698,6 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/object.TokenError'
|
||||
/api/login/oauth/logout:
|
||||
get:
|
||||
tags:
|
||||
- Token API
|
||||
description: delete token by AccessToken
|
||||
operationId: ApiController.TokenLogout
|
||||
parameters:
|
||||
- in: query
|
||||
name: id_token_hint
|
||||
description: id_token_hint
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: post_logout_redirect_uri
|
||||
description: post_logout_redirect_uri
|
||||
type: string
|
||||
- in: query
|
||||
name: state
|
||||
description: state
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/login/oauth/refresh_token:
|
||||
post:
|
||||
tags:
|
||||
@ -1620,6 +1748,19 @@ paths:
|
||||
- Login API
|
||||
description: logout the current user
|
||||
operationId: ApiController.Logout
|
||||
parameters:
|
||||
- in: query
|
||||
name: id_token_hint
|
||||
description: id_token_hint
|
||||
type: string
|
||||
- in: query
|
||||
name: post_logout_redirect_uri
|
||||
description: post_logout_redirect_uri
|
||||
type: string
|
||||
- in: query
|
||||
name: state
|
||||
description: state
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
@ -1630,6 +1771,19 @@ paths:
|
||||
- Login API
|
||||
description: logout the current user
|
||||
operationId: ApiController.Logout
|
||||
parameters:
|
||||
- in: query
|
||||
name: id_token_hint
|
||||
description: id_token_hint
|
||||
type: string
|
||||
- in: query
|
||||
name: post_logout_redirect_uri
|
||||
description: post_logout_redirect_uri
|
||||
type: string
|
||||
- in: query
|
||||
name: state
|
||||
description: state
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
@ -2139,10 +2293,10 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/Response'
|
||||
definitions:
|
||||
2200.0xc0003f8480.false:
|
||||
2268.0xc0000f9650.false:
|
||||
title: "false"
|
||||
type: object
|
||||
2235.0xc0003f84b0.false:
|
||||
2302.0xc0000f9680.false:
|
||||
title: "false"
|
||||
type: object
|
||||
Response:
|
||||
@ -2174,6 +2328,12 @@ definitions:
|
||||
type: string
|
||||
autoSignin:
|
||||
type: boolean
|
||||
captchaToken:
|
||||
type: string
|
||||
captchaType:
|
||||
type: string
|
||||
clientSecret:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
email:
|
||||
@ -2223,9 +2383,9 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/2200.0xc0003f8480.false'
|
||||
$ref: '#/definitions/2268.0xc0000f9650.false'
|
||||
data2:
|
||||
$ref: '#/definitions/2235.0xc0003f84b0.false'
|
||||
$ref: '#/definitions/2302.0xc0000f9680.false'
|
||||
msg:
|
||||
type: string
|
||||
name:
|
||||
@ -2291,8 +2451,12 @@ definitions:
|
||||
type: string
|
||||
displayName:
|
||||
type: string
|
||||
enableAutoSignin:
|
||||
type: boolean
|
||||
enableCodeSignin:
|
||||
type: boolean
|
||||
enableLinkWithEmail:
|
||||
type: boolean
|
||||
enablePassword:
|
||||
type: boolean
|
||||
enableSamlCompress:
|
||||
@ -2308,6 +2472,15 @@ definitions:
|
||||
format: int64
|
||||
forgetUrl:
|
||||
type: string
|
||||
formBackgroundUrl:
|
||||
type: string
|
||||
formCss:
|
||||
type: string
|
||||
formOffset:
|
||||
type: integer
|
||||
format: int64
|
||||
formSideHtml:
|
||||
type: string
|
||||
grantTypes:
|
||||
type: array
|
||||
items:
|
||||
@ -2335,6 +2508,8 @@ definitions:
|
||||
refreshExpireInHours:
|
||||
type: integer
|
||||
format: int64
|
||||
samlReplyUrl:
|
||||
type: string
|
||||
signinHtml:
|
||||
type: string
|
||||
signinUrl:
|
||||
@ -2424,6 +2599,18 @@ definitions:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
object.ManagedAccount:
|
||||
title: ManagedAccount
|
||||
type: object
|
||||
properties:
|
||||
application:
|
||||
type: string
|
||||
password:
|
||||
type: string
|
||||
signinUrl:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
object.Model:
|
||||
title: Model
|
||||
type: object
|
||||
@ -2450,6 +2637,8 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
end_session_endpoint:
|
||||
type: string
|
||||
grant_types_supported:
|
||||
type: array
|
||||
items:
|
||||
@ -2500,6 +2689,8 @@ definitions:
|
||||
$ref: '#/definitions/object.AccountItem'
|
||||
createdTime:
|
||||
type: string
|
||||
defaultApplication:
|
||||
type: string
|
||||
defaultAvatar:
|
||||
type: string
|
||||
displayName:
|
||||
@ -2508,8 +2699,15 @@ definitions:
|
||||
type: boolean
|
||||
favicon:
|
||||
type: string
|
||||
initScore:
|
||||
type: integer
|
||||
format: int64
|
||||
isProfilePublic:
|
||||
type: boolean
|
||||
languages:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
masterPassword:
|
||||
type: string
|
||||
name:
|
||||
@ -2595,10 +2793,20 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
adapter:
|
||||
type: string
|
||||
approveTime:
|
||||
type: string
|
||||
approver:
|
||||
type: string
|
||||
createdTime:
|
||||
type: string
|
||||
displayName:
|
||||
type: string
|
||||
domains:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
effect:
|
||||
type: string
|
||||
isEnabled:
|
||||
@ -2619,6 +2827,10 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
submitter:
|
||||
type: string
|
||||
users:
|
||||
type: array
|
||||
items:
|
||||
@ -2631,6 +2843,8 @@ definitions:
|
||||
type: string
|
||||
currency:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
detail:
|
||||
type: string
|
||||
displayName:
|
||||
@ -2644,6 +2858,10 @@ definitions:
|
||||
price:
|
||||
type: number
|
||||
format: double
|
||||
providerObjs:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Provider'
|
||||
providers:
|
||||
type: array
|
||||
items:
|
||||
@ -2694,6 +2912,8 @@ definitions:
|
||||
type: string
|
||||
customUserInfoUrl:
|
||||
type: string
|
||||
disableSsl:
|
||||
type: boolean
|
||||
displayName:
|
||||
type: string
|
||||
domain:
|
||||
@ -2718,11 +2938,15 @@ definitions:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
pathPrefix:
|
||||
type: string
|
||||
port:
|
||||
type: integer
|
||||
format: int64
|
||||
providerUrl:
|
||||
type: string
|
||||
receiver:
|
||||
type: string
|
||||
regionId:
|
||||
type: string
|
||||
signName:
|
||||
@ -2749,10 +2973,14 @@ definitions:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
prompted:
|
||||
type: boolean
|
||||
provider:
|
||||
$ref: '#/definitions/object.Provider'
|
||||
rule:
|
||||
type: string
|
||||
object.Record:
|
||||
title: Record
|
||||
type: object
|
||||
@ -2790,6 +3018,10 @@ definitions:
|
||||
type: string
|
||||
displayName:
|
||||
type: string
|
||||
domains:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
isEnabled:
|
||||
type: boolean
|
||||
name:
|
||||
@ -2864,6 +3096,9 @@ definitions:
|
||||
type: string
|
||||
user:
|
||||
type: string
|
||||
object.SystemInfo:
|
||||
title: SystemInfo
|
||||
type: object
|
||||
object.TableColumn:
|
||||
title: TableColumn
|
||||
type: object
|
||||
@ -3040,12 +3275,20 @@ definitions:
|
||||
type: string
|
||||
lastSigninTime:
|
||||
type: string
|
||||
lastSigninWrongTime:
|
||||
type: string
|
||||
ldap:
|
||||
type: string
|
||||
line:
|
||||
type: string
|
||||
linkedin:
|
||||
type: string
|
||||
location:
|
||||
type: string
|
||||
managedAccounts:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.ManagedAccount'
|
||||
name:
|
||||
type: string
|
||||
okta:
|
||||
@ -3083,6 +3326,9 @@ definitions:
|
||||
score:
|
||||
type: integer
|
||||
format: int64
|
||||
signinWrongTimes:
|
||||
type: integer
|
||||
format: int64
|
||||
signupApplication:
|
||||
type: string
|
||||
slack:
|
||||
@ -3095,8 +3341,6 @@ definitions:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
unionId:
|
||||
type: string
|
||||
updatedTime:
|
||||
type: string
|
||||
webauthnCredentials:
|
||||
|
25
util/slice.go
Normal file
25
util/slice.go
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 util
|
||||
|
||||
func DeleteVal(values []string, val string) []string {
|
||||
newValues := []string{}
|
||||
for _, v := range values {
|
||||
if v != val {
|
||||
newValues = append(newValues, v)
|
||||
}
|
||||
}
|
||||
return newValues
|
||||
}
|
@ -123,8 +123,8 @@ func GenerateSimpleTimeId() string {
|
||||
return t
|
||||
}
|
||||
|
||||
func GetId(name string) string {
|
||||
return fmt.Sprintf("admin/%s", name)
|
||||
func GetId(owner, name string) string {
|
||||
return fmt.Sprintf("%s/%s", owner, name)
|
||||
}
|
||||
|
||||
func GetMd5Hash(text string) string {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user