mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-13 01:17:45 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
53ad454962 | ||
![]() |
fb203a6f30 | ||
![]() |
f716a0985f | ||
![]() |
340fbe135d | ||
![]() |
79119760f2 | ||
![]() |
4dd67a8dcb | ||
![]() |
deed857788 | ||
![]() |
802995ed16 | ||
![]() |
b14554a5ba | ||
![]() |
4665ffa759 | ||
![]() |
f914e8e929 | ||
![]() |
dc33b41107 |
@@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
@@ -80,7 +80,7 @@ func (captcha *AliyunCaptchaProvider) VerifyCaptcha(token, clientSecret string)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -58,7 +58,7 @@ func (captcha *GEETESTCaptchaProvider) VerifyCaptcha(token, clientSecret string)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ package captcha
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -43,7 +43,7 @@ func (captcha *HCaptchaProvider) VerifyCaptcha(token, clientSecret string) (bool
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ package captcha
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -43,7 +43,7 @@ func (captcha *ReCaptchaProvider) VerifyCaptcha(token, clientSecret string) (boo
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@@ -274,6 +274,7 @@ func (c *ApiController) GetAccount() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetUserinfo
|
||||
// UserInfo
|
||||
// @Title UserInfo
|
||||
// @Tag Account API
|
||||
|
@@ -118,7 +118,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
}
|
||||
|
||||
} else {
|
||||
resp = wrapErrorResponse(fmt.Errorf("Unknown response type: %s", form.Type))
|
||||
resp = wrapErrorResponse(fmt.Errorf("unknown response type: %s", form.Type))
|
||||
}
|
||||
|
||||
// if user did not check auto signin
|
||||
|
@@ -23,11 +23,13 @@ import (
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// ApiController
|
||||
// controller for handlers under /api uri
|
||||
type ApiController struct {
|
||||
beego.Controller
|
||||
}
|
||||
|
||||
// RootController
|
||||
// controller for handlers directly under / (root)
|
||||
type RootController struct {
|
||||
ApiController
|
||||
@@ -136,9 +138,9 @@ func (c *ApiController) SetSessionData(s *SessionData) {
|
||||
|
||||
func wrapActionResponse(affected bool) *Response {
|
||||
if affected {
|
||||
return &Response{Status: "ok", Msg: "", Data: "Affected"}
|
||||
return &Response{Status: "ok", Msg: ""}
|
||||
} else {
|
||||
return &Response{Status: "ok", Msg: "", Data: "Unaffected"}
|
||||
return &Response{Status: "error", Msg: "this operation has no effect"}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,7 +31,7 @@ const (
|
||||
InvalidProxyCallback string = "INVALID_PROXY_CALLBACK"
|
||||
InvalidTicket string = "INVALID_TICKET"
|
||||
InvalidService string = "INVALID_SERVICE"
|
||||
InteralError string = "INTERNAL_ERROR"
|
||||
InternalError string = "INTERNAL_ERROR"
|
||||
UnauthorizedService string = "UNAUTHORIZED_SERVICE"
|
||||
)
|
||||
|
||||
@@ -116,7 +116,7 @@ func (c *RootController) CasP3ServiceAndProxyValidate() {
|
||||
}
|
||||
// make a request to pgturl passing pgt and pgtiou
|
||||
if err != nil {
|
||||
c.sendCasAuthenticationResponseErr(InteralError, err.Error(), format)
|
||||
c.sendCasAuthenticationResponseErr(InternalError, err.Error(), format)
|
||||
return
|
||||
}
|
||||
param := pgtUrlObj.Query()
|
||||
@@ -126,7 +126,7 @@ func (c *RootController) CasP3ServiceAndProxyValidate() {
|
||||
|
||||
request, err := http.NewRequest("GET", pgtUrlObj.String(), nil)
|
||||
if err != nil {
|
||||
c.sendCasAuthenticationResponseErr(InteralError, err.Error(), format)
|
||||
c.sendCasAuthenticationResponseErr(InternalError, err.Error(), format)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ func (c *RootController) SamlValidate() {
|
||||
return
|
||||
}
|
||||
|
||||
envelopReponse := struct {
|
||||
envelopResponse := struct {
|
||||
XMLName xml.Name `xml:"SOAP-ENV:Envelope"`
|
||||
Xmlns string `xml:"xmlns:SOAP-ENV"`
|
||||
Body struct {
|
||||
@@ -222,15 +222,15 @@ func (c *RootController) SamlValidate() {
|
||||
Content string `xml:",innerxml"`
|
||||
}
|
||||
}{}
|
||||
envelopReponse.Xmlns = "http://schemas.xmlsoap.org/soap/envelope/"
|
||||
envelopReponse.Body.Content = response
|
||||
envelopResponse.Xmlns = "http://schemas.xmlsoap.org/soap/envelope/"
|
||||
envelopResponse.Body.Content = response
|
||||
|
||||
data, err := xml.Marshal(envelopReponse)
|
||||
data, err := xml.Marshal(envelopResponse)
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
c.Ctx.Output.Body([]byte(data))
|
||||
c.Ctx.Output.Body(data)
|
||||
}
|
||||
|
||||
func (c *RootController) sendCasProxyResponseErr(code, msg, format string) {
|
||||
|
@@ -48,6 +48,7 @@ func (c *ApiController) GetCerts() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetCert
|
||||
// @Title GetCert
|
||||
// @Tag Cert API
|
||||
// @Description get cert
|
||||
@@ -61,6 +62,7 @@ func (c *ApiController) GetCert() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateCert
|
||||
// @Title UpdateCert
|
||||
// @Tag Cert API
|
||||
// @Description update cert
|
||||
@@ -81,6 +83,7 @@ func (c *ApiController) UpdateCert() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddCert
|
||||
// @Title AddCert
|
||||
// @Tag Cert API
|
||||
// @Description add cert
|
||||
@@ -98,6 +101,7 @@ func (c *ApiController) AddCert() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteCert
|
||||
// @Title DeleteCert
|
||||
// @Tag Cert API
|
||||
// @Description delete cert
|
||||
|
88
controllers/enforcer.go
Normal file
88
controllers/enforcer.go
Normal 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()
|
||||
}
|
@@ -44,6 +44,7 @@ type LdapSyncResp struct {
|
||||
Failed []object.LdapRespUser `json:"failed"`
|
||||
}
|
||||
|
||||
// GetLdapUser
|
||||
// @Tag Account API
|
||||
// @Title GetLdapser
|
||||
// @router /get-ldap-user [post]
|
||||
@@ -100,6 +101,7 @@ func (c *ApiController) GetLdapUser() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetLdaps
|
||||
// @Tag Account API
|
||||
// @Title GetLdaps
|
||||
// @router /get-ldaps [post]
|
||||
@@ -110,6 +112,7 @@ func (c *ApiController) GetLdaps() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetLdap
|
||||
// @Tag Account API
|
||||
// @Title GetLdap
|
||||
// @router /get-ldap [post]
|
||||
@@ -125,6 +128,7 @@ func (c *ApiController) GetLdap() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddLdap
|
||||
// @Tag Account API
|
||||
// @Title AddLdap
|
||||
// @router /add-ldap [post]
|
||||
@@ -159,6 +163,7 @@ func (c *ApiController) AddLdap() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateLdap
|
||||
// @Tag Account API
|
||||
// @Title UpdateLdap
|
||||
// @router /update-ldap [post]
|
||||
@@ -186,6 +191,7 @@ func (c *ApiController) UpdateLdap() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteLdap
|
||||
// @Tag Account API
|
||||
// @Title DeleteLdap
|
||||
// @router /delete-ldap [post]
|
||||
@@ -201,6 +207,7 @@ func (c *ApiController) DeleteLdap() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// SyncLdapUsers
|
||||
// @Tag Account API
|
||||
// @Title SyncLdapUsers
|
||||
// @router /sync-ldap-users [post]
|
||||
@@ -223,6 +230,7 @@ func (c *ApiController) SyncLdapUsers() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// CheckLdapUsersExist
|
||||
// @Tag Account API
|
||||
// @Title CheckLdapUserExist
|
||||
// @router /check-ldap-users-exist [post]
|
||||
|
@@ -16,6 +16,7 @@ package controllers
|
||||
|
||||
import "github.com/casdoor/casdoor/object"
|
||||
|
||||
// GetOidcDiscovery
|
||||
// @Title GetOidcDiscovery
|
||||
// @Tag OIDC API
|
||||
// @Description Get Oidc Discovery
|
||||
@@ -27,6 +28,7 @@ func (c *RootController) GetOidcDiscovery() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// GetJwks
|
||||
// @Title GetJwks
|
||||
// @Tag OIDC API
|
||||
// @Success 200 {object} jose.JSONWebKey
|
||||
|
@@ -67,6 +67,7 @@ func (c *ApiController) GetUserPayments() {
|
||||
c.ResponseOk(payments)
|
||||
}
|
||||
|
||||
// GetPayment
|
||||
// @Title GetPayment
|
||||
// @Tag Payment API
|
||||
// @Description get payment
|
||||
@@ -80,6 +81,7 @@ func (c *ApiController) GetPayment() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdatePayment
|
||||
// @Title UpdatePayment
|
||||
// @Tag Payment API
|
||||
// @Description update payment
|
||||
@@ -100,6 +102,7 @@ func (c *ApiController) UpdatePayment() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddPayment
|
||||
// @Title AddPayment
|
||||
// @Tag Payment API
|
||||
// @Description add payment
|
||||
@@ -117,6 +120,7 @@ func (c *ApiController) AddPayment() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeletePayment
|
||||
// @Title DeletePayment
|
||||
// @Tag Payment API
|
||||
// @Description delete payment
|
||||
@@ -134,6 +138,7 @@ func (c *ApiController) DeletePayment() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// NotifyPayment
|
||||
// @Title NotifyPayment
|
||||
// @Tag Payment API
|
||||
// @Description notify payment
|
||||
@@ -159,6 +164,7 @@ func (c *ApiController) NotifyPayment() {
|
||||
}
|
||||
}
|
||||
|
||||
// InvoicePayment
|
||||
// @Title InvoicePayment
|
||||
// @Tag Payment API
|
||||
// @Description invoice payment
|
||||
|
@@ -48,6 +48,7 @@ func (c *ApiController) GetPermissions() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetPermission
|
||||
// @Title GetPermission
|
||||
// @Tag Permission API
|
||||
// @Description get permission
|
||||
@@ -61,6 +62,7 @@ func (c *ApiController) GetPermission() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdatePermission
|
||||
// @Title UpdatePermission
|
||||
// @Tag Permission API
|
||||
// @Description update permission
|
||||
@@ -81,6 +83,7 @@ func (c *ApiController) UpdatePermission() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddPermission
|
||||
// @Title AddPermission
|
||||
// @Tag Permission API
|
||||
// @Description add permission
|
||||
@@ -98,6 +101,7 @@ func (c *ApiController) AddPermission() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeletePermission
|
||||
// @Title DeletePermission
|
||||
// @Tag Permission API
|
||||
// @Description delete permission
|
||||
|
@@ -49,6 +49,7 @@ func (c *ApiController) GetProducts() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetProduct
|
||||
// @Title GetProduct
|
||||
// @Tag Product API
|
||||
// @Description get product
|
||||
@@ -65,6 +66,7 @@ func (c *ApiController) GetProduct() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateProduct
|
||||
// @Title UpdateProduct
|
||||
// @Tag Product API
|
||||
// @Description update product
|
||||
@@ -85,6 +87,7 @@ func (c *ApiController) UpdateProduct() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddProduct
|
||||
// @Title AddProduct
|
||||
// @Tag Product API
|
||||
// @Description add product
|
||||
@@ -102,6 +105,7 @@ func (c *ApiController) AddProduct() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteProduct
|
||||
// @Title DeleteProduct
|
||||
// @Tag Product API
|
||||
// @Description delete product
|
||||
@@ -119,6 +123,7 @@ func (c *ApiController) DeleteProduct() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// BuyProduct
|
||||
// @Title BuyProduct
|
||||
// @Tag Product API
|
||||
// @Description buy product
|
||||
|
@@ -48,6 +48,7 @@ func (c *ApiController) GetProviders() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetProvider
|
||||
// @Title GetProvider
|
||||
// @Tag Provider API
|
||||
// @Description get provider
|
||||
@@ -61,6 +62,7 @@ func (c *ApiController) GetProvider() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateProvider
|
||||
// @Title UpdateProvider
|
||||
// @Tag Provider API
|
||||
// @Description update provider
|
||||
@@ -81,6 +83,7 @@ func (c *ApiController) UpdateProvider() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddProvider
|
||||
// @Title AddProvider
|
||||
// @Tag Provider API
|
||||
// @Description add provider
|
||||
@@ -98,6 +101,7 @@ func (c *ApiController) AddProvider() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteProvider
|
||||
// @Title DeleteProvider
|
||||
// @Tag Provider API
|
||||
// @Description delete provider
|
||||
|
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
// GetResources
|
||||
// @router /get-resources [get]
|
||||
// @Tag Resource API
|
||||
// @Title GetResources
|
||||
@@ -50,6 +51,7 @@ func (c *ApiController) GetResources() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetResource
|
||||
// @Tag Resource API
|
||||
// @Title GetResource
|
||||
// @router /get-resource [get]
|
||||
@@ -60,6 +62,7 @@ func (c *ApiController) GetResource() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateResource
|
||||
// @Tag Resource API
|
||||
// @Title UpdateResource
|
||||
// @router /update-resource [post]
|
||||
@@ -76,6 +79,7 @@ func (c *ApiController) UpdateResource() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddResource
|
||||
// @Tag Resource API
|
||||
// @Title AddResource
|
||||
// @router /add-resource [post]
|
||||
@@ -90,6 +94,7 @@ func (c *ApiController) AddResource() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteResource
|
||||
// @Tag Resource API
|
||||
// @Title DeleteResource
|
||||
// @router /delete-resource [post]
|
||||
@@ -115,6 +120,7 @@ func (c *ApiController) DeleteResource() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UploadResource
|
||||
// @Tag Resource API
|
||||
// @Title UploadResource
|
||||
// @router /upload-resource [post]
|
||||
|
@@ -48,6 +48,7 @@ func (c *ApiController) GetRoles() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetRole
|
||||
// @Title GetRole
|
||||
// @Tag Role API
|
||||
// @Description get role
|
||||
@@ -61,6 +62,7 @@ func (c *ApiController) GetRole() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateRole
|
||||
// @Title UpdateRole
|
||||
// @Tag Role API
|
||||
// @Description update role
|
||||
@@ -81,6 +83,7 @@ func (c *ApiController) UpdateRole() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddRole
|
||||
// @Title AddRole
|
||||
// @Tag Role API
|
||||
// @Description add role
|
||||
@@ -98,6 +101,7 @@ func (c *ApiController) AddRole() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteRole
|
||||
// @Title DeleteRole
|
||||
// @Tag Role API
|
||||
// @Description delete role
|
||||
|
@@ -48,6 +48,7 @@ func (c *ApiController) GetSyncers() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetSyncer
|
||||
// @Title GetSyncer
|
||||
// @Tag Syncer API
|
||||
// @Description get syncer
|
||||
@@ -61,6 +62,7 @@ func (c *ApiController) GetSyncer() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateSyncer
|
||||
// @Title UpdateSyncer
|
||||
// @Tag Syncer API
|
||||
// @Description update syncer
|
||||
@@ -81,6 +83,7 @@ func (c *ApiController) UpdateSyncer() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddSyncer
|
||||
// @Title AddSyncer
|
||||
// @Tag Syncer API
|
||||
// @Description add syncer
|
||||
@@ -98,6 +101,7 @@ func (c *ApiController) AddSyncer() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteSyncer
|
||||
// @Title DeleteSyncer
|
||||
// @Tag Syncer API
|
||||
// @Description delete syncer
|
||||
@@ -115,6 +119,7 @@ func (c *ApiController) DeleteSyncer() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// RunSyncer
|
||||
// @Title RunSyncer
|
||||
// @Tag Syncer API
|
||||
// @Description run syncer
|
||||
|
@@ -255,7 +255,7 @@ func (c *ApiController) RefreshToken() {
|
||||
// @router /login/oauth/logout [get]
|
||||
func (c *ApiController) TokenLogout() {
|
||||
token := c.Input().Get("id_token_hint")
|
||||
flag, application := object.DeleteTokenByAceessToken(token)
|
||||
flag, application := object.DeleteTokenByAccessToken(token)
|
||||
redirectUri := c.Input().Get("post_logout_redirect_uri")
|
||||
state := c.Input().Get("state")
|
||||
if application != nil && object.CheckRedirectUriValid(application, redirectUri) {
|
||||
@@ -288,7 +288,7 @@ func (c *ApiController) IntrospectToken() {
|
||||
if clientId == "" || clientSecret == "" {
|
||||
c.ResponseError("empty clientId or clientSecret")
|
||||
c.Data["json"] = &object.TokenError{
|
||||
Error: object.INVALID_REQUEST,
|
||||
Error: object.InvalidRequest,
|
||||
}
|
||||
c.SetTokenErrorHttpStatus()
|
||||
c.ServeJSON()
|
||||
@@ -299,7 +299,7 @@ func (c *ApiController) IntrospectToken() {
|
||||
if application == nil || application.ClientSecret != clientSecret {
|
||||
c.ResponseError("invalid application or wrong clientSecret")
|
||||
c.Data["json"] = &object.TokenError{
|
||||
Error: object.INVALID_CLIENT,
|
||||
Error: object.InvalidClient,
|
||||
}
|
||||
c.SetTokenErrorHttpStatus()
|
||||
return
|
||||
|
@@ -298,6 +298,7 @@ func (c *ApiController) SetPassword() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// CheckUserPassword
|
||||
// @Title CheckUserPassword
|
||||
// @router /check-user-password [post]
|
||||
// @Tag User API
|
||||
|
@@ -55,7 +55,7 @@ func (c *ApiController) ResponseError(error string, data ...interface{}) {
|
||||
func (c *ApiController) SetTokenErrorHttpStatus() {
|
||||
_, ok := c.Data["json"].(*object.TokenError)
|
||||
if ok {
|
||||
if c.Data["json"].(*object.TokenError).Error == object.INVALID_CLIENT {
|
||||
if c.Data["json"].(*object.TokenError).Error == object.InvalidClient {
|
||||
c.Ctx.Output.SetStatus(401)
|
||||
c.Ctx.Output.Header("WWW-Authenticate", "Basic realm=\"OAuth2\"")
|
||||
} else {
|
||||
|
@@ -98,7 +98,7 @@ func (c *ApiController) SendVerificationCode() {
|
||||
return
|
||||
}
|
||||
|
||||
sendResp := errors.New("Invalid dest type")
|
||||
sendResp := errors.New("invalid dest type")
|
||||
|
||||
if user == nil && checkUser != "" && checkUser != "true" {
|
||||
name := application.Organization
|
||||
|
@@ -16,7 +16,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
)
|
||||
|
||||
// WebAuthnSignupBegin
|
||||
// @Title WebAuthnSignupBegin
|
||||
// @Tag User API
|
||||
// @Description WebAuthn Registration Flow 1st stage
|
||||
@@ -53,6 +54,7 @@ func (c *ApiController) WebAuthnSignupBegin() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// WebAuthnSignupFinish
|
||||
// @Title WebAuthnSignupFinish
|
||||
// @Tag User API
|
||||
// @Description WebAuthn Registration Flow 2nd stage
|
||||
@@ -72,7 +74,7 @@ func (c *ApiController) WebAuthnSignupFinish() {
|
||||
c.ResponseError("Please call WebAuthnSignupBegin first")
|
||||
return
|
||||
}
|
||||
c.Ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||
|
||||
credential, err := webauthnObj.FinishRegistration(user, sessionData, c.Ctx.Request)
|
||||
if err != nil {
|
||||
@@ -84,6 +86,7 @@ func (c *ApiController) WebAuthnSignupFinish() {
|
||||
c.ResponseOk()
|
||||
}
|
||||
|
||||
// WebAuthnSigninBegin
|
||||
// @Title WebAuthnSigninBegin
|
||||
// @Tag Login API
|
||||
// @Description WebAuthn Login Flow 1st stage
|
||||
@@ -110,6 +113,7 @@ func (c *ApiController) WebAuthnSigninBegin() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// WebAuthnSigninFinish
|
||||
// @Title WebAuthnSigninBegin
|
||||
// @Tag Login API
|
||||
// @Description WebAuthn Login Flow 2nd stage
|
||||
@@ -124,7 +128,7 @@ func (c *ApiController) WebAuthnSigninFinish() {
|
||||
c.ResponseError("Please call WebAuthnSigninBegin first")
|
||||
return
|
||||
}
|
||||
c.Ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||
c.Ctx.Request.Body = io.NopCloser(bytes.NewBuffer(c.Ctx.Input.RequestBody))
|
||||
userId := string(sessionData.UserID)
|
||||
user := object.GetUser(userId)
|
||||
_, err := webauthnObj.FinishLogin(user, sessionData, c.Ctx.Request)
|
||||
|
@@ -48,6 +48,7 @@ func (c *ApiController) GetWebhooks() {
|
||||
}
|
||||
}
|
||||
|
||||
// GetWebhook
|
||||
// @Title GetWebhook
|
||||
// @Tag Webhook API
|
||||
// @Description get webhook
|
||||
@@ -61,6 +62,7 @@ func (c *ApiController) GetWebhook() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// UpdateWebhook
|
||||
// @Title UpdateWebhook
|
||||
// @Tag Webhook API
|
||||
// @Description update webhook
|
||||
@@ -81,6 +83,7 @@ func (c *ApiController) UpdateWebhook() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// AddWebhook
|
||||
// @Title AddWebhook
|
||||
// @Tag Webhook API
|
||||
// @Description add webhook
|
||||
@@ -98,6 +101,7 @@ func (c *ApiController) AddWebhook() {
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
||||
// DeleteWebhook
|
||||
// @Title DeleteWebhook
|
||||
// @Tag Webhook API
|
||||
// @Description delete webhook
|
||||
|
14
idp/adfs.go
14
idp/adfs.go
@@ -19,7 +19,7 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -77,6 +77,7 @@ type AdfsToken struct {
|
||||
ErrMsg string `json:"error_description"`
|
||||
}
|
||||
|
||||
// GetToken
|
||||
// get more detail via: https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-openid-connect-oauth-flows-scenarios#request-an-access-token
|
||||
func (idp *AdfsIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
payload := url.Values{}
|
||||
@@ -88,7 +89,7 @@ func (idp *AdfsIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,6 +110,7 @@ func (idp *AdfsIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// GetUserInfo
|
||||
// Since the userinfo endpoint of ADFS only returns sub,
|
||||
// the id_token is used to resolve the userinfo
|
||||
func (idp *AdfsIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
@@ -122,10 +124,10 @@ func (idp *AdfsIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
}
|
||||
tokenSrc := []byte(token.AccessToken)
|
||||
publicKey, _ := keyset.Keys[0].Materialize()
|
||||
id_token, _ := jwt.Parse(bytes.NewReader(tokenSrc), jwt.WithVerify(jwa.RS256, publicKey))
|
||||
sid, _ := id_token.Get("sid")
|
||||
upn, _ := id_token.Get("upn")
|
||||
name, _ := id_token.Get("unique_name")
|
||||
idToken, _ := jwt.Parse(bytes.NewReader(tokenSrc), jwt.WithVerify(jwa.RS256, publicKey))
|
||||
sid, _ := idToken.Get("sid")
|
||||
upn, _ := idToken.Get("upn")
|
||||
name, _ := idToken.Get("unique_name")
|
||||
userinfo := &UserInfo{
|
||||
Id: sid.(string),
|
||||
Username: name.(string),
|
||||
|
@@ -24,7 +24,6 @@ import (
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
@@ -205,7 +204,7 @@ func (idp *AlipayIdProvider) postWithBody(body interface{}, targetUrl string) ([
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@@ -97,7 +97,7 @@ func (idp *BaiduIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -76,6 +75,7 @@ type BilibiliIdProviderTokenResponse struct {
|
||||
Data BilibiliProviderToken `json:"data"`
|
||||
}
|
||||
|
||||
// GetToken
|
||||
/*
|
||||
{
|
||||
"code": 0,
|
||||
@@ -170,7 +170,7 @@ func (idp *BilibiliIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -204,7 +204,7 @@ func (idp *BilibiliIdProvider) postWithBody(body interface{}, url string) ([]byt
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -71,7 +71,7 @@ func (idp *CasdoorIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func (idp *CasdoorIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
_ "net/url"
|
||||
_ "time"
|
||||
@@ -84,7 +84,7 @@ func (idp *CustomIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -101,7 +100,7 @@ func (idp *DingTalkIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
|
||||
token := &oauth2.Token{
|
||||
AccessToken: pToken.AccessToken,
|
||||
Expiry: time.Unix(time.Now().Unix()+int64(pToken.ExpiresIn), 0),
|
||||
Expiry: time.Unix(time.Now().Unix()+pToken.ExpiresIn, 0),
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
@@ -145,7 +144,7 @@ func (idp *DingTalkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -180,7 +179,7 @@ func (idp *DingTalkIdProvider) postWithBody(body interface{}, url string) ([]byt
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -98,7 +98,7 @@ func (idp *DouyinIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -177,7 +177,7 @@ func (idp *DouyinIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -71,6 +71,7 @@ type FacebookCheckToken struct {
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
// FacebookCheckTokenData
|
||||
// Get more detail via: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow#checktoken
|
||||
type FacebookCheckTokenData struct {
|
||||
UserId string `json:"user_id"`
|
||||
|
@@ -19,7 +19,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -93,7 +92,7 @@ func (idp *GiteeIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rbs, err := ioutil.ReadAll(resp.Body)
|
||||
rbs, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -202,7 +201,7 @@ func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -236,7 +235,7 @@ func (idp *GithubIdProvider) postWithBody(body interface{}, url string) ([]byte,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -85,7 +85,7 @@ func (idp *GitlabIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -209,7 +209,7 @@ func (idp *GitlabIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@@ -95,7 +95,7 @@ func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -207,6 +207,7 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
return &idp
|
||||
}
|
||||
|
||||
// SetHttpClient
|
||||
// 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")
|
||||
|
@@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@@ -58,6 +58,7 @@ type InfoflowInterToken struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
}
|
||||
|
||||
// GetToken
|
||||
// get more detail via: https://qy.baidu.com/doc/index.html#/inner_quickstart/flow?id=%E8%8E%B7%E5%8F%96accesstoken
|
||||
func (idp *InfoflowInternalIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
pTokenParams := &struct {
|
||||
@@ -69,7 +70,7 @@ func (idp *InfoflowInternalIdProvider) GetToken(code string) (*oauth2.Token, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,6 +138,7 @@ type InfoflowInternalUserInfo struct {
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// GetUserInfo
|
||||
// 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
|
||||
@@ -147,7 +149,7 @@ func (idp *InfoflowInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserIn
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -165,7 +167,7 @@ func (idp *InfoflowInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserIn
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -63,6 +62,7 @@ type InfoflowToken struct {
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
}
|
||||
|
||||
// GetToken
|
||||
// get more detail via: https://qy.baidu.com/doc/index.html#/third_serverapi/authority
|
||||
func (idp *InfoflowIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
pTokenParams := &struct {
|
||||
@@ -134,6 +134,7 @@ type InfoflowUserInfo struct {
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// GetUserInfo
|
||||
// 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
|
||||
@@ -144,7 +145,7 @@ func (idp *InfoflowIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -162,7 +163,7 @@ func (idp *InfoflowIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -197,7 +198,7 @@ func (idp *InfoflowIdProvider) postWithBody(body interface{}, url string) ([]byt
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -17,7 +17,6 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -173,7 +172,7 @@ func (idp *LarkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -204,7 +203,7 @@ func (idp *LarkIdProvider) postWithBody(body interface{}, url string) ([]byte, e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -85,7 +84,7 @@ func (idp *LinkedInIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rbs, err := ioutil.ReadAll(resp.Body)
|
||||
rbs, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -323,7 +322,7 @@ func (idp *LinkedInIdProvider) GetUrlRespWithAuthorization(url, token string) ([
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
bs, err := ioutil.ReadAll(resp.Body)
|
||||
bs, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@@ -114,7 +114,7 @@ func (idp *OktaIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -178,7 +178,7 @@ func (idp *OktaIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
@@ -75,7 +75,7 @@ func (idp *QqIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
tokenContent, err := ioutil.ReadAll(resp.Body)
|
||||
tokenContent, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -148,7 +148,7 @@ func (idp *QqIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
openIdBody, err := ioutil.ReadAll(resp.Body)
|
||||
openIdBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -167,7 +167,7 @@ func (idp *QqIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
userInfoBody, err := ioutil.ReadAll(resp.Body)
|
||||
userInfoBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -144,7 +144,7 @@ type WechatUserInfo struct {
|
||||
City string `json:"city"` // City filled in by general user's personal data
|
||||
Province string `json:"province"` // Province filled in by ordinary user's personal information
|
||||
Country string `json:"country"` // Country, such as China is CN
|
||||
Headimgurl string `json:"headimgurl"` // User avatar, the last value represents the size of the square avatar (there are optional values of 0, 46, 64, 96, 132, 0 represents a 640*640 square avatar), this item is empty when the user does not have a avatar
|
||||
Headimgurl string `json:"headimgurl"` // User avatar, the last value represents the size of the square avatar (there are optional values of 0, 46, 64, 96, 132, 0 represents a 640*640 square avatar), this item is empty when the user does not have an avatar
|
||||
Privilege []string `json:"privilege"` // User Privilege information, json array, such as Wechat Woka user (chinaunicom)
|
||||
Unionid string `json:"unionid"` // Unified user identification. For an application under a WeChat open platform account, the unionid of the same user is unique.
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@@ -65,7 +65,7 @@ func (idp *WeChatMiniProgramIdProvider) GetSessionByCode(code string) (*WeChatMi
|
||||
return nil, err
|
||||
}
|
||||
defer sessionResponse.Body.Close()
|
||||
data, err := ioutil.ReadAll(sessionResponse.Body)
|
||||
data, err := io.ReadAll(sessionResponse.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -17,13 +17,14 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// WeComInternalIdProvider
|
||||
// This idp is using wecom internal application api as idp
|
||||
type WeComInternalIdProvider struct {
|
||||
Client *http.Client
|
||||
@@ -72,7 +73,7 @@ func (idp *WeComInternalIdProvider) GetToken(code string) (*oauth2.Token, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -123,7 +124,7 @@ func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -144,7 +145,7 @@ func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -195,7 +194,7 @@ func (idp *WeComIdProvider) postWithBody(body interface{}, url string) ([]byte,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -19,7 +19,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -92,7 +91,7 @@ func (idp *WeiBoIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
return
|
||||
}
|
||||
}(resp.Body)
|
||||
bs, err := ioutil.ReadAll(resp.Body)
|
||||
bs, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@ func SendEmail(provider *Provider, title string, content string, dest string, se
|
||||
// DailSmtpServer Dail Smtp server
|
||||
func DailSmtpServer(provider *Provider) error {
|
||||
dialer := gomail.NewDialer(provider.Host, provider.Port, provider.ClientId, provider.ClientSecret)
|
||||
dialer.SSL = !provider.DisableSsl
|
||||
|
||||
sender, err := dialer.Dial()
|
||||
if err != nil {
|
||||
|
@@ -16,7 +16,7 @@ package object
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"github.com/duo-labs/webauthn/webauthn"
|
||||
@@ -158,11 +158,11 @@ func initBuiltInApplication() {
|
||||
func readTokenFromFile() (string, string) {
|
||||
pemPath := "./object/token_jwt_key.pem"
|
||||
keyPath := "./object/token_jwt_key.key"
|
||||
pem, err := ioutil.ReadFile(pemPath)
|
||||
pem, err := os.ReadFile(pemPath)
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
key, err := ioutil.ReadFile(keyPath)
|
||||
key, err := os.ReadFile(keyPath)
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
|
@@ -31,6 +31,7 @@ func GetLdapAutoSynchronizer() *LdapAutoSynchronizer {
|
||||
return globalLdapAutoSynchronizer
|
||||
}
|
||||
|
||||
// StartAutoSync
|
||||
// start autosync for specified ldap, old existing autosync goroutine will be ceased
|
||||
func (l *LdapAutoSynchronizer) StartAutoSync(ldapId string) error {
|
||||
l.Lock()
|
||||
@@ -95,6 +96,7 @@ func (l *LdapAutoSynchronizer) syncRoutine(ldap *Ldap, stopChan chan struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// LdapAutoSynchronizerStartUpAll
|
||||
// start all autosync goroutine for existing ldap servers in each organizations
|
||||
func (l *LdapAutoSynchronizer) LdapAutoSynchronizerStartUpAll() {
|
||||
organizations := []*Organization{}
|
||||
|
@@ -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)
|
||||
|
162
object/permission_enforcer.go
Normal file
162
object/permission_enforcer.go
Normal 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
|
||||
}
|
@@ -43,10 +43,11 @@ type Provider struct {
|
||||
CustomUserInfoUrl string `xorm:"varchar(200)" json:"customUserInfoUrl"`
|
||||
CustomLogo string `xorm:"varchar(200)" json:"customLogo"`
|
||||
|
||||
Host string `xorm:"varchar(100)" json:"host"`
|
||||
Port int `json:"port"`
|
||||
Title string `xorm:"varchar(100)" json:"title"`
|
||||
Content string `xorm:"varchar(1000)" json:"content"`
|
||||
Host string `xorm:"varchar(100)" json:"host"`
|
||||
Port int `json:"port"`
|
||||
DisableSsl bool `json:"disableSsl"`
|
||||
Title string `xorm:"varchar(100)" json:"title"`
|
||||
Content string `xorm:"varchar(1000)" json:"content"`
|
||||
|
||||
RegionId string `xorm:"varchar(100)" json:"regionId"`
|
||||
SignName string `xorm:"varchar(100)" json:"signName"`
|
||||
|
@@ -35,6 +35,7 @@ import (
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// NewSamlResponse
|
||||
// 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{
|
||||
@@ -113,6 +114,7 @@ func (x X509Key) GetKeyPair() (privateKey *rsa.PrivateKey, cert []byte, err erro
|
||||
return privateKey, cert, err
|
||||
}
|
||||
|
||||
// IdpEntityDescriptor
|
||||
// SAML METADATA
|
||||
type IdpEntityDescriptor struct {
|
||||
XMLName xml.Name `xml:"EntityDescriptor"`
|
||||
|
@@ -44,7 +44,7 @@ func ParseSamlResponse(samlResponse string, providerType string) (string, error)
|
||||
func GenerateSamlLoginUrl(id, relayState string) (string, string, error) {
|
||||
provider := GetProvider(id)
|
||||
if provider.Category != "SAML" {
|
||||
return "", "", fmt.Errorf("Provider %s's category is not SAML", provider.Name)
|
||||
return "", "", fmt.Errorf("provider %s's category is not SAML", provider.Name)
|
||||
}
|
||||
sp, err := buildSp(provider, "")
|
||||
if err != nil {
|
||||
|
@@ -27,14 +27,14 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
hourSeconds = 3600
|
||||
INVALID_REQUEST = "invalid_request"
|
||||
INVALID_CLIENT = "invalid_client"
|
||||
INVALID_GRANT = "invalid_grant"
|
||||
UNAUTHORIZED_CLIENT = "unauthorized_client"
|
||||
UNSUPPORTED_GRANT_TYPE = "unsupported_grant_type"
|
||||
INVALID_SCOPE = "invalid_scope"
|
||||
ENDPOINT_ERROR = "endpoint_error"
|
||||
hourSeconds = 3600
|
||||
InvalidRequest = "invalid_request"
|
||||
InvalidClient = "invalid_client"
|
||||
InvalidGrant = "invalid_grant"
|
||||
UnauthorizedClient = "unauthorized_client"
|
||||
UnsupportedGrantType = "unsupported_grant_type"
|
||||
InvalidScope = "invalid_scope"
|
||||
EndpointError = "endpoint_error"
|
||||
)
|
||||
|
||||
type Code struct {
|
||||
@@ -200,7 +200,7 @@ func DeleteToken(token *Token) bool {
|
||||
return affected != 0
|
||||
}
|
||||
|
||||
func DeleteTokenByAceessToken(accessToken string) (bool, *Application) {
|
||||
func DeleteTokenByAccessToken(accessToken string) (bool, *Application) {
|
||||
token := Token{AccessToken: accessToken}
|
||||
existed, err := adapter.Engine.Get(&token)
|
||||
if err != nil {
|
||||
@@ -325,7 +325,7 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
||||
application := GetApplicationByClientId(clientId)
|
||||
if application == nil {
|
||||
return &TokenError{
|
||||
Error: INVALID_CLIENT,
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_id is invalid",
|
||||
}
|
||||
}
|
||||
@@ -334,7 +334,7 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
||||
|
||||
if !IsGrantTypeValid(grantType, application.GrantTypes) && tag == "" {
|
||||
return &TokenError{
|
||||
Error: UNSUPPORTED_GRANT_TYPE,
|
||||
Error: UnsupportedGrantType,
|
||||
ErrorDescription: fmt.Sprintf("grant_type: %s is not supported in this application", grantType),
|
||||
}
|
||||
}
|
||||
@@ -377,20 +377,20 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
// check parameters
|
||||
if grantType != "refresh_token" {
|
||||
return &TokenError{
|
||||
Error: UNSUPPORTED_GRANT_TYPE,
|
||||
Error: UnsupportedGrantType,
|
||||
ErrorDescription: "grant_type should be refresh_token",
|
||||
}
|
||||
}
|
||||
application := GetApplicationByClientId(clientId)
|
||||
if application == nil {
|
||||
return &TokenError{
|
||||
Error: INVALID_CLIENT,
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_id is invalid",
|
||||
}
|
||||
}
|
||||
if clientSecret != "" && application.ClientSecret != clientSecret {
|
||||
return &TokenError{
|
||||
Error: INVALID_CLIENT,
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_secret is invalid",
|
||||
}
|
||||
}
|
||||
@@ -399,7 +399,7 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
existed, err := adapter.Engine.Get(&token)
|
||||
if err != nil || !existed {
|
||||
return &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "refresh token is invalid, expired or revoked",
|
||||
}
|
||||
}
|
||||
@@ -408,7 +408,7 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
_, err = ParseJwtToken(refreshToken, cert)
|
||||
if err != nil {
|
||||
return &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: fmt.Sprintf("parse refresh token error: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
@@ -416,14 +416,14 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
user := getUser(application.Organization, token.User)
|
||||
if user.IsForbidden {
|
||||
return &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the user is forbidden to sign in, please contact the administrator",
|
||||
}
|
||||
}
|
||||
newAccessToken, newRefreshToken, err := generateJwtToken(application, user, "", scope, host)
|
||||
if err != nil {
|
||||
return &TokenError{
|
||||
Error: ENDPOINT_ERROR,
|
||||
Error: EndpointError,
|
||||
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
@@ -464,6 +464,7 @@ func pkceChallenge(verifier string) string {
|
||||
return challenge
|
||||
}
|
||||
|
||||
// IsGrantTypeValid
|
||||
// Check if grantType is allowed in the current application
|
||||
// authorization_code is allowed by default
|
||||
func IsGrantTypeValid(method string, grantTypes []string) bool {
|
||||
@@ -478,11 +479,12 @@ func IsGrantTypeValid(method string, grantTypes []string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetAuthorizationCodeToken
|
||||
// Authorization code flow
|
||||
func GetAuthorizationCodeToken(application *Application, clientSecret string, code string, verifier string) (*Token, *TokenError) {
|
||||
if code == "" {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_REQUEST,
|
||||
Error: InvalidRequest,
|
||||
ErrorDescription: "authorization code should not be empty",
|
||||
}
|
||||
}
|
||||
@@ -490,21 +492,21 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
token := getTokenByCode(code)
|
||||
if token == nil {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "authorization code is invalid",
|
||||
}
|
||||
}
|
||||
if token.CodeIsUsed {
|
||||
// anti replay attacks
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "authorization code has been used",
|
||||
}
|
||||
}
|
||||
|
||||
if token.CodeChallenge != "" && pkceChallenge(verifier) != token.CodeChallenge {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "verifier is invalid",
|
||||
}
|
||||
}
|
||||
@@ -514,13 +516,13 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
// but if it is provided, it must be accurate.
|
||||
if token.CodeChallenge == "" {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_CLIENT,
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_secret is invalid",
|
||||
}
|
||||
} else {
|
||||
if clientSecret != "" {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_CLIENT,
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_secret is invalid",
|
||||
}
|
||||
}
|
||||
@@ -529,7 +531,7 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
|
||||
if application.Name != token.Application {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the token is for wrong application (client_id)",
|
||||
}
|
||||
}
|
||||
@@ -537,39 +539,40 @@ func GetAuthorizationCodeToken(application *Application, clientSecret string, co
|
||||
if time.Now().Unix() > token.CodeExpireIn {
|
||||
// code must be used within 5 minutes
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "authorization code has expired",
|
||||
}
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// GetPasswordToken
|
||||
// Resource Owner Password Credentials flow
|
||||
func GetPasswordToken(application *Application, username string, password string, scope string, host string) (*Token, *TokenError) {
|
||||
user := getUser(application.Organization, username)
|
||||
if user == nil {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the user does not exist",
|
||||
}
|
||||
}
|
||||
msg := CheckPassword(user, password)
|
||||
if msg != "" {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "invalid username or password",
|
||||
}
|
||||
}
|
||||
if user.IsForbidden {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the user is forbidden to sign in, please contact the administrator",
|
||||
}
|
||||
}
|
||||
accessToken, refreshToken, err := generateJwtToken(application, user, "", scope, host)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: ENDPOINT_ERROR,
|
||||
Error: EndpointError,
|
||||
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
@@ -592,11 +595,12 @@ func GetPasswordToken(application *Application, username string, password string
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// GetClientCredentialsToken
|
||||
// Client Credentials flow
|
||||
func GetClientCredentialsToken(application *Application, clientSecret string, scope string, host string) (*Token, *TokenError) {
|
||||
if application.ClientSecret != clientSecret {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_CLIENT,
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "client_secret is invalid",
|
||||
}
|
||||
}
|
||||
@@ -608,7 +612,7 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
|
||||
accessToken, _, err := generateJwtToken(application, nullUser, "", scope, host)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: ENDPOINT_ERROR,
|
||||
Error: EndpointError,
|
||||
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
@@ -630,6 +634,7 @@ func GetClientCredentialsToken(application *Application, clientSecret string, sc
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// GetTokenByUser
|
||||
// Implicit flow
|
||||
func GetTokenByUser(application *Application, user *User, scope string, host string) (*Token, error) {
|
||||
accessToken, refreshToken, err := generateJwtToken(application, user, "", scope, host)
|
||||
@@ -655,12 +660,13 @@ func GetTokenByUser(application *Application, user *User, scope string, host str
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// GetWechatMiniProgramToken
|
||||
// Wechat Mini Program flow
|
||||
func GetWechatMiniProgramToken(application *Application, code string, host string, username string, avatar string) (*Token, *TokenError) {
|
||||
mpProvider := GetWechatMiniProgramProvider(application)
|
||||
if mpProvider == nil {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_CLIENT,
|
||||
Error: InvalidClient,
|
||||
ErrorDescription: "the application does not support wechat mini program",
|
||||
}
|
||||
}
|
||||
@@ -669,14 +675,14 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
|
||||
session, err := mpIdp.GetSessionByCode(code)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: fmt.Sprintf("get wechat mini program session error: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
openId, unionId := session.Openid, session.Unionid
|
||||
if openId == "" && unionId == "" {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_REQUEST,
|
||||
Error: InvalidRequest,
|
||||
ErrorDescription: "the wechat mini program session is invalid",
|
||||
}
|
||||
}
|
||||
@@ -684,7 +690,7 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
|
||||
if user == nil {
|
||||
if !application.EnableSignUp {
|
||||
return nil, &TokenError{
|
||||
Error: INVALID_GRANT,
|
||||
Error: InvalidGrant,
|
||||
ErrorDescription: "the application does not allow to sign up new account",
|
||||
}
|
||||
}
|
||||
@@ -703,13 +709,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{
|
||||
UserPropertiesWechatOpenId: openId,
|
||||
UserPropertiesWechatUnionId: unionId,
|
||||
},
|
||||
}
|
||||
AddUser(user)
|
||||
}
|
||||
@@ -717,7 +726,7 @@ func GetWechatMiniProgramToken(application *Application, code string, host strin
|
||||
accessToken, refreshToken, err := generateJwtToken(application, user, "", "", host)
|
||||
if err != nil {
|
||||
return nil, &TokenError{
|
||||
Error: ENDPOINT_ERROR,
|
||||
Error: EndpointError,
|
||||
ErrorDescription: fmt.Sprintf("generate jwt token error: %s", err.Error()),
|
||||
}
|
||||
}
|
||||
|
@@ -136,6 +136,7 @@ func GenerateId() {
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// GetCasTokenByPgt
|
||||
/**
|
||||
@ret1: whether a token is found
|
||||
@ret2: token, nil if not found
|
||||
@@ -150,6 +151,7 @@ func GetCasTokenByPgt(pgt string) (bool, *CasAuthenticationSuccess, string, stri
|
||||
return false, nil, "", ""
|
||||
}
|
||||
|
||||
// GetCasTokenByTicket
|
||||
/**
|
||||
@ret1: whether a token is found
|
||||
@ret2: token, nil if not found
|
||||
@@ -207,6 +209,7 @@ func GenerateCasToken(userId string, service string) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetValidationBySaml
|
||||
/**
|
||||
@ret1: saml response
|
||||
@ret2: the service URL who requested to issue this token
|
||||
|
@@ -24,6 +24,11 @@ import (
|
||||
"xorm.io/core"
|
||||
)
|
||||
|
||||
const (
|
||||
UserPropertiesWechatUnionId = "wechatUnionId"
|
||||
UserPropertiesWechatOpenId = "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)
|
||||
}
|
||||
|
@@ -50,30 +50,31 @@ func GetWebAuthnObject(host string) *webauthn.WebAuthn {
|
||||
return webAuthn
|
||||
}
|
||||
|
||||
// WebAuthnID
|
||||
// implementation of webauthn.User interface
|
||||
func (u *User) WebAuthnID() []byte {
|
||||
return []byte(u.GetId())
|
||||
func (user *User) WebAuthnID() []byte {
|
||||
return []byte(user.GetId())
|
||||
}
|
||||
|
||||
func (u *User) WebAuthnName() string {
|
||||
return u.Name
|
||||
func (user *User) WebAuthnName() string {
|
||||
return user.Name
|
||||
}
|
||||
|
||||
func (u *User) WebAuthnDisplayName() string {
|
||||
return u.DisplayName
|
||||
func (user *User) WebAuthnDisplayName() string {
|
||||
return user.DisplayName
|
||||
}
|
||||
|
||||
func (u *User) WebAuthnCredentials() []webauthn.Credential {
|
||||
return u.WebauthnCredentials
|
||||
func (user *User) WebAuthnCredentials() []webauthn.Credential {
|
||||
return user.WebauthnCredentials
|
||||
}
|
||||
|
||||
func (u *User) WebAuthnIcon() string {
|
||||
return u.Avatar
|
||||
func (user *User) WebAuthnIcon() string {
|
||||
return user.Avatar
|
||||
}
|
||||
|
||||
// CredentialExcludeList returns a CredentialDescriptor array filled with all the user's credentials
|
||||
func (u *User) CredentialExcludeList() []protocol.CredentialDescriptor {
|
||||
credentials := u.WebAuthnCredentials()
|
||||
func (user *User) CredentialExcludeList() []protocol.CredentialDescriptor {
|
||||
credentials := user.WebAuthnCredentials()
|
||||
credentialExcludeList := []protocol.CredentialDescriptor{}
|
||||
for _, cred := range credentials {
|
||||
descriptor := protocol.CredentialDescriptor{
|
||||
@@ -86,16 +87,16 @@ func (u *User) CredentialExcludeList() []protocol.CredentialDescriptor {
|
||||
return credentialExcludeList
|
||||
}
|
||||
|
||||
func (u *User) AddCredentials(credential webauthn.Credential, isGlobalAdmin bool) bool {
|
||||
u.WebauthnCredentials = append(u.WebauthnCredentials, credential)
|
||||
return UpdateUser(u.GetId(), u, []string{"webauthnCredentials"}, isGlobalAdmin)
|
||||
func (user *User) AddCredentials(credential webauthn.Credential, isGlobalAdmin bool) bool {
|
||||
user.WebauthnCredentials = append(user.WebauthnCredentials, credential)
|
||||
return UpdateUser(user.GetId(), user, []string{"webauthnCredentials"}, isGlobalAdmin)
|
||||
}
|
||||
|
||||
func (u *User) DeleteCredentials(credentialIdBase64 string) bool {
|
||||
for i, credential := range u.WebauthnCredentials {
|
||||
func (user *User) DeleteCredentials(credentialIdBase64 string) bool {
|
||||
for i, credential := range user.WebauthnCredentials {
|
||||
if base64.StdEncoding.EncodeToString(credential.ID) == credentialIdBase64 {
|
||||
u.WebauthnCredentials = append(u.WebauthnCredentials[0:i], u.WebauthnCredentials[i+1:]...)
|
||||
return UpdateUserForAllFields(u.GetId(), u)
|
||||
user.WebauthnCredentials = append(user.WebauthnCredentials[0:i], user.WebauthnCredentials[i+1:]...)
|
||||
return UpdateUserForAllFields(user.GetId(), user)
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
@@ -42,7 +42,7 @@ type VerificationRecord struct {
|
||||
|
||||
func SendVerificationCodeToEmail(organization *Organization, user *User, provider *Provider, remoteAddr string, dest string) error {
|
||||
if provider == nil {
|
||||
return fmt.Errorf("Please set an Email provider first")
|
||||
return fmt.Errorf("please set an Email provider first")
|
||||
}
|
||||
|
||||
sender := organization.DisplayName
|
||||
@@ -60,7 +60,7 @@ func SendVerificationCodeToEmail(organization *Organization, user *User, provide
|
||||
|
||||
func SendVerificationCodeToPhone(organization *Organization, user *User, provider *Provider, remoteAddr string, dest string) error {
|
||||
if provider == nil {
|
||||
return errors.New("Please set a SMS provider first")
|
||||
return errors.New("please set a SMS provider first")
|
||||
}
|
||||
|
||||
code := getRandomCode(5)
|
||||
@@ -85,7 +85,7 @@ func AddToVerificationRecord(user *User, provider *Provider, remoteAddr, recordT
|
||||
|
||||
now := time.Now().Unix()
|
||||
if has && now-record.Time < 60 {
|
||||
return errors.New("You can only send one code in 60s.")
|
||||
return errors.New("you can only send one code in 60s")
|
||||
}
|
||||
|
||||
record.Owner = provider.Owner
|
||||
|
3
pp/gc.go
3
pp/gc.go
@@ -20,7 +20,6 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@@ -147,7 +146,7 @@ func (pp *GcPaymentProvider) doPost(postBytes []byte) ([]byte, error) {
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
respBytes, err := ioutil.ReadAll(resp.Body)
|
||||
respBytes, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -83,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")
|
||||
|
@@ -20,7 +20,7 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -168,7 +168,7 @@ func GetMinLenStr(strs ...string) string {
|
||||
}
|
||||
|
||||
func ReadStringFromPath(path string) string {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -177,7 +177,7 @@ func ReadStringFromPath(path string) string {
|
||||
}
|
||||
|
||||
func WriteStringToPath(s string, path string) {
|
||||
err := ioutil.WriteFile(path, []byte(s), 0o644)
|
||||
err := os.WriteFile(path, []byte(s), 0o644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@@ -42,7 +42,13 @@
|
||||
"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",
|
||||
@@ -89,7 +95,7 @@
|
||||
// don't use strict mod now, otherwise there are a lot of errors in the codebase
|
||||
"no-unused-vars": "off",
|
||||
"react/no-deprecated": "warn",
|
||||
"no-case-declarations": "warn",
|
||||
"no-case-declarations": "off",
|
||||
"react/jsx-key": "warn"
|
||||
}
|
||||
}
|
||||
|
@@ -63,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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ class AccountTable extends React.Component {
|
||||
}
|
||||
|
||||
addRow(table) {
|
||||
let row = {name: Setting.getNewRowNameForTable(table, "Please select an account item"), visible: true, viewRule: "Public", modifyRule: "Self"};
|
||||
const row = {name: Setting.getNewRowNameForTable(table, "Please select an account item"), visible: true, viewRule: "Public", modifyRule: "Self"};
|
||||
if (table === undefined) {
|
||||
table = [];
|
||||
}
|
||||
@@ -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"},
|
||||
|
@@ -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);
|
||||
}
|
||||
@@ -242,7 +242,7 @@ class App extends Component {
|
||||
});
|
||||
|
||||
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") {
|
||||
@@ -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 [];
|
||||
@@ -669,26 +669,28 @@ class App extends Component {
|
||||
if (this.isDoorPages()) {
|
||||
return (
|
||||
<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);}} />)} />
|
||||
<Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/login/:owner" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/auto-signup/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signup"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/signup/oauth/authorize" render={(props) => <SignupPage account={this.state.account} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/login/saml/authorize/:owner/:applicationName" render={(props) => <LoginPage account={this.state.account} type={"saml"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/cas/:owner/:casApplicationName/logout" render={(props) => this.renderHomeIfLoggedIn(<CasLogout clearAccount={() => this.setState({account: null})} {...props} />)} />
|
||||
<Route exact path="/cas/:owner/:casApplicationName/login" render={(props) => {return (<LoginPage type={"cas"} mode={"signup"} account={this.state.account} {...props} />);}} />
|
||||
<Route exact path="/callback" component={AuthCallback} />
|
||||
<Route exact path="/callback/saml" component={SamlCallback} />
|
||||
<Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...props} />)} />
|
||||
<Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...props} />)} />
|
||||
<Route exact path="/prompt" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/prompt/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} {...props} />)} />
|
||||
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
|
||||
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
|
||||
</Switch>
|
||||
<div id="content-wrap" style={{flexDirection: "column"}}>
|
||||
<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);}} />)} />
|
||||
<Route exact path="/login" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/login/:owner" render={(props) => this.renderHomeIfLoggedIn(<SelfLoginPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/auto-signup/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signup"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/signup/oauth/authorize" render={(props) => <SignupPage account={this.state.account} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/login/oauth/authorize" render={(props) => <LoginPage account={this.state.account} type={"code"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/login/saml/authorize/:owner/:applicationName" render={(props) => <LoginPage account={this.state.account} type={"saml"} mode={"signin"} {...props} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} />} />
|
||||
<Route exact path="/cas/:owner/:casApplicationName/logout" render={(props) => this.renderHomeIfLoggedIn(<CasLogout clearAccount={() => this.setState({account: null})} {...props} />)} />
|
||||
<Route exact path="/cas/:owner/:casApplicationName/login" render={(props) => {return (<LoginPage type={"cas"} mode={"signup"} account={this.state.account} {...props} />);}} />
|
||||
<Route exact path="/callback" component={AuthCallback} />
|
||||
<Route exact path="/callback/saml" component={SamlCallback} />
|
||||
<Route exact path="/forget" render={(props) => this.renderHomeIfLoggedIn(<SelfForgetPage {...props} />)} />
|
||||
<Route exact path="/forget/:applicationName" render={(props) => this.renderHomeIfLoggedIn(<ForgetPage {...props} />)} />
|
||||
<Route exact path="/prompt" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} {...props} />)} />
|
||||
<Route exact path="/prompt/:applicationName" render={(props) => this.renderLoginIfNotLoggedIn(<PromptPage account={this.state.account} onUpdateAccount={(account) => {this.onUpdateAccount(account);}} {...props} />)} />
|
||||
<Route path="" render={() => <Result status="404" title="404 NOT FOUND" subTitle={i18next.t("general:Sorry, the page you visited does not exist.")}
|
||||
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>} />} />
|
||||
</Switch>
|
||||
</div>
|
||||
{
|
||||
this.renderFooter()
|
||||
}
|
||||
|
@@ -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,
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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 === "") {
|
||||
|
@@ -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) => {
|
||||
|
@@ -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,
|
||||
@@ -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 === "") {
|
||||
|
@@ -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;
|
||||
|
@@ -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}}>
|
||||
|
@@ -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`);
|
||||
@@ -103,7 +103,7 @@ class LdapSyncPage extends React.Component {
|
||||
}
|
||||
|
||||
getExistUsers(owner, users) {
|
||||
let uuidArray = [];
|
||||
const uuidArray = [];
|
||||
users.forEach(elem => {
|
||||
uuidArray.push(elem.uuid);
|
||||
});
|
||||
@@ -119,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);
|
||||
}
|
||||
@@ -133,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,
|
||||
|
@@ -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,
|
||||
@@ -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 === "") {
|
||||
|
@@ -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;
|
||||
|
@@ -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,
|
||||
@@ -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 === "") {
|
||||
|
@@ -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;
|
||||
|
@@ -54,7 +54,7 @@ export const PasswordModal = (props) => {
|
||||
});
|
||||
};
|
||||
|
||||
let hasOldPassword = user.password !== "";
|
||||
const hasOldPassword = user.password !== "";
|
||||
|
||||
return (
|
||||
<Row>
|
||||
|
@@ -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,
|
||||
@@ -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 === "") {
|
||||
|
@@ -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;
|
||||
|
@@ -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>
|
||||
|
@@ -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,
|
||||
@@ -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 === "") {
|
||||
|
@@ -243,7 +243,7 @@ class PermissionListPage 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;
|
||||
|
@@ -69,7 +69,7 @@ class ProductEditPage extends React.Component {
|
||||
updateProductField(key, value) {
|
||||
value = this.parseProductField(key, value);
|
||||
|
||||
let product = this.state.product;
|
||||
const product = this.state.product;
|
||||
product[key] = value;
|
||||
this.setState({
|
||||
product: product,
|
||||
@@ -252,7 +252,7 @@ class ProductEditPage extends React.Component {
|
||||
}
|
||||
|
||||
renderPreview() {
|
||||
let buyUrl = `/products/${this.state.product.name}/buy`;
|
||||
const buyUrl = `/products/${this.state.product.name}/buy`;
|
||||
return (
|
||||
<Col span={22} style={{display: "flex", flexDirection: "column"}}>
|
||||
<a style={{marginBottom: "10px", display: "flex"}} target="_blank" rel="noreferrer" href={buyUrl}>
|
||||
@@ -268,7 +268,7 @@ class ProductEditPage extends React.Component {
|
||||
}
|
||||
|
||||
submitProductEdit(willExist) {
|
||||
let product = Setting.deepCopy(this.state.product);
|
||||
const product = Setting.deepCopy(this.state.product);
|
||||
ProductBackend.updateProduct(this.state.product.owner, this.state.productName, product)
|
||||
.then((res) => {
|
||||
if (res.msg === "") {
|
||||
|
@@ -269,7 +269,7 @@ class ProductListPage 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;
|
||||
|
@@ -61,7 +61,7 @@ class ProviderEditPage extends React.Component {
|
||||
updateProviderField(key, value) {
|
||||
value = this.parseProviderField(key, value);
|
||||
|
||||
let provider = this.state.provider;
|
||||
const provider = this.state.provider;
|
||||
provider[key] = value;
|
||||
this.setState({
|
||||
provider: provider,
|
||||
@@ -148,11 +148,11 @@ class ProviderEditPage extends React.Component {
|
||||
}
|
||||
|
||||
loadSamlConfiguration() {
|
||||
var parser = new DOMParser();
|
||||
var xmlDoc = parser.parseFromString(this.state.provider.metadata, "text/xml");
|
||||
var cert = xmlDoc.getElementsByTagName("ds:X509Certificate")[0].childNodes[0].nodeValue;
|
||||
var endpoint = xmlDoc.getElementsByTagName("md:SingleSignOnService")[0].getAttribute("Location");
|
||||
var issuerUrl = xmlDoc.getElementsByTagName("md:EntityDescriptor")[0].getAttribute("entityID");
|
||||
const parser = new DOMParser();
|
||||
const xmlDoc = parser.parseFromString(this.state.provider.metadata, "text/xml");
|
||||
const cert = xmlDoc.getElementsByTagName("ds:X509Certificate")[0].childNodes[0].nodeValue;
|
||||
const endpoint = xmlDoc.getElementsByTagName("md:SingleSignOnService")[0].getAttribute("Location");
|
||||
const issuerUrl = xmlDoc.getElementsByTagName("md:EntityDescriptor")[0].getAttribute("entityID");
|
||||
this.updateProviderField("idP", cert);
|
||||
this.updateProviderField("endpoint", endpoint);
|
||||
this.updateProviderField("issuerUrl", issuerUrl);
|
||||
@@ -199,6 +199,7 @@ class ProviderEditPage extends React.Component {
|
||||
this.updateProviderField("type", "GitHub");
|
||||
} else if (value === "Email") {
|
||||
this.updateProviderField("type", "Default");
|
||||
this.updateProviderField("disableSsl", false);
|
||||
this.updateProviderField("title", "Casdoor Verification Code");
|
||||
this.updateProviderField("content", "You have requested a verification code at Casdoor. Here is your code: %s, please enter in 5 minutes.");
|
||||
} else if (value === "SMS") {
|
||||
@@ -510,6 +511,16 @@ class ProviderEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Disable SSL"), i18next.t("provider:Disable SSL - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={1} >
|
||||
<Switch checked={this.state.provider.disableSsl} onChange={checked => {
|
||||
this.updateProviderField("disableSsl", checked);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: "20px"}} >
|
||||
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("provider:Email Title"), i18next.t("provider:Email Title - Tooltip"))} :
|
||||
@@ -717,7 +728,7 @@ class ProviderEditPage extends React.Component {
|
||||
}
|
||||
|
||||
submitProviderEdit(willExist) {
|
||||
let provider = Setting.deepCopy(this.state.provider);
|
||||
const provider = Setting.deepCopy(this.state.provider);
|
||||
ProviderBackend.updateProvider(this.state.provider.owner, this.state.providerName, provider)
|
||||
.then((res) => {
|
||||
if (res.msg === "") {
|
||||
|
@@ -215,7 +215,7 @@ class ProviderListPage 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;
|
||||
|
@@ -39,7 +39,7 @@ class ProviderTable extends React.Component {
|
||||
}
|
||||
|
||||
addRow(table) {
|
||||
let row = {name: Setting.getNewRowNameForTable(table, "Please select a provider"), canSignUp: true, canSignIn: true, canUnlink: true, alertType: "None"};
|
||||
const row = {name: Setting.getNewRowNameForTable(table, "Please select a provider"), canSignUp: true, canSignIn: true, canUnlink: true, alertType: "None"};
|
||||
if (table === undefined) {
|
||||
table = [];
|
||||
}
|
||||
|
@@ -199,7 +199,7 @@ class RecordListPage 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.method !== undefined && params.method !== null) {
|
||||
field = "method";
|
||||
value = params.method;
|
||||
|
@@ -291,8 +291,8 @@ class ResourceListPage 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});
|
||||
ResourceBackend.getResources(this.props.account.owner, this.props.account.name, params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||
.then((res) => {
|
||||
|
@@ -91,7 +91,7 @@ class RoleEditPage extends React.Component {
|
||||
updateRoleField(key, value) {
|
||||
value = this.parseRoleField(key, value);
|
||||
|
||||
let role = this.state.role;
|
||||
const role = this.state.role;
|
||||
role[key] = value;
|
||||
this.setState({
|
||||
role: role,
|
||||
@@ -179,7 +179,7 @@ class RoleEditPage extends React.Component {
|
||||
}
|
||||
|
||||
submitRoleEdit(willExist) {
|
||||
let role = Setting.deepCopy(this.state.role);
|
||||
const role = Setting.deepCopy(this.state.role);
|
||||
RoleBackend.updateRole(this.state.organizationName, this.state.roleName, role)
|
||||
.then((res) => {
|
||||
if (res.msg === "") {
|
||||
|
@@ -194,7 +194,7 @@ class RoleListPage 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;
|
||||
|
@@ -23,7 +23,7 @@ import {authConfig} from "./auth/Auth";
|
||||
import {Helmet} from "react-helmet";
|
||||
import * as Conf from "./Conf";
|
||||
|
||||
export let ServerUrl = "";
|
||||
export const ServerUrl = "";
|
||||
|
||||
// export const StaticBaseUrl = "https://cdn.jsdelivr.net/gh/casbin/static";
|
||||
export const StaticBaseUrl = "https://cdn.casbin.org";
|
||||
@@ -136,11 +136,11 @@ export function getCountryRegionData() {
|
||||
language = Conf.DefaultLanguage;
|
||||
}
|
||||
|
||||
var countries = require("i18n-iso-countries");
|
||||
const countries = require("i18n-iso-countries");
|
||||
countries.registerLocale(require("i18n-iso-countries/langs/" + language + ".json"));
|
||||
var data = countries.getNames(language, {select: "official"});
|
||||
var result = [];
|
||||
for (var i in data) {result.push({code: i, name: data[i]});}
|
||||
const data = countries.getNames(language, {select: "official"});
|
||||
const result = [];
|
||||
for (const i in data) {result.push({code: i, name: data[i]});}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ export function openLink(link) {
|
||||
export function openLinkSafe(link) {
|
||||
// Javascript window.open issue in safari
|
||||
// https://stackoverflow.com/questions/45569893/javascript-window-open-issue-in-safari
|
||||
let a = document.createElement("a");
|
||||
const a = document.createElement("a");
|
||||
a.href = link;
|
||||
a.setAttribute("target", "_blank");
|
||||
a.click();
|
||||
@@ -445,9 +445,9 @@ export function getFriendlyFileSize(size) {
|
||||
return size + " B";
|
||||
}
|
||||
|
||||
let i = Math.floor(Math.log(size) / Math.log(1024));
|
||||
const i = Math.floor(Math.log(size) / Math.log(1024));
|
||||
let num = (size / Math.pow(1024, i));
|
||||
let round = Math.round(num);
|
||||
const round = Math.round(num);
|
||||
num = round < 10 ? num.toFixed(2) : round < 100 ? num.toFixed(1) : round;
|
||||
return `${num} ${"KMGTPEZY"[i - 1]}B`;
|
||||
}
|
||||
@@ -456,7 +456,7 @@ function getRandomInt(s) {
|
||||
let hash = 0;
|
||||
if (s.length !== 0) {
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
let char = s.charCodeAt(i);
|
||||
const char = s.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + char;
|
||||
hash = hash & hash;
|
||||
}
|
||||
@@ -772,7 +772,7 @@ export function getMaskedEmail(email) {
|
||||
username = maskString(username);
|
||||
|
||||
const domain = tokens[1];
|
||||
let domainTokens = domain.split(".");
|
||||
const domainTokens = domain.split(".");
|
||||
domainTokens[domainTokens.length - 2] = maskString(domainTokens[domainTokens.length - 2]);
|
||||
|
||||
return `${username}@${domainTokens.join(".")}`;
|
||||
@@ -802,7 +802,7 @@ export function getTagColor(s) {
|
||||
}
|
||||
|
||||
export function getTags(tags) {
|
||||
let res = [];
|
||||
const res = [];
|
||||
if (!tags) {return res;}
|
||||
tags.forEach((tag, i) => {
|
||||
res.push(
|
||||
@@ -840,7 +840,7 @@ export function getFromLink() {
|
||||
|
||||
export function scrollToDiv(divId) {
|
||||
if (divId) {
|
||||
let ele = document.getElementById(divId);
|
||||
const ele = document.getElementById(divId);
|
||||
if (ele) {
|
||||
ele.scrollIntoView({behavior: "smooth"});
|
||||
}
|
||||
|
@@ -38,7 +38,7 @@ class SignupTable extends React.Component {
|
||||
}
|
||||
|
||||
addRow(table) {
|
||||
let row = {name: Setting.getNewRowNameForTable(table, "Please select a signup item"), visible: true, required: true, rule: "None"};
|
||||
const row = {name: Setting.getNewRowNameForTable(table, "Please select a signup item"), visible: true, required: true, rule: "None"};
|
||||
if (table === undefined) {
|
||||
table = [];
|
||||
}
|
||||
|
@@ -73,7 +73,7 @@ class SyncerEditPage extends React.Component {
|
||||
updateSyncerField(key, value) {
|
||||
value = this.parseSyncerField(key, value);
|
||||
|
||||
let syncer = this.state.syncer;
|
||||
const syncer = this.state.syncer;
|
||||
syncer[key] = value;
|
||||
this.setState({
|
||||
syncer: syncer,
|
||||
@@ -119,7 +119,7 @@ class SyncerEditPage extends React.Component {
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: "100%"}} value={this.state.syncer.type} onChange={(value => {
|
||||
this.updateSyncerField("type", value);
|
||||
let syncer = this.state.syncer;
|
||||
const syncer = this.state.syncer;
|
||||
syncer["tableColumns"] = Setting.getSyncerTableColumns(this.state.syncer);
|
||||
syncer.table = (value === "Keycloak") ? "user_entity" : this.state.syncer.table;
|
||||
this.setState({
|
||||
@@ -295,7 +295,7 @@ class SyncerEditPage extends React.Component {
|
||||
}
|
||||
|
||||
submitSyncerEdit(willExist) {
|
||||
let syncer = Setting.deepCopy(this.state.syncer);
|
||||
const syncer = Setting.deepCopy(this.state.syncer);
|
||||
SyncerBackend.updateSyncer(this.state.syncer.owner, this.state.syncerName, syncer)
|
||||
.then((res) => {
|
||||
if (res.msg === "") {
|
||||
|
@@ -262,7 +262,7 @@ class SyncerListPage 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;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user