mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-09 01:13:41 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
6da452d7e0 | |||
5abcf913e6 | |||
58455e688e | |||
4d6f68eddc | |||
67f3c5a489 | |||
9c48582e0c | |||
645c631db9 | |||
3128e68df4 | |||
2247c6a883 | |||
04709f731b | |||
ebe1887e8b | |||
a7a8805713 |
@ -21,7 +21,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/beego/beego"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/beego/beego"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -18,8 +18,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/beego/beego"
|
||||
"github.com/beego/beego/logs"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,9 +17,6 @@ package controllers
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@ -35,17 +32,7 @@ func StartLdapServer() {
|
||||
routes.Search(handleSearch).Label(" SEARCH****")
|
||||
|
||||
server.Handle(routes)
|
||||
|
||||
go server.ListenAndServe("0.0.0.0:" + conf.GetConfigString("ldapServerPort"))
|
||||
|
||||
// When CTRL+C, SIGINT and SIGTERM signal occurs
|
||||
// Then stop server gracefully
|
||||
ch := make(chan os.Signal)
|
||||
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-ch
|
||||
close(ch)
|
||||
|
||||
server.Stop()
|
||||
server.ListenAndServe("0.0.0.0:" + conf.GetConfigString("ldapServerPort"))
|
||||
}
|
||||
|
||||
func handleBind(w ldapserver.ResponseWriter, m *ldapserver.Message) {
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -22,7 +22,7 @@ import (
|
||||
"mime"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -16,6 +16,7 @@ package controllers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/casdoor/casdoor/object"
|
||||
@ -100,7 +101,7 @@ func (c *ApiController) WebAuthnSigninBegin() {
|
||||
userName := c.Input().Get("name")
|
||||
user := object.GetUserByFields(userOwner, userName)
|
||||
if user == nil {
|
||||
c.ResponseError("Please Giveout Owner and Username.")
|
||||
c.ResponseError(fmt.Sprintf("The user: %s/%s doesn't exist", userOwner, userName))
|
||||
return
|
||||
}
|
||||
options, sessionData, err := webauthnObj.BeginLogin(user)
|
||||
@ -121,6 +122,7 @@ func (c *ApiController) WebAuthnSigninBegin() {
|
||||
// @Success 200 {object} Response "The Response object"
|
||||
// @router /webauthn/signin/finish [post]
|
||||
func (c *ApiController) WebAuthnSigninFinish() {
|
||||
responseType := c.Input().Get("responseType")
|
||||
webauthnObj := object.GetWebAuthnObject(c.Ctx.Request.Host)
|
||||
sessionObj := c.GetSession("authentication")
|
||||
sessionData, ok := sessionObj.(webauthn.SessionData)
|
||||
@ -138,5 +140,11 @@ func (c *ApiController) WebAuthnSigninFinish() {
|
||||
}
|
||||
c.SetSessionUsername(userId)
|
||||
util.LogInfo(c.Ctx, "API: [%s] signed in", userId)
|
||||
c.ResponseOk(userId)
|
||||
|
||||
application := object.GetApplicationByUser(user)
|
||||
var form RequestForm
|
||||
form.Type = responseType
|
||||
resp := c.HandleLoggedIn(application, user, &form)
|
||||
c.Data["json"] = resp
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ package controllers
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/astaxie/beego/utils/pagination"
|
||||
"github.com/beego/beego/utils/pagination"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
2
go.mod
2
go.mod
@ -5,8 +5,8 @@ go 1.16
|
||||
require (
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
|
||||
github.com/astaxie/beego v1.12.3
|
||||
github.com/aws/aws-sdk-go v1.44.4
|
||||
github.com/beego/beego v1.12.11
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/casbin/casbin/v2 v2.30.1
|
||||
github.com/casbin/xorm-adapter/v3 v3.0.1
|
||||
|
17
go.sum
17
go.sum
@ -74,13 +74,13 @@ github.com/aliyun/alibaba-cloud-sdk-go v1.61.1075/go.mod h1:pUKYbK5JQ+1Dfxk80P0q
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/astaxie/beego v1.12.3 h1:SAQkdD2ePye+v8Gn1r4X6IKZM1wd28EyUOVQ3PDSOOQ=
|
||||
github.com/astaxie/beego v1.12.3/go.mod h1:p3qIm0Ryx7zeBHLljmd7omloyca1s4yu1a8kM1FkpIA=
|
||||
github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
|
||||
github.com/aws/aws-sdk-go v1.44.4 h1:ePN0CVJMdiz2vYUcJH96eyxRrtKGSDMgyhP6rah2OgE=
|
||||
github.com/aws/aws-sdk-go v1.44.4/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/beego/beego v1.12.11 h1:MWKcnpavb7iAIS0m6uuEq6pHKkYvGNw/5umIUKqL7jM=
|
||||
github.com/beego/beego v1.12.11/go.mod h1:QURFL1HldOcCZAxnc1cZ7wrplsYR5dKPHFjmk6WkLAs=
|
||||
github.com/beego/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
|
||||
github.com/beego/x2j v0.0.0-20131220205130-a0352aadc542/go.mod h1:kSeGC/p1AbBiEp5kat81+DSQrZenVBZXklMLaELspWU=
|
||||
github.com/beevik/etree v1.1.0 h1:T0xke/WvNtMoCqgzPhkX2r4rjY3GDZFi+FjpRZY2Jbs=
|
||||
@ -115,9 +115,9 @@ github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7 h1:Puu1hUwfps3+1C
|
||||
github.com/cloudflare/cfssl v0.0.0-20190726000631-633726f6bcb7/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20200519150804-63f3cdb75e0d/go.mod h1:TWI8EKQMs5u5jLKW/tsb9VwauIrMIxQG1r5fMsswK5U=
|
||||
github.com/couchbase/gomemcached v0.0.0-20200526233749-ec430f949808/go.mod h1:srVSlQLB8iXBVXHgnqemxUXqN6FCvClgCMPCsjBDR7c=
|
||||
github.com/couchbase/goutils v0.0.0-20180530154633-e865a1461c8a/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/couchbase/go-couchbase v0.0.0-20201216133707-c04035124b17/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
|
||||
github.com/couchbase/gomemcached v0.1.2-0.20201224031647-c432ccf49f32/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo=
|
||||
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -341,7 +341,6 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/pelletier/go-toml v1.0.1/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/peterh/liner v1.0.1-0.20171122030339-3681c2a91233/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -412,7 +411,6 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/syndtr/goleveldb v0.0.0-20160425020131-cfa635847112/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/syndtr/goleveldb v0.0.0-20181127023241-353a9fca669c/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/tealeg/xlsx v1.0.5 h1:+f8oFmvY8Gw1iUXzPk+kz+4GpbDZPK1FhPiQRd+ypgE=
|
||||
@ -430,7 +428,7 @@ github.com/twilio/twilio-go v0.26.0/go.mod h1:lz62Hopu4vicpQ056H5TJ0JE4AP0rS3sQ3
|
||||
github.com/ugorji/go v0.0.0-20171122102828-84cb69a8af83/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.19 h1:jJp+aJgK0e//rZ9I0K2Y7ufJwvuZRo/AQsYDynXMNgA=
|
||||
github.com/volcengine/volc-sdk-golang v1.0.19/go.mod h1:+GGi447k4p1I5PNdbpG2GLaF0Ui9vIInTojMM0IfSS4=
|
||||
github.com/wendal/errors v0.0.0-20130201093226-f66c77a7882b/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
github.com/wendal/errors v0.0.0-20181209125328-7f31f4b264ec/go.mod h1:Q12BUT7DqIlHRmgv3RskH+UCM/4eqVMgI0EMmlSpAXc=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -458,6 +456,7 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
@ -566,6 +565,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -597,6 +597,7 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
6
main.go
6
main.go
@ -18,9 +18,9 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/logs"
|
||||
_ "github.com/astaxie/beego/session/redis"
|
||||
"github.com/beego/beego"
|
||||
"github.com/beego/beego/logs"
|
||||
_ "github.com/beego/beego/session/redis"
|
||||
"github.com/casdoor/casdoor/authz"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/controllers"
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/beego/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
_ "github.com/denisenkom/go-mssqldb" // db = mssql
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/beego/beego"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
goldap "github.com/go-ldap/ldap/v3"
|
||||
"github.com/thanhpk/randstr"
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/beego/beego/logs"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -127,6 +127,11 @@ func UploadFileSafe(provider *Provider, fullFilePath string, fileBuffer *bytes.B
|
||||
}
|
||||
|
||||
func DeleteFile(provider *Provider, objectKey string) error {
|
||||
// check fullFilePath is there security issue
|
||||
if strings.Contains(objectKey, "..") {
|
||||
return fmt.Errorf("the objectKey: %s is not allowed", objectKey)
|
||||
}
|
||||
|
||||
endpoint := getProviderEndpoint(provider)
|
||||
storageProvider := storage.GetStorageProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.RegionId, provider.Bucket, endpoint)
|
||||
if storageProvider == nil {
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/authz"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package routers
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package routers
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ package routers
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -20,7 +20,7 @@
|
||||
package routers
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/beego/beego"
|
||||
|
||||
"github.com/casdoor/casdoor/controllers"
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
@ -19,8 +19,8 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/beego/beego/context"
|
||||
"github.com/beego/beego/logs"
|
||||
)
|
||||
|
||||
func GetIPInfo(clientIP string) string {
|
||||
|
@ -17,7 +17,7 @@ package util
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/beego/beego/logs"
|
||||
)
|
||||
|
||||
func SafeGoroutine(fn func()) {
|
||||
|
@ -43,7 +43,7 @@ module.exports = {
|
||||
options: {
|
||||
lessLoaderOptions: {
|
||||
lessOptions: {
|
||||
modifyVars: {"@primary-color": "rgb(45,120,213)"},
|
||||
modifyVars: {"@primary-color": "rgb(89,54,213)", "@border-radius-base": "5px"},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
|
@ -610,7 +610,7 @@ class App extends Component {
|
||||
// theme="dark"
|
||||
mode={(Setting.isMobile() && this.isStartPages()) ? "inline" : "horizontal"}
|
||||
selectedKeys={[`${this.state.selectedMenuKey}`]}
|
||||
style={{lineHeight: "64px", width: "80%", position: "absolute", left: "145px"}}
|
||||
style={{lineHeight: "64px", width: "78%", position: "absolute", left: "145px"}}
|
||||
>
|
||||
{
|
||||
this.renderMenu()
|
||||
@ -682,7 +682,7 @@ class App extends Component {
|
||||
textAlign: "center",
|
||||
}
|
||||
}>
|
||||
Made with <span style={{color: "rgb(255, 255, 255)"}}>❤️</span> by <a style={{fontWeight: "bold", color: "black"}} target="_blank" href="https://casdoor.org" rel="noreferrer">Casdoor</a>
|
||||
Powered by <a target="_blank" href="https://casdoor.org" rel="noreferrer"><img style={{paddingBottom: "3px"}} height={"20px"} alt={"Casdoor"} src={`${Setting.StaticBaseUrl}/img/casdoor-logo_1185x256.png`} /></a>
|
||||
</Footer>
|
||||
</>
|
||||
);
|
||||
|
@ -28,7 +28,7 @@
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
#root{
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@ -59,11 +59,18 @@
|
||||
height: 70px; /* Footer height */
|
||||
}
|
||||
|
||||
#language-box-corner {
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.language_box {
|
||||
background: url("@{StaticBaseUrl}/img/muti_language.svg");
|
||||
background-size: 25px, 25px;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
border-radius: 5px;
|
||||
width: 45px;
|
||||
height: 65px;
|
||||
float: right;
|
||||
@ -87,9 +94,19 @@
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.login-content{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.loginBackground {
|
||||
height: 100%;
|
||||
background: #ffffff no-repeat;
|
||||
background: #fff no-repeat;
|
||||
background-size: 100% 100%;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
@ -37,8 +37,8 @@ class SelectLanguageBox extends React.Component {
|
||||
Setting.changeLanguage(e.key);
|
||||
}}>
|
||||
<Menu.Item key="en" icon={flagIcon("US", "English")}>English</Menu.Item>
|
||||
<Menu.Item key="es" icon={flagIcon("ES", "Español")}>Español</Menu.Item>
|
||||
<Menu.Item key="zh" icon={flagIcon("CN", "简体中文")}>简体中文</Menu.Item>
|
||||
<Menu.Item key="es" icon={flagIcon("ES", "Español")}>Español</Menu.Item>
|
||||
<Menu.Item key="fr" icon={flagIcon("FR", "Français")}>Français</Menu.Item>
|
||||
<Menu.Item key="de" icon={flagIcon("DE", "Deutsch")}>Deutsch</Menu.Item>
|
||||
<Menu.Item key="ja" icon={flagIcon("JP", "日本語")}>日本語</Menu.Item>
|
||||
@ -49,7 +49,7 @@ class SelectLanguageBox extends React.Component {
|
||||
|
||||
return (
|
||||
<Dropdown overlay={menu} >
|
||||
<div className="language_box" />
|
||||
<div className="language_box" id={this.props.id} style={this.props.style} />
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
|
@ -127,8 +127,12 @@ class UserEditPage extends React.Component {
|
||||
this.getUser();
|
||||
}
|
||||
|
||||
isSelf() {
|
||||
return (this.state.user.id === this.props.account?.id);
|
||||
}
|
||||
|
||||
isSelfOrAdmin() {
|
||||
return (this.state.user.id === this.props.account?.id) || Setting.isAdminUser(this.props.account);
|
||||
return this.isSelf() || Setting.isAdminUser(this.props.account);
|
||||
}
|
||||
|
||||
renderAccountItem(accountItem) {
|
||||
@ -136,7 +140,6 @@ class UserEditPage extends React.Component {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isSelf = this.state.user.id === this.props.account?.id;
|
||||
const isAdmin = Setting.isAdminUser(this.props.account);
|
||||
|
||||
// return (
|
||||
@ -148,7 +151,7 @@ class UserEditPage extends React.Component {
|
||||
// )
|
||||
|
||||
if (accountItem.viewRule === "Self") {
|
||||
if (!isSelf && !isAdmin) {
|
||||
if (!this.isSelfOrAdmin()) {
|
||||
return null;
|
||||
}
|
||||
} else if (accountItem.viewRule === "Admin") {
|
||||
@ -159,7 +162,7 @@ class UserEditPage extends React.Component {
|
||||
|
||||
let disabled = false;
|
||||
if (accountItem.modifyRule === "Self") {
|
||||
if (!isSelf && !isAdmin) {
|
||||
if (!this.isSelfOrAdmin()) {
|
||||
disabled = true;
|
||||
}
|
||||
} else if (accountItem.modifyRule === "Admin") {
|
||||
@ -296,7 +299,11 @@ class UserEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
<Col span={11} >
|
||||
{this.state.user.id === this.props.account?.id ? (<ResetModal application={this.state.application} disabled={disabled} buttonText={i18next.t("user:Reset Email...")} destType={"email"} />) : null}
|
||||
{
|
||||
!this.isSelf() ? null : (
|
||||
<ResetModal application={this.state.application} disabled={disabled} buttonText={i18next.t("user:Reset Email...")} destType={"email"} />
|
||||
)
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
@ -556,7 +563,7 @@ class UserEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("user:WebAuthn credentials"), i18next.t("user:WebAuthn credentials"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<WebAuthnCredentialTable table={this.state.user.webauthnCredentials} updateTable={(table) => {this.updateUserField("webauthnCredentials", table);}} refresh={this.getUser.bind(this)} />
|
||||
<WebAuthnCredentialTable isSelf={this.isSelf()} table={this.state.user.webauthnCredentials} updateTable={(table) => {this.updateUserField("webauthnCredentials", table);}} refresh={this.getUser.bind(this)} />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
@ -19,40 +19,6 @@ import * as UserWebauthnBackend from "./backend/UserWebauthnBackend";
|
||||
import * as Setting from "./Setting";
|
||||
|
||||
class WebAuthnCredentialTable extends React.Component {
|
||||
render() {
|
||||
const columns = [
|
||||
{
|
||||
title: i18next.t("user:WebAuthn credentials"),
|
||||
dataIndex: "ID",
|
||||
key: "ID",
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Action"),
|
||||
key: "action",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Button style={{marginTop: "5px", marginBottom: "5px", marginRight: "5px"}} type="danger" onClick={() => {this.deleteRow(this.props.table, index);}}>
|
||||
{i18next.t("general:Delete")}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Table scroll={{x: "max-content"}} rowKey={"ID"} columns={columns} dataSource={this.props.table} size="middle" bordered pagination={false}
|
||||
title={() => (
|
||||
<div>
|
||||
{i18next.t("user:WebAuthn credentials")}
|
||||
<Button style={{marginRight: "5px"}} type="primary" size="small" onClick={() => {this.registerWebAuthn();}}>
|
||||
{i18next.t("general:Add")}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
deleteRow(table, i) {
|
||||
table = Setting.deleteRow(table, i);
|
||||
this.props.updateTable(table);
|
||||
@ -71,6 +37,41 @@ class WebAuthnCredentialTable extends React.Component {
|
||||
Setting.showMessage("error", `Failed to connect to server: ${error}`);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const columns = [
|
||||
{
|
||||
title: i18next.t("general:Name"),
|
||||
dataIndex: "ID",
|
||||
key: "ID",
|
||||
},
|
||||
{
|
||||
title: i18next.t("general:Action"),
|
||||
key: "action",
|
||||
width: "170px",
|
||||
render: (text, record, index) => {
|
||||
return (
|
||||
<Button style={{marginTop: "5px", marginBottom: "5px", marginRight: "5px"}} type="danger" onClick={() => {this.deleteRow(this.props.table, index);}}>
|
||||
{i18next.t("general:Delete")}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Table rowKey={"ID"} columns={columns} dataSource={this.props.table} size="middle" bordered pagination={false}
|
||||
title={() => (
|
||||
<div>
|
||||
{i18next.t("user:WebAuthn credentials")}
|
||||
<Button disabled={!this.props.isSelf} style={{marginRight: "5px"}} type="primary" size="small" onClick={() => {this.registerWebAuthn();}}>
|
||||
{i18next.t("general:Add")}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default WebAuthnCredentialTable;
|
||||
|
@ -37,7 +37,7 @@ export function getEmailAndPhone(values) {
|
||||
}).then((res) => res.json());
|
||||
}
|
||||
|
||||
function oAuthParamsToQuery(oAuthParams) {
|
||||
export function oAuthParamsToQuery(oAuthParams) {
|
||||
// login
|
||||
if (oAuthParams === null) {
|
||||
return "";
|
||||
|
@ -28,6 +28,7 @@ import SelfLoginButton from "./SelfLoginButton";
|
||||
import i18next from "i18next";
|
||||
import CustomGithubCorner from "../CustomGithubCorner";
|
||||
import {CountDownInput} from "../common/CountDownInput";
|
||||
import SelectLanguageBox from "../SelectLanguageBox";
|
||||
|
||||
const {TabPane} = Tabs;
|
||||
|
||||
@ -41,7 +42,6 @@ class LoginPage extends React.Component {
|
||||
owner: props.owner !== undefined ? props.owner : (props.match === undefined ? null : props.match.params.owner),
|
||||
application: null,
|
||||
mode: props.mode !== undefined ? props.mode : (props.match === undefined ? null : props.match.params.mode), // "signup" or "signin"
|
||||
isCodeSignin: false,
|
||||
msg: null,
|
||||
username: null,
|
||||
validEmailOrPhone: false,
|
||||
@ -269,23 +269,6 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
getSamlUrl(provider) {
|
||||
const params = new URLSearchParams(this.props.location.search);
|
||||
const clientId = params.get("client_id");
|
||||
const application = params.get("state");
|
||||
const realRedirectUri = params.get("redirect_uri");
|
||||
const redirectUri = `${window.location.origin}/callback/saml`;
|
||||
const providerName = provider.name;
|
||||
const relayState = `${clientId}&${application}&${providerName}&${realRedirectUri}&${redirectUri}`;
|
||||
AuthBackend.getSamlLogin(`${provider.owner}/${providerName}`, btoa(relayState)).then((res) => {
|
||||
if (res.data2 === "POST") {
|
||||
document.write(res.data);
|
||||
} else {
|
||||
window.location.href = res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
isProviderVisible(providerItem) {
|
||||
if (this.state.mode === "signup") {
|
||||
return Setting.isProviderVisibleForSignUp(providerItem);
|
||||
@ -366,7 +349,7 @@ class LoginPage extends React.Component {
|
||||
},
|
||||
{
|
||||
validator: (_, value) => {
|
||||
if (this.state.isCodeSignin) {
|
||||
if (this.state.loginMethod === "verificationCode") {
|
||||
if (this.state.email !== "" && !Setting.isValidEmail(this.state.username) && !Setting.isValidPhone(this.state.username)) {
|
||||
this.setState({validEmailOrPhone: false});
|
||||
return Promise.reject(i18next.t("login:The input is not valid Email or Phone!"));
|
||||
@ -389,7 +372,7 @@ class LoginPage extends React.Component {
|
||||
<Input
|
||||
id = "input"
|
||||
prefix={<UserOutlined className="site-form-item-icon" />}
|
||||
placeholder={this.state.isCodeSignin ? i18next.t("login:Email or phone") : i18next.t("login:username, Email or phone")}
|
||||
placeholder={(this.state.loginMethod === "verificationCode") ? i18next.t("login:Email or phone") : i18next.t("login:username, Email or phone")}
|
||||
disabled={!application.enablePassword}
|
||||
onChange={e => {
|
||||
this.setState({
|
||||
@ -416,29 +399,17 @@ class LoginPage extends React.Component {
|
||||
</a>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{
|
||||
this.state.loginMethod === "password" ?
|
||||
(
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
style={{width: "100%", marginBottom: "5px"}}
|
||||
disabled={!application.enablePassword}
|
||||
>
|
||||
{i18next.t("login:Sign In")}
|
||||
</Button>
|
||||
) :
|
||||
(
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
style={{width: "100%", marginBottom: "5px"}}
|
||||
disabled={!application.enablePassword}
|
||||
>
|
||||
{i18next.t("login:Sign in with WebAuthn")}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
<Button
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
style={{width: "100%", marginBottom: "5px"}}
|
||||
disabled={!application.enablePassword}
|
||||
>
|
||||
{
|
||||
this.state.loginMethod === "webAuthn" ? i18next.t("login:Sign in with WebAuthn") :
|
||||
i18next.t("login:Sign In")
|
||||
}
|
||||
</Button>
|
||||
{
|
||||
this.renderFooter(application)
|
||||
}
|
||||
@ -446,7 +417,7 @@ class LoginPage extends React.Component {
|
||||
<Form.Item>
|
||||
{
|
||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small");
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small", this.props.location);
|
||||
})
|
||||
}
|
||||
</Form.Item>
|
||||
@ -467,7 +438,7 @@ class LoginPage extends React.Component {
|
||||
<br />
|
||||
{
|
||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 40, 10, "big");
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 40, 10, "big", this.props.location);
|
||||
})
|
||||
}
|
||||
<div>
|
||||
@ -496,19 +467,6 @@ class LoginPage extends React.Component {
|
||||
} else {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<span style={{float: "left"}}>
|
||||
{
|
||||
!application.enableCodeSignin ? null : (
|
||||
<a onClick={() => {
|
||||
this.setState({
|
||||
isCodeSignin: !this.state.isCodeSignin,
|
||||
});
|
||||
}}>
|
||||
{this.state.isCodeSignin ? i18next.t("login:Sign in with password") : i18next.t("login:Sign in with code")}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
</span>
|
||||
<span style={{float: "right"}}>
|
||||
{
|
||||
!application.enableSignUp ? null : (
|
||||
@ -529,14 +487,19 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
sendSilentSigninData(data) {
|
||||
if (Setting.inIframe()) {
|
||||
const message = {tag: "Casdoor", type: "SilentSignin", data: data};
|
||||
window.parent.postMessage(message, "*");
|
||||
}
|
||||
}
|
||||
|
||||
renderSignedInBox() {
|
||||
if (this.props.account === undefined || this.props.account === null) {
|
||||
if (window !== window.parent) {
|
||||
const message = {tag: "Casdoor", type: "SilentSignin", data: "user-not-logged-in"};
|
||||
window.parent.postMessage(message, "*");
|
||||
}
|
||||
this.sendSilentSigninData("user-not-logged-in");
|
||||
return null;
|
||||
}
|
||||
|
||||
const application = this.getApplicationObj();
|
||||
if (this.props.account.owner !== application.organization) {
|
||||
return null;
|
||||
@ -545,10 +508,7 @@ class LoginPage extends React.Component {
|
||||
const params = new URLSearchParams(this.props.location.search);
|
||||
const silentSignin = params.get("silentSignin");
|
||||
if (silentSignin !== null) {
|
||||
if (window !== window.parent) {
|
||||
const message = {tag: "Casdoor", type: "SilentSignin", data: "signing-in"};
|
||||
window.parent.postMessage(message, "*");
|
||||
}
|
||||
this.sendSilentSigninData("signing-in");
|
||||
|
||||
const values = {};
|
||||
values["application"] = this.state.application.name;
|
||||
@ -614,7 +574,7 @@ class LoginPage extends React.Component {
|
||||
const rawId = assertion.rawId;
|
||||
const sig = assertion.response.signature;
|
||||
const userHandle = assertion.response.userHandle;
|
||||
return fetch(`${Setting.ServerUrl}/api/webauthn/signin/finish`, {
|
||||
return fetch(`${Setting.ServerUrl}/api/webauthn/signin/finish${AuthBackend.oAuthParamsToQuery(oAuthParams)}`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
body: JSON.stringify({
|
||||
@ -654,7 +614,23 @@ class LoginPage extends React.Component {
|
||||
renderPasswordOrCodeInput() {
|
||||
const application = this.getApplicationObj();
|
||||
if (this.state.loginMethod === "password") {
|
||||
return this.state.isCodeSignin ? (
|
||||
return (
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
name="password"
|
||||
rules={[{required: true, message: i18next.t("login:Please input your password!")}]}
|
||||
>
|
||||
<Input.Password
|
||||
prefix={<LockOutlined className="site-form-item-icon" />}
|
||||
type="password"
|
||||
placeholder={i18next.t("login:Password")}
|
||||
disabled={!application.enablePassword}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
);
|
||||
} else if (this.state.loginMethod === "verificationCode") {
|
||||
return (
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
name="code"
|
||||
@ -667,32 +643,29 @@ class LoginPage extends React.Component {
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
) : (
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
name="password"
|
||||
rules={[{required: true, message: i18next.t("login:Please input your password!")}]}
|
||||
>
|
||||
<Input
|
||||
prefix={<LockOutlined className="site-form-item-icon" />}
|
||||
type="password"
|
||||
placeholder={i18next.t("login:Password")}
|
||||
disabled={!application.enablePassword}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
renderMethodChoiceBox() {
|
||||
const application = this.getApplicationObj();
|
||||
if (application.enableWebAuthn) {
|
||||
if (application.enableCodeSignin || application.enableWebAuthn) {
|
||||
return (
|
||||
<div>
|
||||
<Tabs defaultActiveKey="password" onChange={(key) => {this.setState({loginMethod: key});}} centered>
|
||||
<Tabs size={"small"} defaultActiveKey="password" onChange={(key) => {this.setState({loginMethod: key});}} centered>
|
||||
<TabPane tab={i18next.t("login:Password")} key="password" />
|
||||
<TabPane tab={"WebAuthn"} key="webAuthn" />
|
||||
{
|
||||
!application.enableCodeSignin ? null : (
|
||||
<TabPane tab={i18next.t("login:Verification Code")} key="verificationCode" />
|
||||
)
|
||||
}
|
||||
{
|
||||
!application.enableWebAuthn ? null : (
|
||||
<TabPane tab={i18next.t("login:WebAuthn")} key="webAuthn" />
|
||||
)
|
||||
}
|
||||
</Tabs>
|
||||
</div>
|
||||
);
|
||||
@ -726,27 +699,29 @@ class LoginPage extends React.Component {
|
||||
return (
|
||||
<div className="loginBackground" style={{backgroundImage: Setting.inIframe() || Setting.isMobile() ? null : `url(${application.formBackgroundUrl})`}}>
|
||||
<CustomGithubCorner />
|
||||
<Row >
|
||||
<Row>
|
||||
<Col span={8} offset={application.formOffset === 0 || Setting.inIframe() || Setting.isMobile() ? 8 : application.formOffset} style={{display: "flex", justifyContent: "center"}}>
|
||||
<div style={{marginTop: "80px", marginBottom: "50px", textAlign: "center", ...formStyle}}>
|
||||
<div>
|
||||
{
|
||||
Setting.renderHelmet(application)
|
||||
}
|
||||
{
|
||||
Setting.renderLogo(application)
|
||||
}
|
||||
{/* {*/}
|
||||
{/* this.state.clientId !== null ? "Redirect" : null*/}
|
||||
{/* }*/}
|
||||
{
|
||||
this.renderSignedInBox()
|
||||
}
|
||||
{
|
||||
this.renderForm(application)
|
||||
}
|
||||
<div className="login-content">
|
||||
<div style={{marginTop: "80px", marginBottom: "50px", textAlign: "center", ...formStyle}}>
|
||||
<SelectLanguageBox id="language-box-corner" style={{top: "80px", right: "5px"}} />
|
||||
<div>
|
||||
{
|
||||
Setting.renderHelmet(application)
|
||||
}
|
||||
{
|
||||
Setting.renderLogo(application)
|
||||
}
|
||||
{/* {*/}
|
||||
{/* this.state.clientId !== null ? "Redirect" : null*/}
|
||||
{/* }*/}
|
||||
{
|
||||
this.renderSignedInBox()
|
||||
}
|
||||
{
|
||||
this.renderForm(application)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -39,6 +39,7 @@ import SteamLoginButton from "./SteamLoginButton";
|
||||
import BilibiliLoginButton from "./BilibiliLoginButton";
|
||||
import OktaLoginButton from "./OktaLoginButton";
|
||||
import DouyinLoginButton from "./DouyinLoginButton";
|
||||
import * as AuthBackend from "./AuthBackend";
|
||||
|
||||
function getSigninButton(type) {
|
||||
const text = i18next.t("login:Sign in with {type}").replace("{type}", type);
|
||||
@ -95,7 +96,24 @@ function getSigninButton(type) {
|
||||
return text;
|
||||
}
|
||||
|
||||
export function renderProviderLogo(provider, application, width, margin, size) {
|
||||
function getSamlUrl(provider, location) {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const clientId = params.get("client_id");
|
||||
const application = params.get("state");
|
||||
const realRedirectUri = params.get("redirect_uri");
|
||||
const redirectUri = `${window.location.origin}/callback/saml`;
|
||||
const providerName = provider.name;
|
||||
const relayState = `${clientId}&${application}&${providerName}&${realRedirectUri}&${redirectUri}`;
|
||||
AuthBackend.getSamlLogin(`${provider.owner}/${providerName}`, btoa(relayState)).then((res) => {
|
||||
if (res.data2 === "POST") {
|
||||
document.write(res.data);
|
||||
} else {
|
||||
window.location.href = res.data;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function renderProviderLogo(provider, application, width, margin, size, location) {
|
||||
if (size === "small") {
|
||||
if (provider.category === "OAuth") {
|
||||
return (
|
||||
@ -105,7 +123,7 @@ export function renderProviderLogo(provider, application, width, margin, size) {
|
||||
);
|
||||
} else if (provider.category === "SAML") {
|
||||
return (
|
||||
<a key={provider.displayName} onClick={this.getSamlUrl.bind(this, provider)}>
|
||||
<a key={provider.displayName} onClick={() => getSamlUrl(provider, location)}>
|
||||
<img width={width} height={width} src={getProviderLogoURL(provider)} alt={provider.displayName} style={{margin: margin}} />
|
||||
</a>
|
||||
);
|
||||
|
@ -51,7 +51,7 @@ class SamlCallback extends React.Component {
|
||||
const samlResponse = params.get("samlResponse");
|
||||
const messages = atob(relayState).split("&");
|
||||
const clientId = messages[0];
|
||||
const applicationName = messages[1] === "null" ? "app-built-in" : messages[1];
|
||||
const applicationName = (messages[1] === "null" || messages[1] === "undefined") ? "app-built-in" : messages[1];
|
||||
const providerName = messages[2];
|
||||
const redirectUri = messages[3];
|
||||
const responseType = this.getResponseType(redirectUri);
|
||||
|
@ -25,6 +25,7 @@ import * as ApplicationBackend from "../backend/ApplicationBackend";
|
||||
import {CountDownInput} from "../common/CountDownInput";
|
||||
import SelectRegionBox from "../SelectRegionBox";
|
||||
import CustomGithubCorner from "../CustomGithubCorner";
|
||||
import SelectLanguageBox from "../SelectLanguageBox";
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
@ -595,7 +596,7 @@ class SignupPage extends React.Component {
|
||||
</Form.Item>
|
||||
{
|
||||
application.providers.filter(providerItem => this.isProviderVisible(providerItem)).map(providerItem => {
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small");
|
||||
return ProviderButton.renderProviderLogo(providerItem.provider, application, 30, 5, "small", this.props.location);
|
||||
})
|
||||
}
|
||||
</Form>
|
||||
@ -622,16 +623,19 @@ class SignupPage extends React.Component {
|
||||
|
||||
<Row>
|
||||
<Col span={8} offset={application.formOffset === 0 || Setting.inIframe() || Setting.isMobile() ? 8 : application.formOffset} style={{display: "flex", justifyContent: "center"}} >
|
||||
<div style={{marginBottom: "10px", textAlign: "center", ...formStyle}}>
|
||||
{
|
||||
Setting.renderHelmet(application)
|
||||
}
|
||||
{
|
||||
Setting.renderLogo(application)
|
||||
}
|
||||
{
|
||||
this.renderForm(application)
|
||||
}
|
||||
<div className="login-content">
|
||||
<div style={{marginBottom: "10px", textAlign: "center", ...formStyle}}>
|
||||
<SelectLanguageBox id="language-box-corner" style={{top: "3px", right: "5px"}} />
|
||||
{
|
||||
Setting.renderHelmet(application)
|
||||
}
|
||||
{
|
||||
Setting.renderLogo(application)
|
||||
}
|
||||
{
|
||||
this.renderForm(application)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -87,7 +87,7 @@ export const CaptchaPreview = ({
|
||||
backgroundRepeat: "no-repeat",
|
||||
height: "80px",
|
||||
width: "200px",
|
||||
borderRadius: "3px",
|
||||
borderRadius: "5px",
|
||||
border: "1px solid #ccc",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
|
@ -101,7 +101,7 @@ export const CountDownInput = (props) => {
|
||||
backgroundRepeat: "no-repeat",
|
||||
height: "80px",
|
||||
width: "200px",
|
||||
borderRadius: "3px",
|
||||
borderRadius: "5px",
|
||||
border: "1px solid #ccc",
|
||||
marginBottom: 10,
|
||||
}}
|
||||
|
@ -277,12 +277,12 @@
|
||||
"Please input your username, Email or phone!": "Bitte geben Sie Ihren Benutzernamen, E-Mail oder Telefon ein!",
|
||||
"Sign In": "Anmelden",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with code": "Mit Code anmelden",
|
||||
"Sign in with password": "Mit Passwort anmelden",
|
||||
"Sign in with {type}": "Mit {type} anmelden",
|
||||
"Signing in...": "Anmelden...",
|
||||
"The input is not valid Email or Phone!": "Die Eingabe ist keine gültige E-Mail oder Telefon!",
|
||||
"To access": "Zu Zugriff",
|
||||
"Verification Code": "Verification Code",
|
||||
"WebAuthn": "WebAuthn",
|
||||
"sign up now": "jetzt anmelden",
|
||||
"username, Email or phone": "Benutzername, E-Mail oder Telefon"
|
||||
},
|
||||
|
@ -277,12 +277,12 @@
|
||||
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
|
||||
"Sign In": "Sign In",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with code": "Sign in with code",
|
||||
"Sign in with password": "Sign in with password",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signing in...": "Signing in...",
|
||||
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!",
|
||||
"To access": "To access",
|
||||
"Verification Code": "Verification Code",
|
||||
"WebAuthn": "WebAuthn",
|
||||
"sign up now": "sign up now",
|
||||
"username, Email or phone": "username, Email or phone"
|
||||
},
|
||||
|
@ -277,12 +277,12 @@
|
||||
"Please input your username, Email or phone!": "Veuillez entrer votre nom d'utilisateur, votre e-mail ou votre téléphone!",
|
||||
"Sign In": "Se connecter",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with code": "Se connecter avec le code",
|
||||
"Sign in with password": "Se connecter avec le mot de passe",
|
||||
"Sign in with {type}": "Se connecter avec {type}",
|
||||
"Signing in...": "Connexion en cours...",
|
||||
"The input is not valid Email or Phone!": "L'entrée n'est pas valide Email ou Téléphone !",
|
||||
"To access": "Pour accéder à",
|
||||
"Verification Code": "Verification Code",
|
||||
"WebAuthn": "WebAuthn",
|
||||
"sign up now": "inscrivez-vous maintenant",
|
||||
"username, Email or phone": "nom d'utilisateur, e-mail ou téléphone"
|
||||
},
|
||||
|
@ -277,12 +277,12 @@
|
||||
"Please input your username, Email or phone!": "ユーザー名、メールアドレスまたは電話番号を入力してください。",
|
||||
"Sign In": "サインイン",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with code": "コードでサインイン",
|
||||
"Sign in with password": "パスワードでサインイン",
|
||||
"Sign in with {type}": "{type} でサインイン",
|
||||
"Signing in...": "サインイン中...",
|
||||
"The input is not valid Email or Phone!": "入力されたメールアドレスまたは電話番号が正しくありません。",
|
||||
"To access": "アクセスするには",
|
||||
"Verification Code": "Verification Code",
|
||||
"WebAuthn": "WebAuthn",
|
||||
"sign up now": "今すぐサインアップ",
|
||||
"username, Email or phone": "ユーザー名、メールアドレスまたは電話番号"
|
||||
},
|
||||
|
@ -277,12 +277,12 @@
|
||||
"Please input your username, Email or phone!": "Please input your username, Email or phone!",
|
||||
"Sign In": "Sign In",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with code": "Sign in with code",
|
||||
"Sign in with password": "Sign in with password",
|
||||
"Sign in with {type}": "Sign in with {type}",
|
||||
"Signing in...": "Signing in...",
|
||||
"The input is not valid Email or Phone!": "The input is not valid Email or Phone!",
|
||||
"To access": "To access",
|
||||
"Verification Code": "Verification Code",
|
||||
"WebAuthn": "WebAuthn",
|
||||
"sign up now": "sign up now",
|
||||
"username, Email or phone": "username, Email or phone"
|
||||
},
|
||||
|
@ -277,12 +277,12 @@
|
||||
"Please input your username, Email or phone!": "Пожалуйста, введите ваше имя пользователя, адрес электронной почты или телефон!",
|
||||
"Sign In": "Войти",
|
||||
"Sign in with WebAuthn": "Sign in with WebAuthn",
|
||||
"Sign in with code": "Войти с помощью кода",
|
||||
"Sign in with password": "Войти с помощью пароля",
|
||||
"Sign in with {type}": "Войти с помощью {type}",
|
||||
"Signing in...": "Вход...",
|
||||
"The input is not valid Email or Phone!": "Введен неверный адрес электронной почты или телефон!",
|
||||
"To access": "На доступ",
|
||||
"Verification Code": "Verification Code",
|
||||
"WebAuthn": "WebAuthn",
|
||||
"sign up now": "зарегистрироваться",
|
||||
"username, Email or phone": "имя пользователя, адрес электронной почты или телефон"
|
||||
},
|
||||
|
@ -277,12 +277,12 @@
|
||||
"Please input your username, Email or phone!": "请输入您的用户名、Email或手机号!",
|
||||
"Sign In": "登录",
|
||||
"Sign in with WebAuthn": "WebAuthn登录",
|
||||
"Sign in with code": "验证码登录",
|
||||
"Sign in with password": "密码登录",
|
||||
"Sign in with {type}": "{type}登录",
|
||||
"Signing in...": "正在登录...",
|
||||
"The input is not valid Email or Phone!": "您输入的电子邮箱格式或手机号有误!",
|
||||
"To access": "访问",
|
||||
"Verification Code": "验证码",
|
||||
"WebAuthn": "Web身份验证",
|
||||
"sign up now": "立即注册",
|
||||
"username, Email or phone": "用户名、Email或手机号"
|
||||
},
|
||||
@ -702,7 +702,7 @@
|
||||
"Unlink": "解绑",
|
||||
"Upload (.xlsx)": "上传(.xlsx)",
|
||||
"Upload a photo": "上传头像",
|
||||
"WebAuthn credentials": "WebAuthn credentials",
|
||||
"WebAuthn credentials": "WebAuthn凭据",
|
||||
"input password": "输入密码"
|
||||
},
|
||||
"webhook": {
|
||||
|
Reference in New Issue
Block a user