Compare commits

...

28 Commits

Author SHA1 Message Date
jakiuncle
4dd67a8dcb fix: fix all frontend warnings (#983)
* fix:fix all frontend warnings

* fix:fix all frontend warnings

* fix:fix all frontend warnings

* fix:fix all frontend warnings

* fix:fix all frontend warnings

* fix:fix all frontend warnings
2022-08-09 12:19:56 +08:00
q1anx1
deed857788 chore(style): allow case declarations and ban var (#987)
* chore(style): allow case declarations

* chore(style): ban `var` and prefer `const`
2022-08-08 23:35:24 +08:00
Mikey
802995ed16 refactor: remove WeChat unionId to properties (#985) 2022-08-08 18:43:12 +08:00
q1anx1
b14554a5ba feat(web): check style when commit (#980)
feat(web): check style when commit
2022-08-08 00:10:31 +08:00
Gucheng Wang
4665ffa759 Update i18n data 2022-08-08 00:02:47 +08:00
Gucheng Wang
f914e8e929 Add permission_enforcer.go 2022-08-07 23:57:06 +08:00
Yixiang Zhao
dc33b41107 feat: expose some casbin APIs (#955)
* feat: expose some casbin APIs

Signed-off-by: Yixiang Zhao <seriouszyx@foxmail.com>

* feat: add BatchEnforce API

Signed-off-by: Yixiang Zhao <seriouszyx@foxmail.com>

* fix: solve requested changes

Signed-off-by: Yixiang Zhao <seriouszyx@foxmail.com>
2022-08-07 23:42:45 +08:00
Bingchang Chen
ee8dd23a56 fix: fixed footer css (#951) 2022-08-07 17:22:52 +08:00
github-actions[bot]
08d0269e30 refactor: New Crowdin translations by Github Action (#974)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2022-08-07 16:06:52 +08:00
leoshine
8e5cd18c91 fix: Restrict the request permissions of providers and applications (#970) 2022-08-07 16:05:05 +08:00
Gucheng Wang
32b4d98c2a Add ExtendProductWithProviders(). 2022-08-07 15:45:06 +08:00
q1anx1
2ea58cd639 chore(style): use gofumpt to fmt go code (#967) 2022-08-07 12:26:14 +08:00
q1anx1
45d2745b67 chore(style): add eslint rules: no-unused-imports and no-unused-vars (#976)
* feat(web): no-unused-imports and no-unused-vars

* chore: fix json style
2022-08-07 11:51:53 +08:00
Yang Luo
cba338eef2 Merge pull request #973 from qianxi0410/eslint
feat(web): add some eslint rules
2022-08-07 00:41:51 +08:00
qianxi0410
c428de6e42 feat: fix some comma dangle 2022-08-07 00:17:27 +08:00
qianxi0410
9bca6bb72e feat: no-multi-spacing 2022-08-07 00:06:20 +08:00
qianxi0410
cd966116d4 feat: comma dangle 2022-08-06 23:54:56 +08:00
qianxi0410
9abf1b9d73 feat: key spacing 2022-08-06 23:47:28 +08:00
qianxi0410
6aaba6debd feat: space between infix op 2022-08-06 23:43:09 +08:00
qianxi0410
77565712e0 feat: no-multi-empty-lines 2022-08-06 23:38:03 +08:00
qianxi0410
d025259db7 feat: indent 2022-08-06 23:36:20 +08:00
Artem
aafdc546fa fix: panic when creating a user in a non-existent org (#969) 2022-08-06 22:30:56 +08:00
q1anx1
539ca2d731 chore(web): add fix command (#964) 2022-08-05 23:40:04 +08:00
Ryao
ea326b3513 fix: show social buttons on signup page (#962) 2022-08-05 18:59:56 +08:00
Товарищ программист
98ef766fb4 fix: fix webauthn entry cannot add bug (#960)
* fix: fix webauthn

* Update LoginPage.js

Co-authored-by: Yang Luo <hsluoyz@qq.com>
2022-08-05 17:43:04 +08:00
Gucheng Wang
e94ada9ea2 Fix new accountItem. 2022-08-05 15:36:07 +08:00
Resulte Lee
4ea482223d feat: add geetest captcha (#953) 2022-08-04 20:55:04 +08:00
Gucheng Wang
d55ae7d1d2 Enable some other DBs 2022-08-04 20:28:09 +08:00
169 changed files with 1970 additions and 1118 deletions

View File

@@ -68,7 +68,7 @@ m = (r.subOwner == p.subOwner || p.subOwner == "*") && \
Enforcer.ClearPolicy()
//if len(Enforcer.GetPolicy()) == 0 {
// if len(Enforcer.GetPolicy()) == 0 {
if true {
ruleText := `
p, built-in, *, *, *, *, *
@@ -83,7 +83,7 @@ p, *, *, GET, /api/get-account, *, *
p, *, *, GET, /api/userinfo, *, *
p, *, *, *, /api/login/oauth, *, *
p, *, *, GET, /api/get-application, *, *
p, *, *, GET, /api/get-applications, *, *
p, *, *, GET, /api/get-organization-applications, *, *
p, *, *, GET, /api/get-user, *, *
p, *, *, GET, /api/get-user-application, *, *
p, *, *, GET, /api/get-resources, *, *
@@ -92,7 +92,6 @@ p, *, *, POST, /api/buy-product, *, *
p, *, *, GET, /api/get-payment, *, *
p, *, *, POST, /api/update-payment, *, *
p, *, *, POST, /api/invoice-payment, *, *
p, *, *, GET, /api/get-providers, *, *
p, *, *, POST, /api/notify-payment, *, *
p, *, *, POST, /api/unlink, *, *
p, *, *, POST, /api/set-password, *, *

View File

@@ -31,8 +31,7 @@ import (
const AliyunCaptchaVerifyUrl = "http://afs.aliyuncs.com"
type AliyunCaptchaProvider struct {
}
type AliyunCaptchaProvider struct{}
func NewAliyunCaptchaProvider() *AliyunCaptchaProvider {
captcha := &AliyunCaptchaProvider{}

View File

@@ -16,8 +16,7 @@ package captcha
import "github.com/casdoor/casdoor/object"
type DefaultCaptchaProvider struct {
}
type DefaultCaptchaProvider struct{}
func NewDefaultCaptchaProvider() *DefaultCaptchaProvider {
captcha := &DefaultCaptchaProvider{}

81
captcha/geetest.go Normal file
View File

@@ -0,0 +1,81 @@
// 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"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"time"
"github.com/casdoor/casdoor/util"
)
const GEETESTCaptchaVerifyUrl = "http://gcaptcha4.geetest.com/validate"
type GEETESTCaptchaProvider struct{}
func NewGEETESTCaptchaProvider() *GEETESTCaptchaProvider {
captcha := &GEETESTCaptchaProvider{}
return captcha
}
func (captcha *GEETESTCaptchaProvider) VerifyCaptcha(token, clientSecret string) (bool, error) {
pathData, err := url.ParseQuery(token)
if err != nil {
return false, err
}
signToken := util.GetHmacSha256(clientSecret, pathData["lot_number"][0])
formData := make(url.Values)
formData["lot_number"] = []string{pathData["lot_number"][0]}
formData["captcha_output"] = []string{pathData["captcha_output"][0]}
formData["pass_token"] = []string{pathData["pass_token"][0]}
formData["gen_time"] = []string{pathData["gen_time"][0]}
formData["sign_token"] = []string{signToken}
captchaId := pathData["captcha_id"][0]
cli := http.Client{Timeout: time.Second * 5}
resp, err := cli.PostForm(fmt.Sprintf("%s?captcha_id=%s", GEETESTCaptchaVerifyUrl, captchaId), formData)
if err != nil || resp.StatusCode != 200 {
return false, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
type captchaResponse struct {
Result string `json:"result"`
Reason string `json:"reason"`
}
captchaResp := &captchaResponse{}
err = json.Unmarshal(body, captchaResp)
if err != nil {
return false, err
}
if captchaResp.Result == "success" {
return true, nil
}
return false, errors.New(captchaResp.Reason)
}

View File

@@ -25,8 +25,7 @@ import (
const HCaptchaVerifyUrl = "https://hcaptcha.com/siteverify"
type HCaptchaProvider struct {
}
type HCaptchaProvider struct{}
func NewHCaptchaProvider() *HCaptchaProvider {
captcha := &HCaptchaProvider{}

View File

@@ -27,6 +27,8 @@ func GetCaptchaProvider(captchaType string) CaptchaProvider {
return NewHCaptchaProvider()
} else if captchaType == "Aliyun Captcha" {
return NewAliyunCaptchaProvider()
} else if captchaType == "GEETEST" {
return NewGEETESTCaptchaProvider()
}
return nil
}

View File

@@ -25,8 +25,7 @@ import (
const ReCaptchaVerifyUrl = "https://recaptcha.net/recaptcha/api/siteverify"
type ReCaptchaProvider struct {
}
type ReCaptchaProvider struct{}
func NewReCaptchaProvider() *ReCaptchaProvider {
captcha := &ReCaptchaProvider{}

View File

@@ -48,8 +48,8 @@ func GetConfigInt64(key string) (int64, error) {
}
func init() {
//this array contains the beego configuration items that may be modified via env
var presetConfigItems = []string{"httpport", "appname"}
// this array contains the beego configuration items that may be modified via env
presetConfigItems := []string{"httpport", "appname"}
for _, key := range presetConfigItems {
if value, ok := os.LookupEnv(key); ok {
beego.AppConfig.Set(key, value)

View File

@@ -32,7 +32,7 @@ func TestGetConfString(t *testing.T) {
{"Should be return value", "key", "value"},
}
//do some set up job
// do some set up job
os.Setenv("appname", "casbin")
os.Setenv("key", "value")
@@ -58,7 +58,7 @@ func TestGetConfInt(t *testing.T) {
{"Should be return 8000", "verificationCodeTimeout", 10},
}
//do some set up job
// do some set up job
os.Setenv("httpport", "8001")
err := beego.LoadAppConfig("ini", "app.conf")

View File

@@ -94,6 +94,29 @@ func (c *ApiController) GetUserApplication() {
c.ServeJSON()
}
// GetOrganizationApplications
// @Title GetOrganizationApplications
// @Tag Application API
// @Description get the detail of the organization's application
// @Param organization query string true "The organization name"
// @Success 200 {array} object.Application The Response object
// @router /get-organization-applications [get]
func (c *ApiController) GetOrganizationApplications() {
userId := c.GetSessionUsername()
owner := c.Input().Get("owner")
organization := c.Input().Get("organization")
if organization == "" {
c.ResponseError("Parameter organization is missing")
return
}
var applications []*object.Application
applications = object.GetApplicationsByOrganizationName(owner, organization)
c.Data["json"] = object.GetMaskedApplications(applications, userId)
c.ServeJSON()
}
// UpdateApplication
// @Title UpdateApplication
// @Tag Application API

View File

@@ -44,7 +44,6 @@ func tokenToResponse(token *object.Token) *Response {
return &Response{Status: "error", Msg: "fail to get accessToken", Data: token.AccessToken}
}
return &Response{Status: "ok", Msg: "", Data: token.AccessToken}
}
// HandleLoggedIn ...
@@ -86,7 +85,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
// The prompt page needs the user to be signed in
c.SetSessionUsername(userId)
}
} else if form.Type == ResponseTypeToken || form.Type == ResponseTypeIdToken { //implicit flow
} else if form.Type == ResponseTypeToken || form.Type == ResponseTypeIdToken { // implicit flow
if !object.IsGrantTypeValid(form.Type, application.GrantTypes) {
resp = &Response{Status: "error", Msg: fmt.Sprintf("error: grant_type: %s is not supported in this application", form.Type), Data: ""}
} else {
@@ -94,7 +93,6 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
token, _ := object.GetTokenByUser(application, user, scope, c.Ctx.Request.Host)
resp = tokenToResponse(token)
}
} else if form.Type == ResponseTypeSaml { // saml flow
res, redirectUrl, err := object.GetSamlResponse(application, user, form.SamlRequest, c.Ctx.Request.Host)
if err != nil {
@@ -103,7 +101,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
}
resp = &Response{Status: "ok", Msg: "", Data: res, Data2: redirectUrl}
} else if form.Type == ResponseTypeCas {
//not oauth but CAS SSO protocol
// not oauth but CAS SSO protocol
service := c.Input().Get("service")
resp = wrapErrorResponse(nil)
if service != "" {
@@ -430,7 +428,7 @@ func (c *ApiController) Login() {
} else if provider.Category == "SAML" {
resp = &Response{Status: "error", Msg: "The account does not exist"}
}
//resp = &Response{Status: "ok", Msg: "", Data: res}
// resp = &Response{Status: "ok", Msg: "", Data: res}
} else { // form.Method != "signup"
userId := c.GetSessionUsername()
if userId == "" {

View File

@@ -44,14 +44,13 @@ func (c *RootController) CasValidate() {
return
}
if ok, response, issuedService, _ := object.GetCasTokenByTicket(ticket); ok {
//check whether service is the one for which we previously issued token
// check whether service is the one for which we previously issued token
if issuedService == service {
c.Ctx.Output.Body([]byte(fmt.Sprintf("yes\n%s\n", response.User)))
return
}
}
//token not found
// token not found
c.Ctx.Output.Body([]byte("no\n"))
}
@@ -83,39 +82,39 @@ func (c *RootController) CasP3ServiceAndProxyValidate() {
Xmlns: "http://www.yale.edu/tp/cas",
}
//check whether all required parameters are met
// check whether all required parameters are met
if service == "" || ticket == "" {
c.sendCasAuthenticationResponseErr(InvalidRequest, "service and ticket must exist", format)
return
}
ok, response, issuedService, userId := object.GetCasTokenByTicket(ticket)
//find the token
// find the token
if ok {
//check whether service is the one for which we previously issued token
// check whether service is the one for which we previously issued token
if strings.HasPrefix(service, issuedService) {
serviceResponse.Success = response
} else {
//service not match
// service not match
c.sendCasAuthenticationResponseErr(InvalidService, fmt.Sprintf("service %s and %s does not match", service, issuedService), format)
return
}
} else {
//token not found
// token not found
c.sendCasAuthenticationResponseErr(InvalidTicket, fmt.Sprintf("Ticket %s not recognized", ticket), format)
return
}
if pgtUrl != "" && serviceResponse.Failure == nil {
//that means we are in proxy web flow
// that means we are in proxy web flow
pgt := object.StoreCasTokenForPgt(serviceResponse.Success, service, userId)
pgtiou := serviceResponse.Success.ProxyGrantingTicket
//todo: check whether it is https
// todo: check whether it is https
pgtUrlObj, err := url.Parse(pgtUrl)
if pgtUrlObj.Scheme != "https" {
c.sendCasAuthenticationResponseErr(InvalidProxyCallback, "callback is not https", format)
return
}
//make a request to pgturl passing pgt and pgtiou
// make a request to pgturl passing pgt and pgtiou
if err != nil {
c.sendCasAuthenticationResponseErr(InteralError, err.Error(), format)
return
@@ -133,7 +132,7 @@ func (c *RootController) CasP3ServiceAndProxyValidate() {
resp, err := http.DefaultClient.Do(request)
if err != nil || !(resp.StatusCode >= 200 && resp.StatusCode < 400) {
//failed to send request
// failed to send request
c.sendCasAuthenticationResponseErr(InvalidProxyCallback, err.Error(), format)
return
}
@@ -184,7 +183,6 @@ func (c *RootController) CasProxy() {
c.Data["xml"] = serviceResponse
c.ServeXML()
}
}
func (c *RootController) SamlValidate() {

88
controllers/enforcer.go Normal file
View File

@@ -0,0 +1,88 @@
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package controllers
import (
"encoding/json"
"github.com/casdoor/casdoor/object"
)
func (c *ApiController) Enforce() {
userId := c.GetSessionUsername()
if userId == "" {
c.ResponseError("Please sign in first")
return
}
var permissionRule object.PermissionRule
err := json.Unmarshal(c.Ctx.Input.RequestBody, &permissionRule)
if err != nil {
panic(err)
}
c.Data["json"] = object.Enforce(userId, &permissionRule)
c.ServeJSON()
}
func (c *ApiController) BatchEnforce() {
userId := c.GetSessionUsername()
if userId == "" {
c.ResponseError("Please sign in first")
return
}
var permissionRules []object.PermissionRule
err := json.Unmarshal(c.Ctx.Input.RequestBody, &permissionRules)
if err != nil {
panic(err)
}
c.Data["json"] = object.BatchEnforce(userId, permissionRules)
c.ServeJSON()
}
func (c *ApiController) GetAllObjects() {
userId := c.GetSessionUsername()
if userId == "" {
c.ResponseError("Please sign in first")
return
}
c.Data["json"] = object.GetAllObjects(userId)
c.ServeJSON()
}
func (c *ApiController) GetAllActions() {
userId := c.GetSessionUsername()
if userId == "" {
c.ResponseError("Please sign in first")
return
}
c.Data["json"] = object.GetAllActions(userId)
c.ServeJSON()
}
func (c *ApiController) GetAllRoles() {
userId := c.GetSessionUsername()
if userId == "" {
c.ResponseError("Please sign in first")
return
}
c.Data["json"] = object.GetAllRoles(userId)
c.ServeJSON()
}

View File

@@ -30,7 +30,7 @@ type LdapServer struct {
}
type LdapResp struct {
//Groups []LdapRespGroup `json:"groups"`
// Groups []LdapRespGroup `json:"groups"`
Users []object.LdapRespUser `json:"users"`
}
@@ -88,7 +88,7 @@ func (c *ApiController) GetLdapUser() {
Uid: user.Uid,
Cn: user.Cn,
GroupId: user.GidNumber,
//GroupName: groupsMap[user.GidNumber].Cn,
// GroupName: groupsMap[user.GidNumber].Cn,
Uuid: user.Uuid,
Email: util.GetMaxLenStr(user.Mail, user.Email, user.EmailAddress),
Phone: util.GetMaxLenStr(user.TelephoneNumber, user.Mobile, user.MobileTelephoneNumber),

View File

@@ -58,7 +58,10 @@ func (c *ApiController) GetProducts() {
func (c *ApiController) GetProduct() {
id := c.Input().Get("id")
c.Data["json"] = object.GetProduct(id)
product := object.GetProduct(id)
object.ExtendProductWithProviders(product)
c.Data["json"] = product
c.ServeJSON()
}

View File

@@ -16,6 +16,7 @@ package controllers
import (
"encoding/json"
"github.com/astaxie/beego/utils/pagination"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"

View File

@@ -16,6 +16,7 @@ package controllers
import (
"encoding/json"
"github.com/astaxie/beego/utils/pagination"
"github.com/casdoor/casdoor/object"
"github.com/casdoor/casdoor/util"

View File

@@ -24,7 +24,6 @@ func NewArgon2idCredManager() *Argon2idCredManager {
}
func (cm *Argon2idCredManager) GetHashedPassword(password string, userSalt string, organizationSalt string) string {
hash, err := argon2id.CreateHash(password, argon2id.DefaultParams)
if err != nil {
return ""

View File

@@ -17,6 +17,7 @@ package cred
import (
"crypto/sha256"
"encoding/base64"
"golang.org/x/crypto/pbkdf2"
)
@@ -36,4 +37,4 @@ func (cm *Pbkdf2SaltCredManager) GetHashedPassword(password string, userSalt str
func (cm *Pbkdf2SaltCredManager) IsPasswordCorrect(plainPwd string, hashedPwd string, userSalt string, organizationSalt string) bool {
return hashedPwd == cm.GetHashedPassword(plainPwd, userSalt, organizationSalt)
}
}

2
go.mod
View File

@@ -14,6 +14,7 @@ require (
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/duo-labs/webauthn v0.0.0-20211221191814-a22482edaa3b
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
github.com/go-ldap/ldap/v3 v3.3.0
@@ -23,6 +24,7 @@ require (
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/lib/pq v1.8.0
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

2
go.sum
View File

@@ -125,6 +125,7 @@ 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/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/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=
@@ -173,6 +174,7 @@ github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptG
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
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/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=

View File

@@ -59,12 +59,12 @@ func (idp *AdfsIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *AdfsIdProvider) getConfig(hostUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
AuthURL: fmt.Sprintf("%s/adfs/oauth2/authorize", hostUrl),
TokenURL: fmt.Sprintf("%s/adfs/oauth2/token", hostUrl),
}
var config = &oauth2.Config{
config := &oauth2.Config{
Endpoint: endpoint,
}

View File

@@ -56,12 +56,12 @@ func (idp *AlipayIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *AlipayIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
AuthURL: "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm",
TokenURL: "https://openapi.alipay.com/gateway.do",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"", ""},
Endpoint: endpoint,
ClientID: clientId,
@@ -206,7 +206,6 @@ func (idp *AlipayIdProvider) postWithBody(body interface{}, targetUrl string) ([
return nil, err
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

View File

@@ -46,12 +46,12 @@ func (idp *BaiduIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *BaiduIdProvider) getConfig() *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
AuthURL: "https://openapi.baidu.com/oauth/2.0/authorize",
TokenURL: "https://openapi.baidu.com/oauth/2.0/token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"email"},
Endpoint: endpoint,
}

View File

@@ -47,12 +47,12 @@ func (idp *BilibiliIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *BilibiliIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://api.bilibili.com/x/account-oauth2/v1/token",
AuthURL: "http://member.bilibili.com/arcopen/fn/user/account/info",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"", ""},
Endpoint: endpoint,
ClientID: clientId,
@@ -104,7 +104,6 @@ func (idp *BilibiliIdProvider) GetToken(code string) (*oauth2.Token, error) {
}
data, err := idp.postWithBody(pTokenParams, idp.Config.Endpoint.TokenURL)
if err != nil {
return nil, err
}
@@ -167,7 +166,6 @@ func (idp *BilibiliIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
userInfoUrl := fmt.Sprintf("%s?%s", idp.Config.Endpoint.AuthURL, params.Encode())
resp, err := idp.Client.Get(userInfoUrl)
if err != nil {
return nil, err
}

View File

@@ -72,7 +72,6 @@ func (idp *CasdoorIdProvider) GetToken(code string) (*oauth2.Token, error) {
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
@@ -82,7 +81,7 @@ func (idp *CasdoorIdProvider) GetToken(code string) (*oauth2.Token, error) {
return nil, err
}
//check if token is expired
// check if token is expired
if pToken.ExpiresIn <= 0 {
return nil, fmt.Errorf("%s", pToken.AccessToken)
}
@@ -91,7 +90,6 @@ func (idp *CasdoorIdProvider) GetToken(code string) (*oauth2.Token, error) {
Expiry: time.Unix(time.Now().Unix()+int64(pToken.ExpiresIn), 0),
}
return token, nil
}
/*
@@ -125,7 +123,7 @@ func (idp *CasdoorIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error
if err != nil {
return nil, err
}
//add accesstoken to bearer token
// add accesstoken to bearer token
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))
resp, err := idp.Client.Do(request)
if err != nil {
@@ -155,5 +153,4 @@ func (idp *CasdoorIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error
AvatarUrl: cdUserinfo.AvatarUrl,
}
return userInfo, nil
}

View File

@@ -36,7 +36,7 @@ func NewCustomIdProvider(clientId string, clientSecret string, redirectUrl strin
idp := &CustomIdProvider{}
idp.UserInfoUrl = userInfoUrl
var config = &oauth2.Config{
config := &oauth2.Config{
ClientID: clientId,
ClientSecret: clientSecret,
RedirectURL: redirectUrl,
@@ -76,7 +76,7 @@ func (idp *CustomIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
if err != nil {
return nil, err
}
//add accessToken to request header
// add accessToken to request header
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))
resp, err := idp.Client.Do(request)
if err != nil {

View File

@@ -48,12 +48,12 @@ func (idp *DingTalkIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *DingTalkIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
AuthURL: "https://api.dingtalk.com/v1.0/contact/users/me",
TokenURL: "https://api.dingtalk.com/v1.0/oauth2/userAccessToken",
}
var config = &oauth2.Config{
config := &oauth2.Config{
// DingTalk not allow to set scopes,here it is just a placeholder,
// convenient to use later
Scopes: []string{"", ""},

View File

@@ -42,12 +42,12 @@ func (idp *DouyinIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *DouyinIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://open.douyin.com/oauth/access_token",
AuthURL: "https://open.douyin.com/platform/oauth/connect",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"user_info"},
Endpoint: endpoint,
ClientID: clientId,

View File

@@ -46,11 +46,11 @@ func (idp *FacebookIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *FacebookIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://graph.facebook.com/oauth/access_token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"email,public_profile"},
Endpoint: endpoint,
ClientID: clientId,
@@ -62,9 +62,9 @@ func (idp *FacebookIdProvider) getConfig(clientId string, clientSecret string, r
}
type FacebookAccessToken struct {
AccessToken string `json:"access_token"` //Interface call credentials
TokenType string `json:"token_type"` //Access token type
ExpiresIn int64 `json:"expires_in"` //access_token interface call credential timeout time, unit (seconds)
AccessToken string `json:"access_token"` // Interface call credentials
TokenType string `json:"token_type"` // Access token type
ExpiresIn int64 `json:"expires_in"` // access_token interface call credential timeout time, unit (seconds)
}
type FacebookCheckToken struct {

View File

@@ -49,11 +49,11 @@ func (idp *GiteeIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *GiteeIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://gitee.com/oauth/token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"user_info emails"},
Endpoint: endpoint,

View File

@@ -49,12 +49,12 @@ func (idp *GithubIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *GithubIdProvider) getConfig() *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
AuthURL: "https://github.com/login/oauth/authorize",
TokenURL: "https://github.com/login/oauth/access_token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"user:email", "read:user"},
Endpoint: endpoint,
}
@@ -93,7 +93,6 @@ func (idp *GithubIdProvider) GetToken(code string) (*oauth2.Token, error) {
}
return token, nil
}
//{

View File

@@ -46,11 +46,11 @@ func (idp *GitlabIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *GitlabIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://gitlab.com/oauth/token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"read_user+profile"},
Endpoint: endpoint,
ClientID: clientId,

View File

@@ -47,12 +47,12 @@ func (idp *GoogleIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *GoogleIdProvider) getConfig() *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
AuthURL: "https://accounts.google.com/o/oauth2/auth",
TokenURL: "https://accounts.google.com/o/oauth2/token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"profile", "email"},
Endpoint: endpoint,
}

View File

@@ -207,7 +207,7 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
return &idp
}
//Goth's idp all implement the Client method, but since the goth.Provider interface does not provide to modify idp's client method, reflection is required
// Goth's idp all implement the Client method, but since the goth.Provider interface does not provide to modify idp's client method, reflection is required
func (idp *GothIdProvider) SetHttpClient(client *http.Client) {
idpClient := reflect.ValueOf(idp.Provider).Elem().FieldByName("HTTPClient")
idpClient.Set(reflect.ValueOf(client))
@@ -225,8 +225,8 @@ func (idp *GothIdProvider) GetToken(code string) (*oauth2.Token, error) {
return nil, err
}
} else {
//Need to construct variables supported by goth
//to call the function to obtain accessToken
// Need to construct variables supported by goth
// to call the function to obtain accessToken
value = url.Values{}
value.Add("code", code)
}
@@ -235,7 +235,7 @@ func (idp *GothIdProvider) GetToken(code string) (*oauth2.Token, error) {
return nil, err
}
//Get ExpiresAt's value
// Get ExpiresAt's value
valueOfExpire := reflect.ValueOf(idp.Session).Elem().FieldByName("ExpiresAt")
if valueOfExpire.IsValid() {
expireAt = valueOfExpire.Interface().(time.Time)
@@ -264,8 +264,8 @@ func getUser(gothUser goth.User, provider string) *UserInfo {
Email: gothUser.Email,
AvatarUrl: gothUser.AvatarURL,
}
//Some idp return an empty Name
//so construct the Name with firstname and lastname or nickname
// Some idp return an empty Name
// so construct the Name with firstname and lastname or nickname
if user.Username == "" {
if gothUser.FirstName != "" && gothUser.LastName != "" {
user.Username = getName(gothUser.FirstName, gothUser.LastName)

View File

@@ -43,7 +43,7 @@ func (idp *InfoflowInternalIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *InfoflowInternalIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var config = &oauth2.Config{
config := &oauth2.Config{
ClientID: clientId,
ClientSecret: clientSecret,
RedirectURL: redirectUrl,
@@ -139,7 +139,7 @@ type InfoflowInternalUserInfo struct {
// get more detail via: https://qy.baidu.com/doc/index.html#/inner_serverapi/contacts?id=%e8%8e%b7%e5%8f%96%e6%88%90%e5%91%98
func (idp *InfoflowInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
//Get userid first
// Get userid first
accessToken := token.AccessToken
code := token.Extra("code").(string)
resp, err := idp.Client.Get(fmt.Sprintf("https://qy.im.baidu.com/api/user/getuserinfo?access_token=%s&code=%s&agentid=%s", accessToken, code, idp.AgentId))
@@ -159,7 +159,7 @@ func (idp *InfoflowInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserIn
if userResp.Errcode != 0 {
return nil, fmt.Errorf("userIdResp.Errcode = %d, userIdResp.Errmsg = %s", userResp.Errcode, userResp.Errmsg)
}
//Use userid and accesstoken to get user information
// Use userid and accesstoken to get user information
resp, err = idp.Client.Get(fmt.Sprintf("https://api.im.baidu.com/api/user/get?access_token=%s&userid=%s", accessToken, userResp.UserId))
if err != nil {
return nil, err

View File

@@ -47,7 +47,7 @@ func (idp *InfoflowIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *InfoflowIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var config = &oauth2.Config{
config := &oauth2.Config{
ClientID: clientId,
ClientSecret: clientSecret,
RedirectURL: redirectUrl,
@@ -136,7 +136,7 @@ type InfoflowUserInfo struct {
// get more detail via: https://qy.baidu.com/doc/index.html#/third_serverapi/contacts?id=%e8%8e%b7%e5%8f%96%e6%88%90%e5%91%98
func (idp *InfoflowIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
//Get userid first
// Get userid first
accessToken := token.AccessToken
code := token.Extra("code").(string)
resp, err := idp.Client.Get(fmt.Sprintf("https://api.im.baidu.com/api/user/getuserinfo?access_token=%s&code=%s&agentid=%s", accessToken, code, idp.AgentId))
@@ -156,7 +156,7 @@ func (idp *InfoflowIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
if userResp.Errcode != 0 {
return nil, fmt.Errorf("userIdResp.Errcode = %d, userIdResp.Errmsg = %s", userResp.Errcode, userResp.Errmsg)
}
//Use userid and accesstoken to get user information
// Use userid and accesstoken to get user information
resp, err = idp.Client.Get(fmt.Sprintf("https://api.im.baidu.com/api/user/get?access_token=%s&userid=%s", accessToken, userResp.UserId))
if err != nil {
return nil, err

View File

@@ -45,11 +45,11 @@ func (idp *LarkIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *LarkIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{},
Endpoint: endpoint,
ClientID: clientId,

View File

@@ -47,11 +47,11 @@ func (idp *LinkedInIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *LinkedInIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://www.linkedIn.com/oauth/v2/accessToken",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"email,public_profile"},
Endpoint: endpoint,
ClientID: clientId,
@@ -63,8 +63,8 @@ func (idp *LinkedInIdProvider) getConfig(clientId string, clientSecret string, r
}
type LinkedInAccessToken struct {
AccessToken string `json:"access_token"` //Interface call credentials
ExpiresIn int64 `json:"expires_in"` //access_token interface call credential timeout time, unit (seconds)
AccessToken string `json:"access_token"` // Interface call credentials
ExpiresIn int64 `json:"expires_in"` // access_token interface call credential timeout time, unit (seconds)
}
// GetToken use code get access_token (*operation of getting code ought to be done in front)

View File

@@ -48,12 +48,12 @@ func (idp *OktaIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *OktaIdProvider) getConfig(hostUrl string, clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: fmt.Sprintf("%s/v1/token", hostUrl),
AuthURL: fmt.Sprintf("%s/v1/authorize", hostUrl),
}
var config = &oauth2.Config{
config := &oauth2.Config{
// openid is required for authentication requests
// get more details via: https://developer.okta.com/docs/reference/api/oidc/#reserved-scopes
Scopes: []string{"openid", "profile", "email"},

View File

@@ -48,11 +48,11 @@ func (idp *QqIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *QqIdProvider) getConfig() *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://graph.qq.com/oauth2.0/token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"get_user_info"},
Endpoint: endpoint,
}

View File

@@ -47,11 +47,11 @@ func (idp *WeChatIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *WeChatIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://graph.qq.com/oauth2.0/token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"snsapi_login"},
Endpoint: endpoint,
ClientID: clientId,
@@ -63,12 +63,12 @@ func (idp *WeChatIdProvider) getConfig(clientId string, clientSecret string, red
}
type WechatAccessToken struct {
AccessToken string `json:"access_token"` //Interface call credentials
ExpiresIn int64 `json:"expires_in"` //access_token interface call credential timeout time, unit (seconds)
RefreshToken string `json:"refresh_token"` //User refresh access_token
Openid string `json:"openid"` //Unique ID of authorized user
Scope string `json:"scope"` //The scope of user authorization, separated by commas. (,)
Unionid string `json:"unionid"` //This field will appear if and only if the website application has been authorized by the user's UserInfo.
AccessToken string `json:"access_token"` // Interface call credentials
ExpiresIn int64 `json:"expires_in"` // access_token interface call credential timeout time, unit (seconds)
RefreshToken string `json:"refresh_token"` // User refresh access_token
Openid string `json:"openid"` // Unique ID of authorized user
Scope string `json:"scope"` // The scope of user authorization, separated by commas. (,)
Unionid string `json:"unionid"` // This field will appear if and only if the website application has been authorized by the user's UserInfo.
}
// GetToken use code get access_token (*operation of getting code ought to be done in front)

View File

@@ -42,7 +42,7 @@ func (idp *WeChatMiniProgramIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *WeChatMiniProgramIdProvider) getConfig(clientId string, clientSecret string) *oauth2.Config {
var config = &oauth2.Config{
config := &oauth2.Config{
ClientID: clientId,
ClientSecret: clientSecret,
}
@@ -78,5 +78,4 @@ func (idp *WeChatMiniProgramIdProvider) GetSessionByCode(code string) (*WeChatMi
return nil, fmt.Errorf("err: %s", session.Errmsg)
}
return &session, nil
}

View File

@@ -24,7 +24,7 @@ import (
"golang.org/x/oauth2"
)
//This idp is using wecom internal application api as idp
// This idp is using wecom internal application api as idp
type WeComInternalIdProvider struct {
Client *http.Client
Config *oauth2.Config
@@ -44,7 +44,7 @@ func (idp *WeComInternalIdProvider) SetHttpClient(client *http.Client) {
}
func (idp *WeComInternalIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var config = &oauth2.Config{
config := &oauth2.Config{
ClientID: clientId,
ClientSecret: clientSecret,
RedirectURL: redirectUrl,
@@ -115,7 +115,7 @@ type WecomInternalUserInfo struct {
}
func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
//Get userid first
// Get userid first
accessToken := token.AccessToken
code := token.Extra("code").(string)
resp, err := idp.Client.Get(fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s", accessToken, code))
@@ -138,7 +138,7 @@ func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo,
if userResp.OpenId != "" {
return nil, fmt.Errorf("not an internal user")
}
//Use userid and accesstoken to get user information
// Use userid and accesstoken to get user information
resp, err = idp.Client.Get(fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=%s&userid=%s", accessToken, userResp.UserId))
if err != nil {
return nil, err

View File

@@ -46,11 +46,11 @@ func (idp *WeComIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *WeComIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://graph.qq.com/oauth2.0/token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{"snsapi_login"},
Endpoint: endpoint,
ClientID: clientId,

View File

@@ -48,11 +48,11 @@ func (idp *WeiBoIdProvider) SetHttpClient(client *http.Client) {
// getConfig return a point of Config, which describes a typical 3-legged OAuth2 flow
func (idp *WeiBoIdProvider) getConfig(clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
var endpoint = oauth2.Endpoint{
endpoint := oauth2.Endpoint{
TokenURL: "https://api.weibo.com/oauth2/access_token",
}
var config = &oauth2.Config{
config := &oauth2.Config{
Scopes: []string{""},
Endpoint: endpoint,
ClientID: clientId,

View File

@@ -42,9 +42,9 @@ func main() {
proxy.InitHttpClient()
authz.InitAuthz()
util.SafeGoroutine(func() {object.RunSyncUsersJob()})
util.SafeGoroutine(func() { object.RunSyncUsersJob() })
//beego.DelStaticPath("/static")
// beego.DelStaticPath("/static")
beego.SetStaticPath("/static", "web/build/static")
beego.BConfig.WebConfig.DirectoryIndex = true
beego.SetStaticPath("/swagger", "swagger")
@@ -66,14 +66,14 @@ func main() {
beego.BConfig.WebConfig.Session.SessionProviderConfig = conf.GetConfigString("redisEndpoint")
}
beego.BConfig.WebConfig.Session.SessionCookieLifeTime = 3600 * 24 * 30
//beego.BConfig.WebConfig.Session.SessionCookieSameSite = http.SameSiteNoneMode
// beego.BConfig.WebConfig.Session.SessionCookieSameSite = http.SameSiteNoneMode
err := logs.SetLogger("file", `{"filename":"logs/casdoor.log","maxdays":99999,"perm":"0770"}`)
if err != nil {
panic(err)
}
port := beego.AppConfig.DefaultInt("httpport", 8000)
//logs.SetLevel(logs.LevelInformational)
// logs.SetLevel(logs.LevelInformational)
logs.SetLogFuncCall(false)
beego.Run(fmt.Sprintf(":%v", port))
}

View File

@@ -21,10 +21,10 @@ import (
"github.com/astaxie/beego"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/util"
//_ "github.com/denisenkom/go-mssqldb" // db = mssql
_ "github.com/go-sql-driver/mysql" // db = mysql
//_ "github.com/lib/pq" // db = postgres
//_ "github.com/mattn/go-sqlite3" // db = sqlite3
_ "github.com/denisenkom/go-mssqldb" // db = mssql
_ "github.com/go-sql-driver/mysql" // db = mysql
_ "github.com/lib/pq" // db = postgres
//_ "github.com/mattn/go-sqlite3" // db = sqlite3
"xorm.io/core"
"xorm.io/xorm"
)

View File

@@ -317,7 +317,7 @@ func (application *Application) GetId() string {
}
func CheckRedirectUriValid(application *Application, redirectUri string) bool {
var validUri = false
validUri := false
for _, tmpUri := range application.RedirectUris {
if strings.Contains(redirectUri, tmpUri) {
validUri = true

View File

@@ -182,7 +182,7 @@ func CheckUserPassword(organization string, username string, password string) (*
}
if user.Ldap != "" {
//ONLY for ldap users
// ONLY for ldap users
return checkLdapUserPassword(user, password)
} else {
msg := CheckPassword(user, password)

View File

@@ -56,7 +56,7 @@ type ldapUser struct {
Uid string
Cn string
GidNumber string
//Gcn string
// Gcn string
Uuid string
Mail string
Email string
@@ -73,7 +73,7 @@ type LdapRespUser struct {
Uid string `json:"uid"`
Cn string `json:"cn"`
GroupId string `json:"groupId"`
//GroupName string `json:"groupName"`
// GroupName string `json:"groupName"`
Uuid string `json:"uuid"`
Email string `json:"email"`
Phone string `json:"phone"`
@@ -208,11 +208,15 @@ func GetLdapConn(host string, port int, adminUser string, adminPasswd string) (*
func (l *ldapConn) GetLdapUsers(baseDn string) ([]ldapUser, error) {
SearchFilter := "(objectClass=posixAccount)"
SearchAttributes := []string{"uidNumber", "uid", "cn", "gidNumber", "entryUUID", "mail", "email",
"emailAddress", "telephoneNumber", "mobile", "mobileTelephoneNumber", "registeredAddress", "postalAddress"}
SearchAttributes := []string{
"uidNumber", "uid", "cn", "gidNumber", "entryUUID", "mail", "email",
"emailAddress", "telephoneNumber", "mobile", "mobileTelephoneNumber", "registeredAddress", "postalAddress",
}
SearchFilterMsAD := "(objectClass=user)"
SearchAttributesMsAD := []string{"uidNumber", "sAMAccountName", "cn", "gidNumber", "entryUUID", "mail", "email",
"emailAddress", "telephoneNumber", "mobile", "mobileTelephoneNumber", "registeredAddress", "postalAddress"}
SearchAttributesMsAD := []string{
"uidNumber", "sAMAccountName", "cn", "gidNumber", "entryUUID", "mail", "email",
"emailAddress", "telephoneNumber", "mobile", "mobileTelephoneNumber", "registeredAddress", "postalAddress",
}
var searchReq *goldap.SearchRequest
if l.IsAD {
searchReq = goldap.NewSearchRequest(baseDn,
@@ -459,7 +463,7 @@ func CheckLdapUuidExist(owner string, uuids []string) []string {
}
}
for uuid, _ := range existUuidSet {
for uuid := range existUuidSet {
existUuids = append(existUuids, uuid)
}
return existUuids

View File

@@ -31,7 +31,7 @@ func GetLdapAutoSynchronizer() *LdapAutoSynchronizer {
return globalLdapAutoSynchronizer
}
//start autosync for specified ldap, old existing autosync goroutine will be ceased
// start autosync for specified ldap, old existing autosync goroutine will be ceased
func (l *LdapAutoSynchronizer) StartAutoSync(ldapId string) error {
l.Lock()
defer l.Unlock()
@@ -48,7 +48,7 @@ func (l *LdapAutoSynchronizer) StartAutoSync(ldapId string) error {
stopChan := make(chan struct{})
l.ldapIdToStopChan[ldapId] = stopChan
logs.Info(fmt.Sprintf("autoSync started for %s", ldap.Id))
util.SafeGoroutine(func() {l.syncRoutine(ldap, stopChan)})
util.SafeGoroutine(func() { l.syncRoutine(ldap, stopChan) })
return nil
}
@@ -61,7 +61,7 @@ func (l *LdapAutoSynchronizer) StopAutoSync(ldapId string) {
}
}
//autosync goroutine
// autosync goroutine
func (l *LdapAutoSynchronizer) syncRoutine(ldap *Ldap, stopChan chan struct{}) {
ticker := time.NewTicker(time.Duration(ldap.AutoSync) * time.Minute)
defer ticker.Stop()
@@ -74,7 +74,7 @@ func (l *LdapAutoSynchronizer) syncRoutine(ldap *Ldap, stopChan chan struct{}) {
}
UpdateLdapSyncTime(ldap.Id)
//fetch all users
// fetch all users
conn, err := GetLdapConn(ldap.Host, ldap.Port, ldap.Admin, ldap.Passwd)
if err != nil {
logs.Warning(fmt.Sprintf("autoSync failed for %s, error %s", ldap.Id, err))
@@ -93,10 +93,9 @@ func (l *LdapAutoSynchronizer) syncRoutine(ldap *Ldap, stopChan chan struct{}) {
logs.Info(fmt.Sprintf("ldap autosync success, %d new users, %d existing users", len(users)-len(*existed), len(*existed)))
}
}
}
//start all autosync goroutine for existing ldap servers in each organizations
// start all autosync goroutine for existing ldap servers in each organizations
func (l *LdapAutoSynchronizer) LdapAutoSynchronizerStartUpAll() {
organizations := []*Organization{}
err := adapter.Engine.Desc("created_time").Find(&organizations)

View File

@@ -27,8 +27,8 @@ type Model struct {
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
DisplayName string `xorm:"varchar(100)" json:"displayName"`
ModelText string `xorm:"mediumtext" json:"modelText"`
IsEnabled bool `json:"isEnabled"`
ModelText string `xorm:"mediumtext" json:"modelText"`
IsEnabled bool `json:"isEnabled"`
}
func GetModelCount(owner, field, value string) int {

View File

@@ -93,9 +93,9 @@ func GetOidcDiscovery(host string) OidcDiscovery {
func GetJsonWebKeySet() (jose.JSONWebKeySet, error) {
certs := GetCerts("admin")
jwks := jose.JSONWebKeySet{}
//follows the protocol rfc 7517(draft)
//link here: https://self-issued.info/docs/draft-ietf-jose-json-web-key.html
//or https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key
// follows the protocol rfc 7517(draft)
// link here: https://self-issued.info/docs/draft-ietf-jose-json-web-key.html
// or https://datatracker.ietf.org/doc/html/draft-ietf-jose-json-web-key
for _, cert := range certs {
certPemBlock := []byte(cert.Certificate)
certDerBlock, _ := pem.Decode(certPemBlock)

View File

@@ -16,12 +16,7 @@ package object
import (
"fmt"
"strings"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
xormadapter "github.com/casbin/xorm-adapter/v2"
"github.com/casdoor/casdoor/conf"
"github.com/casdoor/casdoor/util"
"xorm.io/core"
)
@@ -45,13 +40,13 @@ type Permission struct {
}
type PermissionRule struct {
PType string `xorm:"varchar(100) index not null default ''"`
V0 string `xorm:"varchar(100) index not null default ''"`
V1 string `xorm:"varchar(100) index not null default ''"`
V2 string `xorm:"varchar(100) index not null default ''"`
V3 string `xorm:"varchar(100) index not null default ''"`
V4 string `xorm:"varchar(100) index not null default ''"`
V5 string `xorm:"varchar(100) index not null default ''"`
Ptype string `xorm:"varchar(100) index not null default ''" json:"ptype"`
V0 string `xorm:"varchar(100) index not null default ''" json:"v0"`
V1 string `xorm:"varchar(100) index not null default ''" json:"v1"`
V2 string `xorm:"varchar(100) index not null default ''" json:"v2"`
V3 string `xorm:"varchar(100) index not null default ''" json:"v3"`
V4 string `xorm:"varchar(100) index not null default ''" json:"v4"`
V5 string `xorm:"varchar(100) index not null default ''" json:"v5"`
}
func GetPermissionCount(owner, field, value string) int {
@@ -158,78 +153,6 @@ func (permission *Permission) GetId() string {
return fmt.Sprintf("%s/%s", permission.Owner, permission.Name)
}
func getEnforcer(permission *Permission) *casbin.Enforcer {
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
adapter, err := xormadapter.NewAdapterWithTableName(conf.GetConfigString("driverName"), conf.GetBeegoConfDataSourceName()+conf.GetConfigString("dbName"), "permission_rule", tableNamePrefix, true)
if err != nil {
panic(err)
}
modelText := `
[request_definition]
r = sub, obj, act
[policy_definition]
p = permission, sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act`
permissionModel := getModel(permission.Owner, permission.Model)
if permissionModel != nil {
modelText = permissionModel.ModelText
}
m, err := model.NewModelFromString(modelText)
if err != nil {
panic(err)
}
enforcer, err := casbin.NewEnforcer(m, adapter)
if err != nil {
panic(err)
}
err = enforcer.LoadFilteredPolicy(xormadapter.Filter{V0: []string{permission.GetId()}})
if err != nil {
panic(err)
}
return enforcer
}
func getPolicies(permission *Permission) [][]string {
var policies [][]string
for _, user := range permission.Users {
for _, resource := range permission.Resources {
for _, action := range permission.Actions {
policies = append(policies, []string{permission.GetId(), user, resource, strings.ToLower(action)})
}
}
}
return policies
}
func addPolicies(permission *Permission) {
enforcer := getEnforcer(permission)
policies := getPolicies(permission)
_, err := enforcer.AddPolicies(policies)
if err != nil {
panic(err)
}
}
func removePolicies(permission *Permission) {
enforcer := getEnforcer(permission)
_, err := enforcer.RemoveFilteredPolicy(0, permission.GetId())
if err != nil {
panic(err)
}
}
func GetPermissionsByUser(userId string) []*Permission {
permissions := []*Permission{}
err := adapter.Engine.Where("users like ?", "%"+userId+"%").Find(&permissions)

View File

@@ -0,0 +1,162 @@
// Copyright 2021 The Casdoor Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package object
import (
"strings"
"github.com/casbin/casbin/v2"
"github.com/casbin/casbin/v2/model"
xormadapter "github.com/casbin/xorm-adapter/v2"
"github.com/casdoor/casdoor/conf"
)
func getEnforcer(permission *Permission) *casbin.Enforcer {
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
adapter, err := xormadapter.NewAdapterWithTableName(conf.GetConfigString("driverName"), conf.GetBeegoConfDataSourceName()+conf.GetConfigString("dbName"), "permission_rule", tableNamePrefix, true)
if err != nil {
panic(err)
}
modelText := `
[request_definition]
r = sub, obj, act
[policy_definition]
p = permission, sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act`
permissionModel := getModel(permission.Owner, permission.Model)
if permissionModel != nil {
modelText = permissionModel.ModelText
}
m, err := model.NewModelFromString(modelText)
if err != nil {
panic(err)
}
enforcer, err := casbin.NewEnforcer(m, adapter)
if err != nil {
panic(err)
}
err = enforcer.LoadFilteredPolicy(xormadapter.Filter{V0: []string{permission.GetId()}})
if err != nil {
panic(err)
}
return enforcer
}
func getPolicies(permission *Permission) [][]string {
var policies [][]string
for _, user := range permission.Users {
for _, resource := range permission.Resources {
for _, action := range permission.Actions {
policies = append(policies, []string{permission.GetId(), user, resource, strings.ToLower(action)})
}
}
}
for _, role := range permission.Roles {
for _, resource := range permission.Resources {
for _, action := range permission.Actions {
policies = append(policies, []string{permission.GetId(), role, resource, strings.ToLower(action)})
}
}
}
return policies
}
func addPolicies(permission *Permission) {
enforcer := getEnforcer(permission)
policies := getPolicies(permission)
_, err := enforcer.AddPolicies(policies)
if err != nil {
panic(err)
}
}
func removePolicies(permission *Permission) {
enforcer := getEnforcer(permission)
_, err := enforcer.RemoveFilteredPolicy(0, permission.GetId())
if err != nil {
panic(err)
}
}
func Enforce(userId string, permissionRule *PermissionRule) bool {
permission := GetPermission(permissionRule.V0)
enforcer := getEnforcer(permission)
allow, err := enforcer.Enforce(userId, permissionRule.V2, permissionRule.V3)
if err != nil {
panic(err)
}
return allow
}
func BatchEnforce(userId string, permissionRules []PermissionRule) []bool {
var requests [][]interface{}
for _, permissionRule := range permissionRules {
requests = append(requests, []interface{}{userId, permissionRule.V2, permissionRule.V3})
}
permission := GetPermission(permissionRules[0].V0)
enforcer := getEnforcer(permission)
allow, err := enforcer.BatchEnforce(requests)
if err != nil {
panic(err)
}
return allow
}
func getAllValues(userId string, sec string, fieldIndex int) []string {
permissions := GetPermissionsByUser(userId)
var values []string
for _, permission := range permissions {
enforcer := getEnforcer(permission)
enforcer.ClearPolicy()
err := enforcer.LoadFilteredPolicy(xormadapter.Filter{V0: []string{permission.GetId()}, V1: []string{userId}})
if err != nil {
return nil
}
for _, value := range enforcer.GetModel().GetValuesForFieldInPolicyAllTypes(sec, fieldIndex) {
values = append(values, value)
}
}
return values
}
func GetAllObjects(userId string) []string {
return getAllValues(userId, "p", 2)
}
func GetAllActions(userId string) []string {
return getAllValues(userId, "p", 3)
}
func GetAllRoles(userId string) []string {
roles := GetRolesByUser(userId)
var res []string
for _, role := range roles {
res = append(res, role.Name)
}
return res
}

View File

@@ -38,6 +38,8 @@ type Product struct {
ReturnUrl string `xorm:"varchar(1000)" json:"returnUrl"`
State string `xorm:"varchar(100)" json:"state"`
ProviderObjs []*Provider `xorm:"-" json:"providerObjs"`
}
func GetProductCount(owner, field, value string) int {
@@ -209,3 +211,14 @@ func BuyProduct(id string, providerName string, user *User, host string) (string
return payUrl, err
}
func ExtendProductWithProviders(product *Product) {
product.ProviderObjs = []*Provider{}
m := getProviderMap(product.Owner)
for _, providerItem := range product.Providers {
if provider, ok := m[providerItem]; ok {
product.ProviderObjs = append(product.ProviderObjs, provider)
}
}
}

View File

@@ -29,7 +29,7 @@ func init() {
var err error
logPostOnly, err = conf.GetConfigBool("logPostOnly")
if err != nil {
//panic(err)
// panic(err)
}
}

View File

@@ -110,7 +110,7 @@ func UpdateResource(id string, resource *Resource) bool {
panic(err)
}
//return affected != 0
// return affected != 0
return true
}

View File

@@ -35,7 +35,7 @@ import (
uuid "github.com/satori/go.uuid"
)
//returns a saml2 response
// returns a saml2 response
func NewSamlResponse(user *User, host string, certificate string, destination string, iss string, requestId string, redirectUri []string) (*etree.Element, error) {
samlResponse := &etree.Element{
Space: "samlp",
@@ -100,7 +100,6 @@ func NewSamlResponse(user *User, host string, certificate string, destination st
displayName.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.DisplayName)
return samlResponse, nil
}
type X509Key struct {
@@ -114,7 +113,7 @@ func (x X509Key) GetKeyPair() (privateKey *rsa.PrivateKey, cert []byte, err erro
return privateKey, cert, err
}
//SAML METADATA
// SAML METADATA
type IdpEntityDescriptor struct {
XMLName xml.Name `xml:"EntityDescriptor"`
DS string `xml:"xmlns:ds,attr"`
@@ -299,7 +298,7 @@ func NewSamlResponse11(user *User, requestID string, host string) *etree.Element
Space: "samlp",
Tag: "Response",
}
//create samlresponse
// create samlresponse
samlResponse.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:1.0:protocol")
samlResponse.CreateAttr("MajorVersion", "1")
samlResponse.CreateAttr("MinorVersion", "1")
@@ -315,7 +314,7 @@ func NewSamlResponse11(user *User, requestID string, host string) *etree.Element
samlResponse.CreateElement("samlp:Status").CreateElement("samlp:StatusCode").CreateAttr("Value", "samlp:Success")
//create assertion which is inside the response
// create assertion which is inside the response
assertion := samlResponse.CreateElement("saml:Assertion")
assertion.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:1.0:assertion")
assertion.CreateAttr("MajorVersion", "1")
@@ -328,19 +327,19 @@ func NewSamlResponse11(user *User, requestID string, host string) *etree.Element
condition.CreateAttr("NotBefore", now)
condition.CreateAttr("NotOnOrAfter", expireTime)
//AuthenticationStatement inside assertion
// AuthenticationStatement inside assertion
authenticationStatement := assertion.CreateElement("saml:AuthenticationStatement")
authenticationStatement.CreateAttr("AuthenticationMethod", "urn:oasis:names:tc:SAML:1.0:am:password")
authenticationStatement.CreateAttr("AuthenticationInstant", now)
//subject inside AuthenticationStatement
// subject inside AuthenticationStatement
subject := assertion.CreateElement("saml:Subject")
//nameIdentifier inside subject
// nameIdentifier inside subject
nameIdentifier := subject.CreateElement("saml:NameIdentifier")
//nameIdentifier.CreateAttr("Format", "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")
// nameIdentifier.CreateAttr("Format", "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")
nameIdentifier.SetText(user.Name)
//subjectConfirmation inside subject
// subjectConfirmation inside subject
subjectConfirmation := subject.CreateElement("saml:SubjectConfirmation")
subjectConfirmation.CreateElement("saml:ConfirmationMethod").SetText("urn:oasis:names:tc:SAML:1.0:cm:artifact")

View File

@@ -31,7 +31,7 @@ func init() {
var err error
isCloudIntranet, err = conf.GetConfigBool("isCloudIntranet")
if err != nil {
//panic(err)
// panic(err)
}
}

View File

@@ -220,7 +220,7 @@ func DeleteTokenByAceessToken(accessToken string) (bool, *Application) {
}
func GetTokenByAccessToken(accessToken string) *Token {
//Check if the accessToken is in the database
// Check if the accessToken is in the database
token := Token{AccessToken: accessToken}
existed, err := adapter.Engine.Get(&token)
if err != nil || !existed {
@@ -330,7 +330,7 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
}
}
//Check if grantType is allowed in the current application
// Check if grantType is allowed in the current application
if !IsGrantTypeValid(grantType, application.GrantTypes) && tag == "" {
return &TokenError{
@@ -688,7 +688,7 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
ErrorDescription: "the application does not allow to sign up new account",
}
}
//Add new user
// Add new user
var name string
if username != "" {
name = username
@@ -703,13 +703,16 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
Avatar: avatar,
SignupApplication: application.Name,
WeChat: openId,
WeChatUnionId: unionId,
Type: "normal-user",
CreatedTime: util.GetCurrentTime(),
IsAdmin: false,
IsGlobalAdmin: false,
IsForbidden: false,
IsDeleted: false,
Properties: map[string]string{
USER_PROPERTIES_WECHAT_OPEN_ID: openId,
USER_PROPERTIES_WECHAT_UNION_ID: unionId,
},
}
AddUser(user)
}
@@ -729,7 +732,7 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
Application: application.Name,
Organization: user.Owner,
User: user.Name,
Code: session.SessionKey, //a trick, because miniprogram does not use the code, so use the code field to save the session_key
Code: session.SessionKey, // a trick, because miniprogram does not use the code, so use the code field to save the session_key
AccessToken: accessToken,
RefreshToken: refreshToken,
ExpiresIn: application.ExpireInHours * 60,

View File

@@ -88,7 +88,7 @@ type CasAnyAttribute struct {
type CasAuthenticationSuccessWrapper struct {
AuthenticationSuccess *CasAuthenticationSuccess // the token we issued
Service string //to which service this token is issued
Service string // to which service this token is issued
UserId string
}
@@ -116,10 +116,10 @@ type Saml11AssertionArtifact struct {
InnerXML string `xml:",innerxml"`
}
//st is short for service ticket
// st is short for service ticket
var stToServiceResponse sync.Map
//pgt is short for proxy granting ticket
// pgt is short for proxy granting ticket
var pgtToServiceResponse sync.Map
func StoreCasTokenForPgt(token *CasAuthenticationSuccess, service, userId string) string {
@@ -262,12 +262,11 @@ func GetValidationBySaml(samlRequest string, host string) (string, string, error
return "", "", fmt.Errorf("err: %s", err.Error())
}
return xmlStr, service, nil
}
func (c *CasAuthenticationSuccess) DeepCopy() CasAuthenticationSuccess {
res := *c
//copy proxy
// copy proxy
if c.Proxies != nil {
tmp := c.Proxies.DeepCopy()
res.Proxies = &tmp
@@ -307,7 +306,6 @@ func (c *CasAttributes) DeepCopy() CasAttributes {
res.ExtraAttributes[i] = &tmp
}
return res
}
func (c *CasUserAttributes) DeepCopy() CasUserAttributes {
@@ -316,11 +314,11 @@ func (c *CasUserAttributes) DeepCopy() CasUserAttributes {
Attributes: make([]*CasNamedAttribute, len(c.Attributes)),
}
for i, a := range c.AnyAttributes {
var tmp = *a
tmp := *a
res.AnyAttributes[i] = &tmp
}
for i, a := range c.Attributes {
var tmp = *a
tmp := *a
res.Attributes[i] = &tmp
}
return res

View File

@@ -24,6 +24,11 @@ import (
"xorm.io/core"
)
const (
USER_PROPERTIES_WECHAT_UNION_ID = "wechatUnionId"
USER_PROPERTIES_WECHAT_OPEN_ID = "wechatOpenId"
)
type User struct {
Owner string `xorm:"varchar(100) notnull pk" json:"owner"`
Name string `xorm:"varchar(100) notnull pk" json:"name"`
@@ -73,32 +78,31 @@ 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"`
WeChatUnionId string `xorm:"varchar(100)" json:"unionId"`
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"`
Custom string `xorm:"custom varchar(100)" json:"custom"`
WebauthnCredentials []webauthn.Credential `xorm:"webauthnCredentials blob" json:"webauthnCredentials"`
@@ -243,7 +247,7 @@ func getUserByWechatId(wechatOpenId string, wechatUnionId string) *User {
wechatUnionId = wechatOpenId
}
user := &User{}
existed, err := adapter.Engine.Where("wechat = ? OR wechat = ? OR unionid = ?", wechatOpenId, wechatUnionId, wechatUnionId).Get(user)
existed, err := adapter.Engine.Where("wechat = ? OR wechat = ?", wechatOpenId, wechatUnionId).Get(user)
if err != nil {
panic(err)
}
@@ -417,6 +421,10 @@ func AddUser(user *User) bool {
}
organization := GetOrganizationByUser(user)
if organization == nil {
return false
}
user.UpdateUserPassword(organization)
user.UpdateUserHash()

View File

@@ -46,7 +46,7 @@ func NewAlipayPaymentProvider(appId string, appCertificate string, appPrivateKey
}
func (pp *AlipayPaymentProvider) Pay(providerName string, productName string, payerName string, paymentName string, productDisplayName string, price float64, returnUrl string, notifyUrl string) (string, error) {
//pp.Client.DebugSwitch = gopay.DebugOn
// pp.Client.DebugSwitch = gopay.DebugOn
bm := gopay.BodyMap{}

View File

@@ -25,8 +25,10 @@ import (
"golang.org/x/net/proxy"
)
var DefaultHttpClient *http.Client
var ProxyHttpClient *http.Client
var (
DefaultHttpClient *http.Client
ProxyHttpClient *http.Client
)
func InitHttpClient() {
// not use proxy

View File

@@ -78,7 +78,7 @@ func getObject(ctx *context.Context) (string, string) {
var obj Object
err := json.Unmarshal(body, &obj)
if err != nil {
//panic(err)
// panic(err)
return "", ""
}

View File

@@ -71,5 +71,4 @@ func AutoSigninFilter(ctx *context.Context) {
setSessionUser(ctx, userId)
return
}
}

View File

@@ -30,19 +30,18 @@ func init() {
}
func initAPI() {
ns :=
beego.NewNamespace("/",
beego.NSNamespace("/api",
beego.NSInclude(
&controllers.ApiController{},
),
ns := beego.NewNamespace("/",
beego.NSNamespace("/api",
beego.NSInclude(
&controllers.ApiController{},
),
beego.NSNamespace("",
beego.NSInclude(
&controllers.RootController{},
),
),
beego.NSNamespace("",
beego.NSInclude(
&controllers.RootController{},
),
)
),
)
beego.AddNamespace(ns)
beego.Router("/api/signup", &controllers.ApiController{}, "POST:Signup")
@@ -84,6 +83,12 @@ func initAPI() {
beego.Router("/api/add-permission", &controllers.ApiController{}, "POST:AddPermission")
beego.Router("/api/delete-permission", &controllers.ApiController{}, "POST:DeletePermission")
beego.Router("/api/enforce", &controllers.ApiController{}, "POST:Enforce")
beego.Router("/api/batch-enforce", &controllers.ApiController{}, "POST:BatchEnforce")
beego.Router("/api/get-all-objects", &controllers.ApiController{}, "GET:GetAllObjects")
beego.Router("/api/get-all-actions", &controllers.ApiController{}, "GET:GetAllActions")
beego.Router("/api/get-all-roles", &controllers.ApiController{}, "GET:GetAllRoles")
beego.Router("/api/get-models", &controllers.ApiController{}, "GET:GetModels")
beego.Router("/api/get-model", &controllers.ApiController{}, "GET:GetModel")
beego.Router("/api/update-model", &controllers.ApiController{}, "POST:UpdateModel")
@@ -116,6 +121,7 @@ func initAPI() {
beego.Router("/api/get-applications", &controllers.ApiController{}, "GET:GetApplications")
beego.Router("/api/get-application", &controllers.ApiController{}, "GET:GetApplication")
beego.Router("/api/get-user-application", &controllers.ApiController{}, "GET:GetUserApplication")
beego.Router("/api/get-organization-applications", &controllers.ApiController{}, "GET:GetOrganizationApplications")
beego.Router("/api/update-application", &controllers.ApiController{}, "POST:UpdateApplication")
beego.Router("/api/add-application", &controllers.ApiController{}, "POST:AddApplication")
beego.Router("/api/delete-application", &controllers.ApiController{}, "POST:DeleteApplication")
@@ -195,5 +201,4 @@ func initAPI() {
beego.Router("/api/webauthn/signup/finish", &controllers.ApiController{}, "Post:WebAuthnSignupFinish")
beego.Router("/api/webauthn/signin/begin", &controllers.ApiController{}, "Get:WebAuthnSigninBegin")
beego.Router("/api/webauthn/signin/finish", &controllers.ApiController{}, "Post:WebAuthnSigninFinish")
}

View File

@@ -1291,6 +1291,35 @@
}
}
},
"/api/get-organization-applications": {
"get": {
"tags": [
"Application API"
],
"description": "get the detail of the organization's application",
"operationId": "ApiController.GetOrganizationApplications",
"parameters": [
{
"in": "query",
"name": "organization",
"description": "The organization name",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "The Response object",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/object.Application"
}
}
}
}
}
},
"/api/get-organizations": {
"get": {
"tags": [
@@ -1853,6 +1882,24 @@
"description": "The id of the user",
"required": true,
"type": "string"
},
{
"in": "query",
"name": "owner",
"description": "The owner of the user",
"type": "string"
},
{
"in": "query",
"name": "email",
"description": "The email of the user",
"type": "string"
},
{
"in": "query",
"name": "phone",
"description": "The phone of the user",
"type": "string"
}
],
"responses": {
@@ -3220,11 +3267,11 @@
}
},
"definitions": {
"2127.0xc000427560.false": {
"2200.0xc0003f8480.false": {
"title": "false",
"type": "object"
},
"2161.0xc000427590.false": {
"2235.0xc0003f84b0.false": {
"title": "false",
"type": "object"
},
@@ -3342,10 +3389,10 @@
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/2127.0xc000427560.false"
"$ref": "#/definitions/2200.0xc0003f8480.false"
},
"data2": {
"$ref": "#/definitions/2161.0xc000427590.false"
"$ref": "#/definitions/2235.0xc0003f84b0.false"
},
"msg": {
"type": "string"
@@ -3549,6 +3596,9 @@
"type": "integer",
"format": "int64"
},
"certificate": {
"type": "string"
},
"createdTime": {
"type": "string"
},
@@ -3571,9 +3621,6 @@
"privateKey": {
"type": "string"
},
"certificate": {
"type": "string"
},
"scope": {
"type": "string"
},
@@ -4585,6 +4632,12 @@
"permanentAvatar": {
"type": "string"
},
"permissions": {
"type": "array",
"items": {
"$ref": "#/definitions/object.Permission"
}
},
"phone": {
"type": "string"
},
@@ -4606,6 +4659,12 @@
"region": {
"type": "string"
},
"roles": {
"type": "array",
"items": {
"$ref": "#/definitions/object.Role"
}
},
"score": {
"type": "integer",
"format": "int64"

View File

@@ -837,6 +837,25 @@ paths:
description: The Response object
schema:
$ref: '#/definitions/object.Organization'
/api/get-organization-applications:
get:
tags:
- Application API
description: get the detail of the organization's application
operationId: ApiController.GetOrganizationApplications
parameters:
- in: query
name: organization
description: The organization name
required: true
type: string
responses:
"200":
description: The Response object
schema:
type: array
items:
$ref: '#/definitions/object.Application'
/api/get-organizations:
get:
tags:
@@ -1209,6 +1228,18 @@ paths:
description: The id of the user
required: true
type: string
- in: query
name: owner
description: The owner of the user
type: string
- in: query
name: email
description: The email of the user
type: string
- in: query
name: phone
description: The phone of the user
type: string
responses:
"200":
description: The Response object
@@ -2108,10 +2139,10 @@ paths:
schema:
$ref: '#/definitions/Response'
definitions:
2127.0xc000427560.false:
2200.0xc0003f8480.false:
title: "false"
type: object
2161.0xc000427590.false:
2235.0xc0003f84b0.false:
title: "false"
type: object
Response:
@@ -2192,9 +2223,9 @@ definitions:
type: object
properties:
data:
$ref: '#/definitions/2127.0xc000427560.false'
$ref: '#/definitions/2200.0xc0003f8480.false'
data2:
$ref: '#/definitions/2161.0xc000427590.false'
$ref: '#/definitions/2235.0xc0003f84b0.false'
msg:
type: string
name:
@@ -2331,6 +2362,8 @@ definitions:
bitSize:
type: integer
format: int64
certificate:
type: string
createdTime:
type: string
cryptoAlgorithm:
@@ -2346,8 +2379,6 @@ definitions:
type: string
privateKey:
type: string
certificate:
type: string
scope:
type: string
type:
@@ -3027,6 +3058,10 @@ definitions:
type: string
permanentAvatar:
type: string
permissions:
type: array
items:
$ref: '#/definitions/object.Permission'
phone:
type: string
preHash:
@@ -3041,6 +3076,10 @@ definitions:
format: int64
region:
type: string
roles:
type: array
items:
$ref: '#/definitions/object.Role'
score:
type: integer
format: int64

View File

@@ -17,7 +17,9 @@ package util
import (
"crypto/hmac"
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
)
func GetHmacSha1(keyStr, value string) string {
@@ -28,3 +30,10 @@ func GetHmacSha1(keyStr, value string) string {
return res
}
func GetHmacSha256(key string, data string) string {
mac := hmac.New(sha256.New, []byte(key))
mac.Write([]byte(data))
return hex.EncodeToString(mac.Sum(nil))
}

View File

@@ -32,7 +32,7 @@ func GetIPInfo(clientIP string) string {
res := ""
for i := range ips {
ip := strings.TrimSpace(ips[i])
//desc := GetDescFromIP(ip)
// desc := GetDescFromIP(ip)
ipstr := fmt.Sprintf("%s: %s", ip, "")
if i != len(ips)-1 {
res += ipstr + " -> "

View File

@@ -19,8 +19,10 @@ import (
"regexp"
)
var rePhoneCn *regexp.Regexp
var rePhone *regexp.Regexp
var (
rePhoneCn *regexp.Regexp
rePhone *regexp.Regexp
)
func init() {
// https://learnku.com/articles/31543

View File

@@ -69,7 +69,7 @@ func BoolToString(b bool) string {
return "0"
}
//CamelToSnakeCase This function transform camelcase in snakecase LoremIpsum in lorem_ipsum
// CamelToSnakeCase This function transform camelcase in snakecase LoremIpsum in lorem_ipsum
func CamelToSnakeCase(camel string) string {
var buf bytes.Buffer
for _, c := range camel {
@@ -177,7 +177,7 @@ func ReadStringFromPath(path string) string {
}
func WriteStringToPath(s string, path string) {
err := ioutil.WriteFile(path, []byte(s), 0644)
err := ioutil.WriteFile(path, []byte(s), 0o644)
if err != nil {
panic(err)
}

View File

@@ -15,9 +15,10 @@
package util
import (
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"testing"
)
func TestParseInt(t *testing.T) {
@@ -245,4 +246,3 @@ func TestSnakeString(t *testing.T) {
})
}
}

View File

@@ -31,7 +31,6 @@ func Test_GetCurrentTime(t *testing.T) {
types := reflect.TypeOf(test).Kind()
assert.Equal(t, types, reflect.String, "GetCurrentUnixTime should be return string")
}
func Test_GetCurrentUnixTime_Shoud_Return_String(t *testing.T) {
@@ -41,7 +40,6 @@ func Test_GetCurrentUnixTime_Shoud_Return_String(t *testing.T) {
}
func Test_IsTokenExpired(t *testing.T) {
type input struct {
createdTime string
expiresIn int

View File

@@ -17,11 +17,12 @@
"version": "detect"
}
},
"plugins": ["unused-imports"],
"extends": ["eslint:recommended", "plugin:react/recommended"],
"rules": {
// "eqeqeq": "error",
"semi": ["error", "always"],
// "indent": ["error", 2],
"indent": ["error", 2],
// follow antd's style guide
"quotes": ["error", "double"],
"jsx-quotes": ["error", "prefer-double"],
@@ -41,23 +42,60 @@
"space-before-function-paren": ["error", "never"],
"no-trailing-spaces": ["error", { "ignoreComments": true }],
"eol-last": ["error", "always"],
// "no-var": ["error"],
"no-var": ["error"],
"prefer-const": [
"error",
{
"destructuring": "all"
}
],
"curly": ["error", "all"],
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"no-mixed-spaces-and-tabs": "error",
"sort-imports": ["error", {
"ignoreDeclarationSort": true
}],
"sort-imports": [
"error",
{
"ignoreDeclarationSort": true
}
],
"no-multiple-empty-lines": [
"error",
{ "max": 1, "maxBOF": 0, "maxEOF": 0 }
],
"space-unary-ops": ["error", { "words": true, "nonwords": false }],
"space-infix-ops": "error",
"key-spacing": ["error", { "beforeColon": false, "afterColon": true }],
"comma-style": ["error", "last"],
"comma-dangle": [
"error",
{
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "never",
"exports": "never",
"functions": "never"
}
],
"no-multi-spaces": ["error", { "ignoreEOLComments": true }],
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"error",
{
"vars": "all",
"varsIgnorePattern": "^_",
"args": "none",
"argsIgnorePattern": "^_"
}
],
"react/prop-types": "off",
"react/display-name": "off",
"react/react-in-jsx-scope": "off",
// don't use strict mod now, otherwise there are a lot of errors in the codebase
"no-unused-vars": "warn",
"no-unused-vars": "off",
"react/no-deprecated": "warn",
"no-case-declarations": "warn",
"no-case-declarations": "off",
"react/jsx-key": "warn"
}
}

View File

@@ -34,7 +34,7 @@ module.exports = {
"/cas/validate": {
target: "http://localhost:8000",
changeOrigin: true,
}
},
},
},
plugins: [

View File

@@ -12,13 +12,16 @@
"antd": "^4.15.5",
"codemirror": "^5.61.1",
"copy-to-clipboard": "^3.3.1",
"core-js": "^3.21.1",
"craco-less": "^1.17.1",
"eslint-plugin-unused-imports": "^2.0.0",
"file-saver": "^2.0.5",
"i18n-iso-countries": "^7.0.0",
"i18next": "^19.8.9",
"moment": "^2.29.1",
"qs": "^6.10.2",
"react": "^17.0.2",
"react-app-polyfill": "^3.0.0",
"react-codemirror2": "^7.2.1",
"react-cropper": "^2.1.7",
"react-device-detect": "^1.14.0",
@@ -29,9 +32,7 @@
"react-i18next": "^11.8.7",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"react-social-login-buttons": "^3.4.0",
"react-app-polyfill": "^3.0.0",
"core-js": "^3.21.1"
"react-social-login-buttons": "^3.4.0"
},
"scripts": {
"start": "cross-env PORT=7001 craco start",
@@ -39,7 +40,8 @@
"test": "craco test",
"eject": "craco eject",
"crowdin:sync": "crowdin upload && crowdin download",
"preinstall": "node -e \"if (process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('Use yarn for installing: https://yarnpkg.com/en/docs/install')\""
"preinstall": "node -e \"if (process.env.npm_execpath.indexOf('yarn') === -1) throw new Error('Use yarn for installing: https://yarnpkg.com/en/docs/install')\"",
"fix": "eslint --fix ."
},
"eslintConfig": {
"extends": "react-app"
@@ -61,6 +63,18 @@
"devDependencies": {
"cross-env": "^7.0.3",
"eslint": "^7.11.0",
"eslint-plugin-react": "^7.30.1"
"eslint-plugin-react": "^7.30.1",
"husky": "^4.3.8",
"lint-staged": "^13.0.3"
},
"lint-staged": {
"src/**/*.{js,jsx,css,sass,ts,tsx}": [
"yarn fix"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
}

View File

@@ -38,7 +38,7 @@ class AccountTable extends React.Component {
}
addRow(table) {
let row = {name: Setting.getNewRowNameForTable(table, "Please select an account item"), visible: true};
const row = {name: Setting.getNewRowNameForTable(table, "Please select an account item"), visible: true, viewRule: "Public", modifyRule: "Self"};
if (table === undefined) {
table = [];
}
@@ -116,7 +116,7 @@ class AccountTable extends React.Component {
}
</Select>
);
}
},
},
{
title: i18next.t("provider:visible"),
@@ -129,7 +129,7 @@ class AccountTable extends React.Component {
this.updateField(table, index, "visible", checked);
}} />
);
}
},
},
{
title: i18next.t("organization:viewRule"),
@@ -141,7 +141,7 @@ class AccountTable extends React.Component {
return null;
}
let options = [
const options = [
{id: "Public", name: "Public"},
{id: "Self", name: "Self"},
{id: "Admin", name: "Admin"},
@@ -156,7 +156,7 @@ class AccountTable extends React.Component {
}
</Select>
);
}
},
},
{
title: i18next.t("organization:modifyRule"),
@@ -191,7 +191,7 @@ class AccountTable extends React.Component {
}
</Select>
);
}
},
},
{
title: i18next.t("general:Action"),
@@ -211,7 +211,7 @@ class AccountTable extends React.Component {
</Tooltip>
</div>
);
}
},
},
];

View File

@@ -182,7 +182,7 @@ class App extends Component {
}
setLanguage(account) {
let language = account?.language;
const language = account?.language;
if (language !== "" && language !== i18next.language) {
Setting.setLanguage(language);
}
@@ -238,11 +238,11 @@ class App extends Component {
const owner = this.state.account.owner;
this.setState({
account: null
account: null,
});
Setting.showMessage("success", "Logged out successfully");
let redirectUri = res.data2;
const redirectUri = res.data2;
if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") {
Setting.goToLink(redirectUri);
} else if (owner !== "built-in") {
@@ -258,7 +258,7 @@ class App extends Component {
onUpdateAccount(account) {
this.setState({
account: account
account: account,
});
}
@@ -322,7 +322,7 @@ class App extends Component {
}
renderAccount() {
let res = [];
const res = [];
if (this.state.account === undefined) {
return null;
@@ -349,7 +349,7 @@ class App extends Component {
}
renderMenu() {
let res = [];
const res = [];
if (this.state.account === null || this.state.account === undefined) {
return [];
@@ -566,7 +566,7 @@ class App extends Component {
renderContent() {
if (!Setting.isMobile()) {
return (
<div style={{display: "flex", flex: "auto", width:"100%", flexDirection: "column"}}>
<div style={{display: "flex", flex: "auto", width: "100%", flexDirection: "column"}}>
<Layout style={{display: "flex", alignItems: "stretch"}}>
<Header style={{padding: "0", marginBottom: "3px"}}>
{
@@ -668,7 +668,7 @@ class App extends Component {
renderPage() {
if (this.isDoorPages()) {
return (
<div>
<div style={{position: "relative", minHeight: "100vh"}}>
<Switch>
<Route exact path="/signup" render={(props) => this.renderHomeIfLoggedIn(<SignupPage account={this.state.account} {...props} />)} />
<Route exact path="/signup/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<SignupPage account={this.state.account} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />)} />

View File

@@ -120,7 +120,7 @@ class ApplicationEditPage extends React.Component {
updateApplicationField(key, value) {
value = this.parseApplicationField(key, value);
let application = this.state.application;
const application = this.state.application;
application[key] = value;
this.setState({
application: application,
@@ -156,7 +156,7 @@ class ApplicationEditPage extends React.Component {
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitApplicationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteApplication()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
} style={(Setting.isMobile())? {margin: "5px"}:{}} type="inner">
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Row style={{marginTop: "10px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
@@ -181,7 +181,7 @@ class ApplicationEditPage extends React.Component {
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Logo"), i18next.t("general:Logo - Tooltip"))} :
</Col>
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} :{}}>
<Col span={22} style={(Setting.isMobile()) ? {maxWidth: "100%"} : {}}>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 1}>
{Setting.getLabel(i18next.t("general:URL"), i18next.t("general:URL - Tooltip"))} :
@@ -566,8 +566,8 @@ class ApplicationEditPage extends React.Component {
renderSignupSigninPreview() {
let signUpUrl = `/signup/${this.state.application.name}`;
let signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${this.state.application.redirectUris[0]}&scope=read&state=casdoor`;
let maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "100%", width: "100%", background: "rgba(0,0,0,0.4)"};
const signInUrl = `/login/oauth/authorize?client_id=${this.state.application.clientId}&response_type=code&redirect_uri=${this.state.application.redirectUris[0]}&scope=read&state=casdoor`;
const maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "100%", width: "100%", background: "rgba(0,0,0,0.4)"};
if (!this.state.application.enablePassword) {
signUpUrl = signInUrl.replace("/login/oauth/authorize", "/signup/oauth/authorize");
}
@@ -583,7 +583,7 @@ class ApplicationEditPage extends React.Component {
{i18next.t("application:Copy signup page URL")}
</Button>
<br />
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems:"center", overflow:"auto", flexDirection:"column", flex: "auto"}}>
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
{
this.state.application.enablePassword ? (
<SignupPage application={this.state.application} />
@@ -603,7 +603,7 @@ class ApplicationEditPage extends React.Component {
{i18next.t("application:Copy signin page URL")}
</Button>
<br />
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems:"center", overflow:"auto", flexDirection:"column", flex: "auto"}}>
<div style={{position: "relative", width: "90%", border: "1px solid rgb(217,217,217)", boxShadow: "10px 10px 5px #888888", alignItems: "center", overflow: "auto", flexDirection: "column", flex: "auto"}}>
<LoginPage type={"login"} mode={"signin"} application={this.state.application} />
<div style={maskStyle}></div>
</div>
@@ -613,8 +613,8 @@ class ApplicationEditPage extends React.Component {
}
renderPromptPreview() {
let promptUrl = `/prompt/${this.state.application.name}`;
let maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "100%", width: "100%", background: "rgba(0,0,0,0.4)"};
const promptUrl = `/prompt/${this.state.application.name}`;
const maskStyle = {position: "absolute", top: "0px", left: "0px", zIndex: 10, height: "100%", width: "100%", background: "rgba(0,0,0,0.4)"};
return (
<Col span={11}>
<Button style={{marginBottom: "10px"}} type="primary" shape="round" icon={<CopyOutlined />} onClick={() => {
@@ -634,7 +634,7 @@ class ApplicationEditPage extends React.Component {
}
submitApplicationEdit(willExist) {
let application = Setting.deepCopy(this.state.application);
const application = Setting.deepCopy(this.state.application);
ApplicationBackend.updateApplication(this.state.application.owner, this.state.applicationName, application)
.then((res) => {
if (res.msg === "") {

View File

@@ -99,7 +99,7 @@ class ApplicationListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Created time"),
@@ -109,7 +109,7 @@ class ApplicationListPage extends BaseListPage {
sorter: true,
render: (text, record, index) => {
return Setting.getFormattedDate(text);
}
},
},
{
title: i18next.t("general:Display name"),
@@ -130,7 +130,7 @@ class ApplicationListPage extends BaseListPage {
<img src={text} alt={text} width={150} />
</a>
);
}
},
},
{
title: i18next.t("general:Organization"),
@@ -145,7 +145,7 @@ class ApplicationListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Providers"),
@@ -222,7 +222,7 @@ class ApplicationListPage extends BaseListPage {
</Popconfirm>
</div>
);
}
},
},
];
@@ -250,8 +250,8 @@ class ApplicationListPage extends BaseListPage {
}
fetch = (params = {}) => {
let field = params.searchedColumn, value = params.searchText;
let sortField = params.sortField, sortOrder = params.sortOrder;
const field = params.searchedColumn, value = params.searchText;
const sortField = params.sortField, sortOrder = params.sortOrder;
this.setState({loading: true});
ApplicationBackend.getApplications("admin", params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
.then((res) => {

View File

@@ -57,7 +57,7 @@ class CertEditPage extends React.Component {
updateCertField(key, value) {
value = this.parseCertField(key, value);
let cert = this.state.cert;
const cert = this.state.cert;
cert[key] = value;
this.setState({
cert: cert,
@@ -73,7 +73,7 @@ class CertEditPage extends React.Component {
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitCertEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteCert()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
} style={(Setting.isMobile())? {margin: "5px"}:{}} type="inner">
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Row style={{marginTop: "10px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
@@ -214,7 +214,7 @@ class CertEditPage extends React.Component {
}
submitCertEdit(willExist) {
let cert = Setting.deepCopy(this.state.cert);
const cert = Setting.deepCopy(this.state.cert);
CertBackend.updateCert(this.state.cert.owner, this.state.certName, cert)
.then((res) => {
if (res.msg === "") {

View File

@@ -82,7 +82,7 @@ class CertListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Created time"),
@@ -92,7 +92,7 @@ class CertListPage extends BaseListPage {
sorter: true,
render: (text, record, index) => {
return Setting.getFormattedDate(text);
}
},
},
{
title: i18next.t("general:Display name"),
@@ -169,7 +169,7 @@ class CertListPage extends BaseListPage {
</Popconfirm>
</div>
);
}
},
},
];
@@ -198,7 +198,7 @@ class CertListPage extends BaseListPage {
fetch = (params = {}) => {
let field = params.searchedColumn, value = params.searchText;
let sortField = params.sortField, sortOrder = params.sortOrder;
const sortField = params.sortField, sortOrder = params.sortOrder;
if (params.category !== undefined && params.category !== null) {
field = "category";
value = params.category;

View File

@@ -103,7 +103,7 @@ export const CropperDiv = (props) => {
onCancel={handleCancel}
width={600}
footer={
[<Button block type="primary" onClick={handleOk}>{i18next.t("user:Set new profile picture")}</Button>]
[<Button block key="submit" type="primary" onClick={handleOk}>{i18next.t("user:Set new profile picture")}</Button>]
}
>
<Col style={{margin: "0px auto 40px auto", width: 1000, height: 300}}>

View File

@@ -42,7 +42,7 @@ class LdapEditPage extends React.Component {
.then((res) => {
if (res.status === "ok") {
this.setState({
ldap: res.data
ldap: res.data,
});
} else {
Setting.showMessage("error", res.msg);
@@ -71,7 +71,7 @@ class LdapEditPage extends React.Component {
return (
<span style={{
color: "#faad14",
marginLeft: "20px"
marginLeft: "20px",
}}>{i18next.t("ldap:The Auto Sync option will sync all users to specify organization")}</span>
);
}

View File

@@ -23,7 +23,7 @@ class LdapListPage extends React.Component {
constructor(props) {
super(props);
this.state = {
ldaps: null
ldaps: null,
};
}
@@ -65,7 +65,7 @@ class LdapListPage extends React.Component {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Organization"),
@@ -79,7 +79,7 @@ class LdapListPage extends React.Component {
{text}
</Link>
);
}
},
},
{
title: i18next.t("ldap:Server"),
@@ -89,7 +89,7 @@ class LdapListPage extends React.Component {
sorter: (a, b) => a.host.localeCompare(b.host),
render: (text, record, index) => {
return `${text}:${record.port}`;
}
},
},
{
title: i18next.t("ldap:Base DN"),
@@ -114,7 +114,7 @@ class LdapListPage extends React.Component {
render: (text, record, index) => {
return text === 0 ? (<span style={{color: "#faad14"}}>Disable</span>) : (
<span style={{color: "#52c41a"}}>{text + " mins"}</span>);
}
},
},
{
title: i18next.t("ldap:Last Sync"),
@@ -124,7 +124,7 @@ class LdapListPage extends React.Component {
sorter: (a, b) => a.lastSync.localeCompare(b.lastSync),
render: (text, record, index) => {
return text;
}
},
},
{
title: i18next.t("general:Action"),
@@ -148,7 +148,7 @@ class LdapListPage extends React.Component {
</Popconfirm>
</div>
);
}
},
},
];

View File

@@ -35,7 +35,7 @@ class LdapSyncPage extends React.Component {
}
syncUsers() {
let selectedUsers = this.state.selectedUsers;
const selectedUsers = this.state.selectedUsers;
if (selectedUsers === null || selectedUsers.length === 0) {
Setting.showMessage("error", "Please select al least 1 user first");
return;
@@ -44,10 +44,10 @@ class LdapSyncPage extends React.Component {
LdapBackend.syncUsers(this.state.ldap.owner, this.state.ldap.id, selectedUsers)
.then((res => {
if (res.status === "ok") {
let exist = res.data.exist;
let failed = res.data.failed;
let existUser = [];
let failedUser = [];
const exist = res.data.exist;
const failed = res.data.failed;
const existUser = [];
const failedUser = [];
if ((!exist || exist.length === 0) && (!failed || failed.length === 0)) {
Setting.goToLink(`/organizations/${this.state.ldap.owner}/users`);
@@ -87,7 +87,6 @@ class LdapSyncPage extends React.Component {
});
}
getLdapUser(ldap) {
LdapBackend.getLdapUser(ldap)
.then((res) => {
@@ -104,7 +103,7 @@ class LdapSyncPage extends React.Component {
}
getExistUsers(owner, users) {
let uuidArray = [];
const uuidArray = [];
users.forEach(elem => {
uuidArray.push(elem.uuid);
});
@@ -120,11 +119,11 @@ class LdapSyncPage extends React.Component {
}
buildValArray(data, key) {
let valTypesArray = [];
const valTypesArray = [];
if (data !== null && data.length > 0) {
data.forEach(elem => {
let val = elem[key];
const val = elem[key];
if (!valTypesArray.includes(val)) {
valTypesArray.push(val);
}
@@ -134,10 +133,10 @@ class LdapSyncPage extends React.Component {
}
buildFilter(data, key) {
let filterArray = [];
const filterArray = [];
if (data !== null && data.length > 0) {
let valArray = this.buildValArray(data, key);
const valArray = this.buildValArray(data, key);
valArray.forEach(elem => {
filterArray.push({
text: elem,

View File

@@ -48,7 +48,7 @@ class LdapTable extends React.Component {
passwd: "123",
baseDn: "ou=People,dc=example,dc=com",
autosync: 0,
lastSync: ""
lastSync: "",
};
}
@@ -104,7 +104,7 @@ class LdapTable extends React.Component {
{text}
</Link>
);
}
},
},
{
title: i18next.t("ldap:Server"),
@@ -114,7 +114,7 @@ class LdapTable extends React.Component {
sorter: (a, b) => a.host.localeCompare(b.host),
render: (text, record, index) => {
return `${text}:${record.port}`;
}
},
},
{
title: i18next.t("ldap:Base DN"),
@@ -132,7 +132,7 @@ class LdapTable extends React.Component {
render: (text, record, index) => {
return text === 0 ? (<span style={{color: "#faad14"}}>Disable</span>) : (
<span style={{color: "#52c41a"}}>{text + " mins"}</span>);
}
},
},
{
title: i18next.t("ldap:Last Sync"),
@@ -142,7 +142,7 @@ class LdapTable extends React.Component {
sorter: (a, b) => a.lastSync.localeCompare(b.lastSync),
render: (text, record, index) => {
return text;
}
},
},
{
title: i18next.t("general:Action"),
@@ -166,7 +166,7 @@ class LdapTable extends React.Component {
</Popconfirm>
</div>
);
}
},
},
];

View File

@@ -81,7 +81,7 @@ class ModelEditPage extends React.Component {
updateModelField(key, value) {
value = this.parseModelField(key, value);
let model = this.state.model;
const model = this.state.model;
model[key] = value;
this.setState({
model: model,
@@ -97,7 +97,7 @@ class ModelEditPage extends React.Component {
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitModelEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteModel()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
} style={(Setting.isMobile())? {margin: "5px"}:{}} type="inner">
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Row style={{marginTop: "10px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
@@ -155,7 +155,7 @@ class ModelEditPage extends React.Component {
}
submitModelEdit(willExist) {
let model = Setting.deepCopy(this.state.model);
const model = Setting.deepCopy(this.state.model);
ModelBackend.updateModel(this.state.organizationName, this.state.modelName, model)
.then((res) => {
if (res.msg === "") {

View File

@@ -76,7 +76,7 @@ class ModelListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Name"),
@@ -92,7 +92,7 @@ class ModelListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Created time"),
@@ -102,7 +102,7 @@ class ModelListPage extends BaseListPage {
sorter: true,
render: (text, record, index) => {
return Setting.getFormattedDate(text);
}
},
},
{
title: i18next.t("general:Display name"),
@@ -122,7 +122,7 @@ class ModelListPage extends BaseListPage {
return (
<Switch disabled checkedChildren="ON" unCheckedChildren="OFF" checked={text} />
);
}
},
},
{
title: i18next.t("general:Action"),
@@ -143,7 +143,7 @@ class ModelListPage extends BaseListPage {
</Popconfirm>
</div>
);
}
},
},
];
@@ -174,7 +174,7 @@ class ModelListPage extends BaseListPage {
fetch = (params = {}) => {
let field = params.searchedColumn, value = params.searchText;
let sortField = params.sortField, sortOrder = params.sortOrder;
const sortField = params.sortField, sortOrder = params.sortOrder;
if (params.type !== undefined && params.type !== null) {
field = "type";
value = params.type;

View File

@@ -60,7 +60,7 @@ class OrganizationEditPage extends React.Component {
}
}
this.setState({
ldaps: resdata
ldaps: resdata,
});
});
}
@@ -75,7 +75,7 @@ class OrganizationEditPage extends React.Component {
updateOrganizationField(key, value) {
value = this.parseOrganizationField(key, value);
let organization = this.state.organization;
const organization = this.state.organization;
organization[key] = value;
this.setState({
organization: organization,
@@ -91,7 +91,7 @@ class OrganizationEditPage extends React.Component {
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitOrganizationEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deleteOrganization()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
} style={(Setting.isMobile())? {margin: "5px"}:{}} type="inner">
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Row style={{marginTop: "10px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Name"), i18next.t("general:Name - Tooltip"))} :
@@ -283,7 +283,7 @@ class OrganizationEditPage extends React.Component {
}
submitOrganizationEdit(willExist) {
let organization = Setting.deepCopy(this.state.organization);
const organization = Setting.deepCopy(this.state.organization);
OrganizationBackend.updateOrganization(this.state.organization.owner, this.state.organizationName, organization)
.then((res) => {
if (res.msg === "") {

View File

@@ -112,7 +112,7 @@ class OrganizationListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Created time"),
@@ -122,7 +122,7 @@ class OrganizationListPage extends BaseListPage {
sorter: true,
render: (text, record, index) => {
return Setting.getFormattedDate(text);
}
},
},
{
title: i18next.t("general:Display name"),
@@ -143,7 +143,7 @@ class OrganizationListPage extends BaseListPage {
<img src={text} alt={text} width={40} />
</a>
);
}
},
},
{
title: i18next.t("organization:Website URL"),
@@ -158,7 +158,7 @@ class OrganizationListPage extends BaseListPage {
{text}
</a>
);
}
},
},
{
title: i18next.t("general:Password type"),
@@ -192,7 +192,7 @@ class OrganizationListPage extends BaseListPage {
<img src={text} alt={text} width={40} />
</a>
);
}
},
},
{
title: i18next.t("organization:Soft deletion"),
@@ -204,7 +204,7 @@ class OrganizationListPage extends BaseListPage {
return (
<Switch disabled checkedChildren="ON" unCheckedChildren="OFF" checked={text} />
);
}
},
},
{
title: i18next.t("general:Action"),
@@ -226,7 +226,7 @@ class OrganizationListPage extends BaseListPage {
</Popconfirm>
</div>
);
}
},
},
];
@@ -266,7 +266,7 @@ class OrganizationListPage extends BaseListPage {
fetch = (params = {}) => {
let field = params.searchedColumn, value = params.searchText;
let sortField = params.sortField, sortOrder = params.sortOrder;
const sortField = params.sortField, sortOrder = params.sortOrder;
if (params.passwordType !== undefined && params.passwordType !== null) {
field = "passwordType";
value = params.passwordType;

View File

@@ -54,7 +54,7 @@ export const PasswordModal = (props) => {
});
};
let hasOldPassword = user.password !== "";
const hasOldPassword = user.password !== "";
return (
<Row>

View File

@@ -60,7 +60,7 @@ class PaymentEditPage extends React.Component {
updatePaymentField(key, value) {
value = this.parsePaymentField(key, value);
let payment = this.state.payment;
const payment = this.state.payment;
payment[key] = value;
this.setState({
payment: payment,
@@ -152,7 +152,7 @@ class PaymentEditPage extends React.Component {
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitPaymentEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deletePayment()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
} style={(Setting.isMobile())? {margin: "5px"}:{}} type="inner">
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Row style={{marginTop: "10px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
@@ -440,7 +440,7 @@ class PaymentEditPage extends React.Component {
return;
}
let payment = Setting.deepCopy(this.state.payment);
const payment = Setting.deepCopy(this.state.payment);
PaymentBackend.updatePayment(this.state.payment.owner, this.state.paymentName, payment)
.then((res) => {
if (res.msg === "") {

View File

@@ -89,7 +89,7 @@ class PaymentListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:User"),
@@ -104,7 +104,7 @@ class PaymentListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Name"),
@@ -120,7 +120,7 @@ class PaymentListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("general:Created time"),
@@ -130,7 +130,7 @@ class PaymentListPage extends BaseListPage {
sorter: true,
render: (text, record, index) => {
return Setting.getFormattedDate(text);
}
},
},
// {
// title: i18next.t("general:Display name"),
@@ -154,7 +154,7 @@ class PaymentListPage extends BaseListPage {
{text}
</Link>
);
}
},
},
{
title: i18next.t("payment:Type"),
@@ -163,12 +163,12 @@ class PaymentListPage extends BaseListPage {
width: "140px",
align: "center",
filterMultiple: false,
filters: Setting.getProviderTypeOptions("Payment").map((o) => {return {text:o.id, value:o.name};}),
filters: Setting.getProviderTypeOptions("Payment").map((o) => {return {text: o.id, value: o.name};}),
sorter: true,
render: (text, record, index) => {
record.category = "Payment";
return Provider.getProviderLogoWidget(record);
}
},
},
{
title: i18next.t("payment:Product"),
@@ -221,7 +221,7 @@ class PaymentListPage extends BaseListPage {
</Popconfirm>
</div>
);
}
},
},
];
@@ -250,7 +250,7 @@ class PaymentListPage extends BaseListPage {
fetch = (params = {}) => {
let field = params.searchedColumn, value = params.searchText;
let sortField = params.sortField, sortOrder = params.sortOrder;
const sortField = params.sortField, sortOrder = params.sortOrder;
if (params.type !== undefined && params.type !== null) {
field = "type";
value = params.type;

View File

@@ -67,7 +67,7 @@ class PaymentResultPage extends React.Component {
Setting.goToLink(payment.returnUrl);
}}>
{i18next.t("payment:Return to Website")}
</Button>
</Button>,
]}
/>
</div>
@@ -83,7 +83,7 @@ class PaymentResultPage extends React.Component {
title={`${i18next.t("payment:The payment is still under processing")}: ${payment.productDisplayName}, ${i18next.t("payment:the current state is")}: ${payment.state}, ${i18next.t("payment:please wait for a few seconds...")}`}
subTitle={i18next.t("payment:Please click the below button to return to the original website")}
extra={[
<Spin size="large" tip={i18next.t("payment:Processing...")} />,
<Spin key="returnUrl" size="large" tip={i18next.t("payment:Processing...")} />,
]}
/>
</div>
@@ -103,7 +103,7 @@ class PaymentResultPage extends React.Component {
Setting.goToLink(payment.returnUrl);
}}>
{i18next.t("payment:Return to Website")}
</Button>
</Button>,
]}
/>
</div>

View File

@@ -116,7 +116,7 @@ class PermissionEditPage extends React.Component {
updatePermissionField(key, value) {
value = this.parsePermissionField(key, value);
let permission = this.state.permission;
const permission = this.state.permission;
permission[key] = value;
this.setState({
permission: permission,
@@ -132,7 +132,7 @@ class PermissionEditPage extends React.Component {
<Button style={{marginLeft: "20px"}} type="primary" onClick={() => this.submitPermissionEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
{this.state.mode === "add" ? <Button style={{marginLeft: "20px"}} onClick={() => this.deletePermission()}>{i18next.t("general:Cancel")}</Button> : null}
</div>
} style={(Setting.isMobile())? {margin: "5px"}:{}} type="inner">
} style={(Setting.isMobile()) ? {margin: "5px"} : {}} type="inner">
<Row style={{marginTop: "10px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("general:Organization"), i18next.t("general:Organization - Tooltip"))} :
@@ -288,7 +288,7 @@ class PermissionEditPage extends React.Component {
}
submitPermissionEdit(willExist) {
let permission = Setting.deepCopy(this.state.permission);
const permission = Setting.deepCopy(this.state.permission);
PermissionBackend.updatePermission(this.state.organizationName, this.state.permissionName, permission)
.then((res) => {
if (res.msg === "") {

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