mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-04 12:00:31 +08:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c5c3a08aa9 | ||
![]() |
8efd964835 | ||
![]() |
5dac87a4c3 | ||
![]() |
49c3266400 | ||
![]() |
39548d5d72 | ||
![]() |
1c949e415e | ||
![]() |
1b840a2e9f | ||
![]() |
c9849d8b55 | ||
![]() |
b747f5e27c | ||
![]() |
8b340105c1 | ||
![]() |
43b1006f11 | ||
![]() |
78efc9c2d0 | ||
![]() |
c4089eacb7 | ||
![]() |
4acba2d493 | ||
![]() |
fc0ca4cceb | ||
![]() |
912d9d0c01 | ||
![]() |
8e48bddf5f |
8
build.sh
8
build.sh
@@ -1,11 +1,11 @@
|
||||
#!/bin/bash
|
||||
#try to connect to google to determine whether user need to use proxy
|
||||
curl www.google.com -o /dev/null --connect-timeout 5
|
||||
curl www.google.com -o /dev/null --connect-timeout 5 2 > /dev/null
|
||||
if [ $? == 0 ]
|
||||
then
|
||||
echo "connect to google.com successed"
|
||||
echo "Successfully connected to Google, no need to use Go proxy"
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o server .
|
||||
else
|
||||
echo "connect to google.com failed"
|
||||
echo "Google is blocked, Go proxy is enabled: GOPROXY=https://goproxy.cn,direct"
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOPROXY=https://goproxy.cn,direct go build -ldflags="-w -s" -o server .
|
||||
fi
|
||||
fi
|
||||
|
@@ -116,7 +116,7 @@ func (c *ApiController) Signup() {
|
||||
return
|
||||
}
|
||||
|
||||
if application.IsSignupItemVisible("Email") && form.Email != "" {
|
||||
if application.IsSignupItemVisible("Email") && application.GetSignupItemRule("Email") != "No verification" && form.Email != "" {
|
||||
checkResult := object.CheckVerificationCode(form.Email, form.EmailCode)
|
||||
if len(checkResult) != 0 {
|
||||
c.ResponseError(fmt.Sprintf("Email: %s", checkResult))
|
||||
|
@@ -133,7 +133,7 @@ func (c *ApiController) HandleLoggedIn(application *object.Application, user *ob
|
||||
// @Param scope query string true "scope"
|
||||
// @Param state query string true "state"
|
||||
// @Success 200 {object} controllers.api_controller.Response The Response object
|
||||
// @router /update-application [get]
|
||||
// @router /get-app-login [get]
|
||||
func (c *ApiController) GetApplicationLogin() {
|
||||
clientId := c.Input().Get("clientId")
|
||||
responseType := c.Input().Get("responseType")
|
||||
|
38
cred/argon2id.go
Normal file
38
cred/argon2id.go
Normal file
@@ -0,0 +1,38 @@
|
||||
// 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 cred
|
||||
|
||||
import "github.com/alexedwards/argon2id"
|
||||
|
||||
type Argon2idCredManager struct{}
|
||||
|
||||
func NewArgon2idCredManager() *Argon2idCredManager {
|
||||
cm := &Argon2idCredManager{}
|
||||
return cm
|
||||
}
|
||||
|
||||
func (cm *Argon2idCredManager) GetHashedPassword(password string, userSalt string, organizationSalt string) string {
|
||||
|
||||
hash, err := argon2id.CreateHash(password, argon2id.DefaultParams)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
func (cm *Argon2idCredManager) IsPasswordCorrect(plainPwd string, hashedPwd string, userSalt string, organizationSalt string) bool {
|
||||
match, _ := argon2id.ComparePasswordAndHash(plainPwd, hashedPwd)
|
||||
return match
|
||||
}
|
@@ -30,6 +30,8 @@ func GetCredManager(passwordType string) CredManager {
|
||||
return NewBcryptCredManager()
|
||||
} else if passwordType == "pbkdf2-salt" {
|
||||
return NewPbkdf2SaltCredManager()
|
||||
} else if passwordType == "argon2id" {
|
||||
return NewArgon2idCredManager()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ services:
|
||||
build:
|
||||
context: ./
|
||||
dockerfile: Dockerfile
|
||||
entrypoint: /bin/sh -c './server --createDatabase=true'
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
|
11
go.mod
11
go.mod
@@ -4,15 +4,15 @@ go 1.16
|
||||
|
||||
require (
|
||||
github.com/RobotsAndPencils/go-saml v0.0.0-20170520135329-fb13cb52a46b
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible // indirect
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
|
||||
github.com/astaxie/beego v1.12.3
|
||||
github.com/aws/aws-sdk-go v1.37.30
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.4
|
||||
github.com/beevik/etree v1.1.0
|
||||
github.com/casbin/casbin/v2 v2.30.1
|
||||
github.com/casbin/xorm-adapter/v2 v2.5.1
|
||||
github.com/casdoor/go-sms-sender v0.2.0
|
||||
github.com/casdoor/goth v1.69.0-FIX1
|
||||
github.com/casdoor/oss v1.2.0
|
||||
github.com/dchest/captcha v0.0.0-20200903113550-03f5f0333e1f
|
||||
github.com/go-gomail/gomail v0.0.0-20160411212932-81ebce5c23df
|
||||
github.com/go-ldap/ldap/v3 v3.3.0
|
||||
@@ -20,12 +20,10 @@ require (
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/jinzhu/configor v1.2.1 // indirect
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/lestrrat-go/jwx v0.9.0
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0
|
||||
github.com/qor/oss v0.0.0-20191031055114-aef9ba66bf76
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/russellhaering/gosaml2 v0.6.0
|
||||
github.com/russellhaering/goxmldsig v1.1.1
|
||||
@@ -35,9 +33,8 @@ require (
|
||||
github.com/tealeg/xlsx v1.0.5
|
||||
github.com/thanhpk/randstr v1.0.4
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
|
71
go.sum
71
go.sum
@@ -35,6 +35,21 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
|
||||
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
|
||||
github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U=
|
||||
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
|
||||
github.com/Azure/azure-storage-blob-go v0.15.0 h1:rXtgp8tN1p29GvpGgfJetavIG0V7OgcSXPpwp3tx6qk=
|
||||
github.com/Azure/azure-storage-blob-go v0.15.0/go.mod h1:vbjsVbX0dlxnRc4FFMPsS9BsJWPcne7GB7onqlPvz58=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
@@ -50,18 +65,20 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387 h1:loy0fjI90vF44BPW4ZYOkE3tDkGTy7yHURusOJimt+I=
|
||||
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387/go.mod h1:GuR5j/NW7AU7tDAQUDGCtpiPxWIOy/c3kiRDnlwiCHc=
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1075 h1:Z0SzZttfYI/raZ5O9WF3cezZJTSW4Yz4Kow9uWdyRwg=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1075/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible h1:Ft+KeWIJxFP76LqgJbvtOA1qBIoC8vGkTV3QeCOeJC4=
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.1.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
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.37.30 h1:fZeVg3QuTkWE/dEvPQbK6AL32+3G9ofJfGFSPS1XLH0=
|
||||
github.com/aws/aws-sdk-go v1.37.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
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/goyaml2 v0.0.0-20130207012346-5545475820dd/go.mod h1:1b+Y/CofkYwXMUU0OhQqGvsY2Bvgr4j6jfT699wyZKQ=
|
||||
@@ -85,6 +102,8 @@ github.com/casdoor/go-sms-sender v0.2.0 h1:52bin4EBOPzOee64s9UK7jxd22FODvT9/+Y/Z
|
||||
github.com/casdoor/go-sms-sender v0.2.0/go.mod h1:fsZsNnALvFIo+HFcE1U/oCQv4ZT42FdglXKMsEm3WSk=
|
||||
github.com/casdoor/goth v1.69.0-FIX1 h1:24Y3tfaJxWGJbxickGe3F9y2c8X1PgsQynhxGXV1f9Q=
|
||||
github.com/casdoor/goth v1.69.0-FIX1/go.mod h1:Om55nRo8CkeDkPSNBbzXW4G5uI28ZUkSk5S69dPek3s=
|
||||
github.com/casdoor/oss v1.2.0 h1:ozLAE+nnNdFQBWbzH8U9spzaO8h8NrB57lBcdyMUUQ8=
|
||||
github.com/casdoor/oss v1.2.0/go.mod h1:qii35VBuxnR/uEuYSKpS0aJ8htQFOcCVsZ4FHgHLuss=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
@@ -113,6 +132,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk=
|
||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/glendc/gopher-json v0.0.0-20170414221815-dc4743023d0c/go.mod h1:Gja1A+xZ9BoviGJNA2E9vFkPjjsl+CoJxSXiQM1UXtw=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||
@@ -130,6 +151,12 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-pay/gopay v1.5.72 h1:3zm64xMBhJBa8rXbm//q5UiGgOa4WO5XYEnU394N2Zw=
|
||||
github.com/go-pay/gopay v1.5.72/go.mod h1:0qOGIJuFW7PKDOjmecwKyW0mgsVImgwB9yPJj0ilpn8=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
@@ -252,6 +279,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ledisdb/ledisdb v0.0.0-20200510135210-d35789ec47e6/go.mod h1:n931TsDuKuq+uX4v1fulaMbA/7ZLLhjc85h7chZGBCQ=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lestrrat-go/jwx v0.9.0 h1:Fnd0EWzTm0kFrBPzE/PEPp9nzllES5buMkksPMjEKpM=
|
||||
github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@@ -262,6 +290,8 @@ github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0
|
||||
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911 h1:erppMjjp69Rertg1zlgRbLJH1u+eCmRPxKjMZ5I8/Ro=
|
||||
github.com/mattermost/xml-roundtrip-validator v0.0.0-20201208211235-fe770d50d911/go.mod h1:qccnGMcpgwcNaBnxqpJpWWUiPNr5H3O8eDgGV9gT5To=
|
||||
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
|
||||
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
@@ -315,8 +345,9 @@ github.com/prometheus/procfs v0.1.3 h1:F0+tqvhOksq22sc6iCHF5WGlWjdwj92p0udFh1VFB
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0 h1:q0y8TPa/sTwtriJPRe8gWL++PuZ+XbOUuvKU+hvtTYs=
|
||||
github.com/qiangmzsx/string-adapter/v2 v2.1.0/go.mod h1:PElPB7b7HnGKTsuADAffFpOQXHqjEGJz1+U1a6yR5wA=
|
||||
github.com/qor/oss v0.0.0-20191031055114-aef9ba66bf76 h1:J2Xj92efYLxPl3BiibgEDEUiMsCBzwTurE/8JjD8CG4=
|
||||
github.com/qor/oss v0.0.0-20191031055114-aef9ba66bf76/go.mod h1:JhtPzUhP5KGtCB2yksmxuYAD4hEWw4qGQJpucjsm3U0=
|
||||
github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk=
|
||||
github.com/qiniu/go-sdk/v7 v7.12.1/go.mod h1:btsaOc8CA3hdVloULfFdDgDc+g4f3TDZEFsDY0BLE+w=
|
||||
github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
@@ -385,6 +416,11 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
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-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954 h1:BkypuErRT9A9I/iljuaG3/zdMjd/J6m8tKKJQtGfSdA=
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -433,6 +469,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -449,9 +486,11 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -468,6 +507,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -482,6 +522,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/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=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -501,24 +542,28 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
|
200
idp/okta.go
Normal file
200
idp/okta.go
Normal file
@@ -0,0 +1,200 @@
|
||||
// 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 idp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
type OktaIdProvider struct {
|
||||
Client *http.Client
|
||||
Config *oauth2.Config
|
||||
Host string
|
||||
}
|
||||
|
||||
func NewOktaIdProvider(clientId string, clientSecret string, redirectUrl string, hostUrl string) *OktaIdProvider {
|
||||
idp := &OktaIdProvider{}
|
||||
|
||||
config := idp.getConfig(hostUrl, clientId, clientSecret, redirectUrl)
|
||||
config.ClientID = clientId
|
||||
config.ClientSecret = clientSecret
|
||||
config.RedirectURL = redirectUrl
|
||||
idp.Config = config
|
||||
idp.Host = hostUrl
|
||||
return idp
|
||||
}
|
||||
|
||||
func (idp *OktaIdProvider) SetHttpClient(client *http.Client) {
|
||||
idp.Client = client
|
||||
}
|
||||
|
||||
func (idp *OktaIdProvider) getConfig(hostUrl string, clientId string, clientSecret string, redirectUrl string) *oauth2.Config {
|
||||
var endpoint = oauth2.Endpoint{
|
||||
TokenURL: fmt.Sprintf("%s/v1/token", hostUrl),
|
||||
AuthURL: fmt.Sprintf("%s/v1/authorize", hostUrl),
|
||||
}
|
||||
|
||||
var config = &oauth2.Config{
|
||||
// openid is required for authentication requests
|
||||
// get more details via: https://developer.okta.com/docs/reference/api/oidc/#reserved-scopes
|
||||
Scopes: []string{"openid", "profile", "email"},
|
||||
Endpoint: endpoint,
|
||||
ClientID: clientId,
|
||||
ClientSecret: clientSecret,
|
||||
RedirectURL: redirectUrl,
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// get more details via: https://developer.okta.com/docs/reference/api/oidc/#token
|
||||
/*
|
||||
{
|
||||
"access_token" : "eyJhbGciOiJSUzI1NiJ9.eyJ2ZXIiOjEsImlzcyI6Imh0dHA6Ly9yYWluLm9rdGExLmNvbToxODAyIiwiaWF0IjoxNDQ5Nj
|
||||
I0MDI2LCJleHAiOjE0NDk2Mjc2MjYsImp0aSI6IlVmU0lURzZCVVNfdHA3N21BTjJxIiwic2NvcGVzIjpbIm9wZW5pZCIsI
|
||||
mVtYWlsIl0sImNsaWVudF9pZCI6InVBYXVub2ZXa2FESnh1a0NGZUJ4IiwidXNlcl9pZCI6IjAwdWlkNEJ4WHc2STZUVjRt
|
||||
MGczIn0.HaBu5oQxdVCIvea88HPgr2O5evqZlCT4UXH4UKhJnZ5px-ArNRqwhxXWhHJisslswjPpMkx1IgrudQIjzGYbtLF
|
||||
jrrg2ueiU5-YfmKuJuD6O2yPWGTsV7X6i7ABT6P-t8PRz_RNbk-U1GXWIEkNnEWbPqYDAm_Ofh7iW0Y8WDA5ez1jbtMvd-o
|
||||
XMvJLctRiACrTMLJQ2e5HkbUFxgXQ_rFPNHJbNSUBDLqdi2rg_ND64DLRlXRY7hupNsvWGo0gF4WEUk8IZeaLjKw8UoIs-E
|
||||
TEwJlAMcvkhoVVOsN5dPAaEKvbyvPC1hUGXb4uuThlwdD3ECJrtwgKqLqcWonNtiw",
|
||||
"token_type" : "Bearer",
|
||||
"expires_in" : 3600,
|
||||
"scope" : "openid email",
|
||||
"refresh_token" : "a9VpZDRCeFh3Nkk2VdY",
|
||||
"id_token" : "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiIwMHVpZDRCeFh3Nkk2VFY0bTBnMyIsImVtYWlsIjoid2VibWFzdGVyQGNsb3VkaXR1ZG
|
||||
UubmV0IiwiZW1haWxfdmVyaWZpZWQiOnRydWUsInZlciI6MSwiaXNzIjoiaHR0cDovL3JhaW4ub2t0YTEuY29tOjE4MDIiLCJsb
|
||||
2dpbiI6ImFkbWluaXN0cmF0b3IxQGNsb3VkaXR1ZGUubmV0IiwiYXVkIjoidUFhdW5vZldrYURKeHVrQ0ZlQngiLCJpYXQiOjE0
|
||||
NDk2MjQwMjYsImV4cCI6MTQ0OTYyNzYyNiwiYW1yIjpbInB3ZCJdLCJqdGkiOiI0ZUFXSk9DTUIzU1g4WGV3RGZWUiIsImF1dGh
|
||||
fdGltZSI6MTQ0OTYyNDAyNiwiYXRfaGFzaCI6ImNwcUtmZFFBNWVIODkxRmY1b0pyX1EifQ.Btw6bUbZhRa89DsBb8KmL9rfhku
|
||||
--_mbNC2pgC8yu8obJnwO12nFBepui9KzbpJhGM91PqJwi_AylE6rp-ehamfnUAO4JL14PkemF45Pn3u_6KKwxJnxcWxLvMuuis
|
||||
nvIs7NScKpOAab6ayZU0VL8W6XAijQmnYTtMWQfSuaaR8rYOaWHrffh3OypvDdrQuYacbkT0csxdrayXfBG3UF5-ZAlhfch1fhF
|
||||
T3yZFdWwzkSDc0BGygfiFyNhCezfyT454wbciSZgrA9ROeHkfPCaX7KCFO8GgQEkGRoQntFBNjluFhNLJIUkEFovEDlfuB4tv_M
|
||||
8BM75celdy3jkpOurg"
|
||||
}
|
||||
*/
|
||||
|
||||
type OktaToken struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
Scope string `json:"scope"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
IdToken string `json:"id_token"`
|
||||
}
|
||||
|
||||
// GetToken use code to get access_token
|
||||
// get more details via: https://developer.okta.com/docs/reference/api/oidc/#token
|
||||
func (idp *OktaIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
payload := url.Values{}
|
||||
payload.Set("code", code)
|
||||
payload.Set("grant_type", "authorization_code")
|
||||
payload.Set("client_id", idp.Config.ClientID)
|
||||
payload.Set("client_secret", idp.Config.ClientSecret)
|
||||
payload.Set("redirect_uri", idp.Config.RedirectURL)
|
||||
resp, err := idp.Client.PostForm(idp.Config.Endpoint.TokenURL, payload)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pToken := &OktaToken{}
|
||||
err = json.Unmarshal(data, pToken)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fail to unmarshal token response: %s", err.Error())
|
||||
}
|
||||
|
||||
token := &oauth2.Token{
|
||||
AccessToken: pToken.AccessToken,
|
||||
TokenType: "Bearer",
|
||||
RefreshToken: pToken.RefreshToken,
|
||||
Expiry: time.Unix(time.Now().Unix()+int64(pToken.ExpiresIn), 0),
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// get more details via: https://developer.okta.com/docs/reference/api/oidc/#userinfo
|
||||
/*
|
||||
{
|
||||
"sub": "00uid4BxXw6I6TV4m0g3",
|
||||
"name" :"John Doe",
|
||||
"nickname":"Jimmy",
|
||||
"given_name":"John",
|
||||
"middle_name":"James",
|
||||
"family_name":"Doe",
|
||||
"profile":"https://example.com/john.doe",
|
||||
"zoneinfo":"America/Los_Angeles",
|
||||
"locale":"en-US",
|
||||
"updated_at":1311280970,
|
||||
"email":"john.doe@example.com",
|
||||
"email_verified":true,
|
||||
"address" : { "street_address":"123 Hollywood Blvd.", "locality":"Los Angeles", "region":"CA", "postal_code":"90210", "country":"US" },
|
||||
"phone_number":"+1 (425) 555-1212"
|
||||
}
|
||||
*/
|
||||
|
||||
type OktaUserInfo struct {
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
PreferredUsername string `json:"preferred_username"`
|
||||
Picture string `json:"picture"`
|
||||
Sub string `json:"sub"`
|
||||
}
|
||||
|
||||
// GetUserInfo use token to get user profile
|
||||
// get more details via: https://developer.okta.com/docs/reference/api/oidc/#userinfo
|
||||
func (idp *OktaIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
req, err := http.NewRequest("GET", fmt.Sprintf("%s/v1/userinfo", idp.Host), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token.AccessToken))
|
||||
req.Header.Add("Accept", "application/json")
|
||||
resp, err := idp.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var oktaUserInfo OktaUserInfo
|
||||
err = json.Unmarshal(body, &oktaUserInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userInfo := UserInfo{
|
||||
Id: oktaUserInfo.Sub,
|
||||
Username: oktaUserInfo.PreferredUsername,
|
||||
DisplayName: oktaUserInfo.Name,
|
||||
Email: oktaUserInfo.Email,
|
||||
AvatarUrl: oktaUserInfo.Picture,
|
||||
}
|
||||
return &userInfo, nil
|
||||
}
|
@@ -84,6 +84,8 @@ func GetIdProvider(typ string, subType string, clientId string, clientSecret str
|
||||
}
|
||||
} else if typ == "Casdoor" {
|
||||
return NewCasdoorIdProvider(clientId, clientSecret, redirectUrl, hostUrl)
|
||||
} else if typ == "Okta" {
|
||||
return NewOktaIdProvider(clientId, clientSecret, redirectUrl, hostUrl)
|
||||
} else if isGothSupport(typ) {
|
||||
return NewGothIdProvider(typ, clientId, clientSecret, redirectUrl)
|
||||
}
|
||||
|
@@ -257,7 +257,11 @@ func UpdateApplication(id string, application *Application) bool {
|
||||
providerItem.Provider = nil
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(application)
|
||||
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
||||
if application.ClientSecret == "***" {
|
||||
session.Omit("client_secret")
|
||||
}
|
||||
affected, err := session.Update(application)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@@ -109,7 +109,7 @@ func initBuiltInApplication() {
|
||||
{Name: "Display name", Visible: true, Required: true, Prompted: false, Rule: "None"},
|
||||
{Name: "Password", Visible: true, Required: true, Prompted: false, Rule: "None"},
|
||||
{Name: "Confirm password", Visible: true, Required: true, Prompted: false, Rule: "None"},
|
||||
{Name: "Email", Visible: true, Required: true, Prompted: false, Rule: "None"},
|
||||
{Name: "Email", Visible: true, Required: true, Prompted: false, Rule: "Normal"},
|
||||
{Name: "Phone", Visible: true, Required: true, Prompted: false, Rule: "None"},
|
||||
{Name: "Agreement", Visible: true, Required: true, Prompted: false, Rule: "None"},
|
||||
},
|
||||
@@ -147,7 +147,7 @@ func initBuiltInCert() {
|
||||
DisplayName: "Built-in Cert",
|
||||
Scope: "JWT",
|
||||
Type: "x509",
|
||||
CryptoAlgorithm: "RSA",
|
||||
CryptoAlgorithm: "RS256",
|
||||
BitSize: 4096,
|
||||
ExpireInYears: 20,
|
||||
PublicKey: tokenJwtPublicKey,
|
||||
|
@@ -241,6 +241,7 @@ func (l *ldapConn) GetLdapUsers(baseDn string) ([]ldapUser, error) {
|
||||
case "uidNumber":
|
||||
ldapUserItem.UidNumber = attribute.Values[0]
|
||||
case "uid":
|
||||
ldapUserItem.Uid = attribute.Values[0]
|
||||
case "sAMAccountName":
|
||||
ldapUserItem.Uid = attribute.Values[0]
|
||||
case "cn":
|
||||
@@ -248,6 +249,7 @@ func (l *ldapConn) GetLdapUsers(baseDn string) ([]ldapUser, error) {
|
||||
case "gidNumber":
|
||||
ldapUserItem.GidNumber = attribute.Values[0]
|
||||
case "entryUUID":
|
||||
ldapUserItem.Uuid = attribute.Values[0]
|
||||
case "objectGUID":
|
||||
ldapUserItem.Uuid = attribute.Values[0]
|
||||
case "mail":
|
||||
|
@@ -76,7 +76,7 @@ func GetOidcDiscovery(host string) OidcDiscovery {
|
||||
UserinfoEndpoint: fmt.Sprintf("%s/api/userinfo", originBackend),
|
||||
JwksUri: fmt.Sprintf("%s/.well-known/jwks", originBackend),
|
||||
IntrospectionEndpoint: fmt.Sprintf("%s/api/login/oauth/introspect", originBackend),
|
||||
ResponseTypesSupported: []string{"id_token"},
|
||||
ResponseTypesSupported: []string{"code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none"},
|
||||
ResponseModesSupported: []string{"login", "code", "link"},
|
||||
GrantTypesSupported: []string{"password", "authorization_code"},
|
||||
SubjectTypesSupported: []string{"public"},
|
||||
|
@@ -128,7 +128,7 @@ func UpdateOrganization(id string, organization *Organization) bool {
|
||||
}
|
||||
}
|
||||
|
||||
if organization.MasterPassword != "" {
|
||||
if organization.MasterPassword != "" && organization.MasterPassword != "***" {
|
||||
credManager := cred.GetCredManager(organization.PasswordType)
|
||||
if credManager != nil {
|
||||
hashedPassword := credManager.GetHashedPassword(organization.MasterPassword, "", organization.PasswordSalt)
|
||||
@@ -136,7 +136,11 @@ func UpdateOrganization(id string, organization *Organization) bool {
|
||||
}
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(organization)
|
||||
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
||||
if organization.MasterPassword == "***" {
|
||||
session.Omit("master_password")
|
||||
}
|
||||
affected, err := session.Update(organization)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@@ -172,7 +172,14 @@ func UpdateProvider(id string, provider *Provider) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(provider)
|
||||
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
||||
if provider.ClientSecret == "***" {
|
||||
session = session.Omit("client_secret")
|
||||
}
|
||||
if provider.ClientSecret2 == "***" {
|
||||
session = session.Omit("client_secret2")
|
||||
}
|
||||
affected, err := session.Update(provider)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@@ -133,7 +133,11 @@ func UpdateSyncer(id string, syncer *Syncer) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).AllCols().Update(syncer)
|
||||
session := adapter.Engine.ID(core.PK{owner, name}).AllCols()
|
||||
if syncer.Password == "***" {
|
||||
session.Omit("password")
|
||||
}
|
||||
affected, err := session.Update(syncer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@@ -94,6 +94,7 @@ type User struct {
|
||||
AzureAD string `xorm:"azuread varchar(100)" json:"azuread"`
|
||||
Slack string `xorm:"slack varchar(100)" json:"slack"`
|
||||
Steam string `xorm:"steam varchar(100)" json:"steam"`
|
||||
Okta string `xorm:"okta varchar(100)" json:"okta"`
|
||||
Custom string `xorm:"custom varchar(100)" json:"custom"`
|
||||
|
||||
Ldap string `xorm:"ldap varchar(100)" json:"ldap"`
|
||||
@@ -313,6 +314,9 @@ func UpdateUser(id string, user *User, columns []string, isGlobalAdmin bool) boo
|
||||
return false
|
||||
}
|
||||
|
||||
if user.Password == "***" {
|
||||
user.Password = oldUser.Password
|
||||
}
|
||||
user.UpdateUserHash()
|
||||
|
||||
if user.Avatar != oldUser.Avatar && user.Avatar != "" && user.PermanentAvatar != "*" {
|
||||
|
@@ -97,3 +97,14 @@ func TestGetMaskedUsers(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUserByField(t *testing.T) {
|
||||
InitConfig()
|
||||
|
||||
user := GetUserByField("built-in", "DingTalk", "test")
|
||||
if user != nil {
|
||||
t.Logf("%+v", user)
|
||||
} else {
|
||||
t.Log("no user found")
|
||||
}
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ func GetUserByField(organizationName string, field string, value string) *User {
|
||||
}
|
||||
|
||||
user := User{Owner: organizationName}
|
||||
existed, err := adapter.Engine.Where(fmt.Sprintf("%s=?", field), value).Get(&user)
|
||||
existed, err := adapter.Engine.Where(fmt.Sprintf("%s=?", strings.ToLower(field)), value).Get(&user)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@@ -15,8 +15,8 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"github.com/qor/oss"
|
||||
"github.com/qor/oss/aliyun"
|
||||
"github.com/casdoor/oss"
|
||||
"github.com/casdoor/oss/aliyun"
|
||||
)
|
||||
|
||||
func NewAliyunOssStorageProvider(clientId string, clientSecret string, region string, bucket string, endpoint string) oss.StorageInterface {
|
||||
|
@@ -16,8 +16,8 @@ package storage
|
||||
|
||||
import (
|
||||
awss3 "github.com/aws/aws-sdk-go/service/s3"
|
||||
"github.com/qor/oss"
|
||||
"github.com/qor/oss/s3"
|
||||
"github.com/casdoor/oss"
|
||||
"github.com/casdoor/oss/s3"
|
||||
)
|
||||
|
||||
func NewAwsS3StorageProvider(clientId string, clientSecret string, region string, bucket string, endpoint string) oss.StorageInterface {
|
||||
|
31
storage/azure.go
Normal file
31
storage/azure.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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 storage
|
||||
|
||||
import (
|
||||
"github.com/casdoor/oss"
|
||||
"github.com/casdoor/oss/azureblob"
|
||||
)
|
||||
|
||||
func NewAzureBlobStorageProvider(clientId string, clientSecret string, region string, bucket string, endpoint string) oss.StorageInterface {
|
||||
sp := azureblob.New(&azureblob.Config{
|
||||
AccessId: clientId,
|
||||
AccessKey: clientSecret,
|
||||
Region: region,
|
||||
Bucket: bucket,
|
||||
Endpoint: endpoint,
|
||||
})
|
||||
return sp
|
||||
}
|
@@ -20,7 +20,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/qor/oss"
|
||||
"github.com/casdoor/oss"
|
||||
)
|
||||
|
||||
var baseFolder = "files"
|
||||
|
@@ -14,7 +14,7 @@
|
||||
|
||||
package storage
|
||||
|
||||
import "github.com/qor/oss"
|
||||
import "github.com/casdoor/oss"
|
||||
|
||||
func GetStorageProvider(providerType string, clientId string, clientSecret string, region string, bucket string, endpoint string) oss.StorageInterface {
|
||||
switch providerType {
|
||||
@@ -26,6 +26,8 @@ func GetStorageProvider(providerType string, clientId string, clientSecret strin
|
||||
return NewAliyunOssStorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||
case "Tencent Cloud COS":
|
||||
return NewTencentCloudCosStorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||
case "Azure Blob":
|
||||
return NewAzureBlobStorageProvider(clientId, clientSecret, region, bucket, endpoint)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@@ -15,8 +15,8 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"github.com/qor/oss"
|
||||
"github.com/qor/oss/tencent"
|
||||
"github.com/casdoor/oss"
|
||||
"github.com/casdoor/oss/tencent"
|
||||
)
|
||||
|
||||
func NewTencentCloudCosStorageProvider(clientId string, clientSecret string, region string, bucket string, endpoint string) oss.StorageInterface {
|
||||
|
@@ -35,6 +35,7 @@ require('codemirror/theme/material-darker.css');
|
||||
require("codemirror/mode/htmlmixed/htmlmixed");
|
||||
|
||||
const { Option } = Select;
|
||||
const { TextArea } = Input;
|
||||
|
||||
class ApplicationEditPage extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -48,6 +49,7 @@ class ApplicationEditPage extends React.Component {
|
||||
providers: [],
|
||||
uploading: false,
|
||||
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
||||
samlMetadata: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,6 +58,7 @@ class ApplicationEditPage extends React.Component {
|
||||
this.getOrganizations();
|
||||
this.getCerts();
|
||||
this.getProviders();
|
||||
this.getSamlMetadata();
|
||||
}
|
||||
|
||||
getApplication() {
|
||||
@@ -97,6 +100,15 @@ class ApplicationEditPage extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
getSamlMetadata() {
|
||||
ApplicationBackend.getSamlMetadata("admin", this.state.applicationName)
|
||||
.then((res) => {
|
||||
this.setState({
|
||||
samlMetadata: res,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
parseApplicationField(key, value) {
|
||||
if (["expireInHours", "refreshExpireInHours"].includes(key)) {
|
||||
value = Setting.myParseInt(value);
|
||||
@@ -454,12 +466,21 @@ class ApplicationEditPage extends React.Component {
|
||||
{id: "password", name: "Password"},
|
||||
{id: "client_credentials", name: "Client Credentials"},
|
||||
{id: "token", name: "Token"},
|
||||
{id: "id_token",name:"ID Token"},
|
||||
].map((item, index)=><Option key={index} value={item.id}>{item.name}</Option>)
|
||||
{id: "id_token", name: "ID Token"},
|
||||
{id: "refresh_token", name: "Refresh Token"},
|
||||
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("application:SAML metadata"), i18next.t("application:SAML metadata - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22}>
|
||||
<TextArea rows={8} value={this.state.samlMetadata} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:Providers"), i18next.t("general:Providers - Tooltip"))} :
|
||||
|
@@ -43,7 +43,7 @@ class ApplicationListPage extends BaseListPage {
|
||||
{name: "Display name", visible: true, required: true, rule: "None"},
|
||||
{name: "Password", visible: true, required: true, rule: "None"},
|
||||
{name: "Confirm password", visible: true, required: true, rule: "None"},
|
||||
{name: "Email", visible: true, required: true, rule: "None"},
|
||||
{name: "Email", visible: true, required: true, rule: "Normal"},
|
||||
{name: "Phone", visible: true, required: true, rule: "None"},
|
||||
{name: "Agreement", visible: true, required: true, rule: "None"},
|
||||
],
|
||||
|
@@ -136,7 +136,7 @@ class CertEditPage extends React.Component {
|
||||
})}>
|
||||
{
|
||||
[
|
||||
{id: 'RSA', name: 'RSA'},
|
||||
{id: 'RS256', name: 'RS256'},
|
||||
].map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
|
||||
}
|
||||
</Select>
|
||||
|
@@ -32,7 +32,7 @@ class CertListPage extends BaseListPage {
|
||||
displayName: `New Cert - ${randomName}`,
|
||||
scope: "JWT",
|
||||
type: "x509",
|
||||
cryptoAlgorithm: "RSA",
|
||||
cryptoAlgorithm: "RS256",
|
||||
bitSize: 4096,
|
||||
expireInYears: 20,
|
||||
publicKey: "",
|
||||
@@ -131,7 +131,7 @@ class CertListPage extends BaseListPage {
|
||||
key: 'cryptoAlgorithm',
|
||||
filterMultiple: false,
|
||||
filters: [
|
||||
{text: 'RSA', value: 'RSA'},
|
||||
{text: 'RS256', value: 'RS256'},
|
||||
],
|
||||
width: '190px',
|
||||
sorter: true,
|
||||
|
@@ -155,7 +155,7 @@ class OrganizationEditPage extends React.Component {
|
||||
<Col span={22} >
|
||||
<Select virtual={false} style={{width: '100%'}} value={this.state.organization.passwordType} onChange={(value => {this.updateOrganizationField('passwordType', value);})}>
|
||||
{
|
||||
['plain', 'salt', 'md5-salt', 'bcrypt', 'pbkdf2-salt']
|
||||
['plain', 'salt', 'md5-salt', 'bcrypt', 'pbkdf2-salt', 'argon2id']
|
||||
.map((item, index) => <Option key={index} value={item}>{item}</Option>)
|
||||
}
|
||||
</Select>
|
||||
|
@@ -382,7 +382,7 @@ class ProviderEditPage extends React.Component {
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.provider.type !== "Adfs" && this.state.provider.type !== "Casdoor" ? null : (
|
||||
this.state.provider.type !== "Adfs" && this.state.provider.type !== "Casdoor" && this.state.provider.type !== "Okta" ? null : (
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
|
@@ -74,7 +74,7 @@ class ResourceListPage extends BaseListPage {
|
||||
|
||||
renderUpload() {
|
||||
return (
|
||||
<Upload maxCount={1} accept="image/*,video/*,audio/*,.pdf,.doc,.docx" showUploadList={false}
|
||||
<Upload maxCount={1} accept="image/*,video/*,audio/*,.pdf,.doc,.docx,.csv,.xls,.xlsx" showUploadList={false}
|
||||
beforeUpload={file => {return false}} onChange={info => {this.handleUpload(info)}}>
|
||||
<Button icon={<UploadOutlined />} loading={this.state.uploading} type="primary" size="small">
|
||||
{i18next.t("resource:Upload a file...")}
|
||||
|
@@ -74,6 +74,10 @@ export const OtherProviderInfo = {
|
||||
logo: `${StaticBaseUrl}/img/social_tencent_cloud.jpg`,
|
||||
url: "https://cloud.tencent.com/product/cos",
|
||||
},
|
||||
"Azure Blob": {
|
||||
logo: `${StaticBaseUrl}/img/social_azure.jpg`,
|
||||
url: "https://azure.microsoft.com/en-us/services/storage/blobs/"
|
||||
}
|
||||
},
|
||||
SAML: {
|
||||
"Aliyun IDaaS": {
|
||||
@@ -550,6 +554,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: 'AzureAD', name: 'AzureAD'},
|
||||
{id: 'Slack', name: 'Slack'},
|
||||
{id: 'Steam', name: 'Steam'},
|
||||
{id: 'Okta', name: 'Okta'},
|
||||
{id: 'Custom', name: 'Custom'},
|
||||
]
|
||||
);
|
||||
@@ -575,6 +580,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: 'AWS S3', name: 'AWS S3'},
|
||||
{id: 'Aliyun OSS', name: 'Aliyun OSS'},
|
||||
{id: 'Tencent Cloud COS', name: 'Tencent Cloud COS'},
|
||||
{id: 'Azure Blob', name: 'Azure Blob'}
|
||||
]
|
||||
);
|
||||
} else if (category === "SAML") {
|
||||
|
@@ -159,7 +159,7 @@ class SignupTable extends React.Component {
|
||||
title: i18next.t("provider:rule"),
|
||||
dataIndex: 'rule',
|
||||
key: 'rule',
|
||||
width: '120px',
|
||||
width: '155px',
|
||||
render: (text, record, index) => {
|
||||
let options = [];
|
||||
if (record.name === "ID") {
|
||||
@@ -167,12 +167,17 @@ class SignupTable extends React.Component {
|
||||
{id: 'Random', name: 'Random'},
|
||||
{id: 'Incremental', name: 'Incremental'},
|
||||
];
|
||||
} if (record.name === "Display name") {
|
||||
} else if (record.name === "Display name") {
|
||||
options = [
|
||||
{id: 'None', name: 'None'},
|
||||
{id: 'Real name', name: 'Real name'},
|
||||
{id: 'First, last', name: 'First, last'},
|
||||
];
|
||||
} else if (record.name === "Email") {
|
||||
options = [
|
||||
{id: 'Normal', name: 'Normal'},
|
||||
{id: 'No verification', name: 'No verification'},
|
||||
];
|
||||
}
|
||||
|
||||
if (options.length === 0) {
|
||||
|
@@ -43,6 +43,7 @@ import AppleLoginButton from "./AppleLoginButton"
|
||||
import AzureADLoginButton from "./AzureADLoginButton";
|
||||
import SlackLoginButton from "./SlackLoginButton";
|
||||
import SteamLoginButton from "./SteamLoginButton";
|
||||
import OktaLoginButton from "./OktaLoginButton";
|
||||
import CustomGithubCorner from "../CustomGithubCorner";
|
||||
import {CountDownInput} from "../common/CountDownInput";
|
||||
|
||||
@@ -278,6 +279,8 @@ class LoginPage extends React.Component {
|
||||
return <SlackLoginButton text={text} align={"center"} />
|
||||
} else if (type === "Steam") {
|
||||
return <SteamLoginButton text={text} align={"center"} />
|
||||
} else if (type === "Okta") {
|
||||
return <OktaLoginButton text={text} align={"center"} />
|
||||
}
|
||||
|
||||
return text;
|
||||
|
32
web/src/auth/OktaLoginButton.js
Normal file
32
web/src/auth/OktaLoginButton.js
Normal file
@@ -0,0 +1,32 @@
|
||||
// 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.
|
||||
|
||||
import {createButton} from "react-social-login-buttons";
|
||||
import {StaticBaseUrl} from "../Setting";
|
||||
|
||||
function Icon({ width = 24, height = 24, color }) {
|
||||
return <img src={`${StaticBaseUrl}/buttons/okta.svg`} alt="Sign in with Okta" style={{width: 24, height: 24}} />;
|
||||
}
|
||||
|
||||
const config = {
|
||||
text: "Sign in with Okta",
|
||||
icon: Icon,
|
||||
iconFormat: name => `fa fa-${name}`,
|
||||
style: {background: "#ffffff", color: "#000000"},
|
||||
activeStyle: {background: "#ededee"},
|
||||
};
|
||||
|
||||
const OktaLoginButton = createButton(config);
|
||||
|
||||
export default OktaLoginButton;
|
@@ -107,6 +107,10 @@ const authInfo = {
|
||||
Steam: {
|
||||
endpoint: "https://steamcommunity.com/openid/login",
|
||||
},
|
||||
Okta: {
|
||||
scope: "openid%20profile%20email",
|
||||
endpoint: "http://example.com",
|
||||
},
|
||||
Custom: {
|
||||
endpoint: "https://example.com/",
|
||||
},
|
||||
@@ -230,6 +234,8 @@ export function getAuthUrl(application, provider, method) {
|
||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||
} else if (provider.type === "Steam") {
|
||||
return `${endpoint}?openid.claimed_id=http://specs.openid.net/auth/2.0/identifier_select&openid.identity=http://specs.openid.net/auth/2.0/identifier_select&openid.mode=checkid_setup&openid.ns=http://specs.openid.net/auth/2.0&openid.realm=${window.location.origin}&openid.return_to=${redirectUri}?state=${state}`;
|
||||
} else if (provider.type === "Okta") {
|
||||
return `${provider.domain}/v1/authorize?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||
} else if (provider.type === "Custom") {
|
||||
return `${provider.customAuthUrl}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&scope=${provider.customScope}&response_type=code&state=${state}`;
|
||||
}
|
||||
|
@@ -23,6 +23,14 @@ class SelfLoginButton extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
getAccountShowName() {
|
||||
let {name, displayName} = this.props.account;
|
||||
if (displayName !== '') {
|
||||
name += ' (' + displayName + ')';
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
render() {
|
||||
const config = {
|
||||
icon: this.generateIcon(),
|
||||
@@ -32,7 +40,7 @@ class SelfLoginButton extends React.Component {
|
||||
};
|
||||
|
||||
const SelfLoginButton = createButton(config);
|
||||
return <SelfLoginButton text={`${this.props.account.name} (${this.props.account.displayName})`} onClick={() => this.props.onClick()} align={"center"} />
|
||||
return <SelfLoginButton text={this.getAccountShowName()} onClick={() => this.props.onClick()} align={"center"}/>
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -325,20 +325,23 @@ class SignupPage extends React.Component {
|
||||
>
|
||||
<Input onChange={e => this.setState({email: e.target.value})} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="emailCode"
|
||||
key="emailCode"
|
||||
label={i18next.t("code:Email code")}
|
||||
rules={[{
|
||||
required: required,
|
||||
message: i18next.t("code:Please input your verification code!"),
|
||||
}]}
|
||||
>
|
||||
<CountDownInput
|
||||
disabled={!this.state.validEmail}
|
||||
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationOrgName(application)]}
|
||||
/>
|
||||
</Form.Item>
|
||||
{
|
||||
signupItem.rule !== "No verification" &&
|
||||
<Form.Item
|
||||
name="emailCode"
|
||||
key="emailCode"
|
||||
label={i18next.t("code:Email code")}
|
||||
rules={[{
|
||||
required: required,
|
||||
message: i18next.t("code:Please input your verification code!"),
|
||||
}]}
|
||||
>
|
||||
<CountDownInput
|
||||
disabled={!this.state.validEmail}
|
||||
onButtonClickArgs={[this.state.email, "email", Setting.getApplicationOrgName(application)]}
|
||||
/>
|
||||
</Form.Item>
|
||||
}
|
||||
</React.Fragment>
|
||||
)
|
||||
} else if (signupItem.name === "Phone") {
|
||||
|
@@ -69,3 +69,10 @@ export function deleteApplication(application) {
|
||||
body: JSON.stringify(newApplication),
|
||||
}).then(res => res.json());
|
||||
}
|
||||
|
||||
export function getSamlMetadata(owner, name) {
|
||||
return fetch(`${Setting.ServerUrl}/api/saml/metadata?application=${owner}/${encodeURIComponent(name)}`, {
|
||||
method: "GET",
|
||||
credentials: "include"
|
||||
}).then(res => res.text());
|
||||
}
|
||||
|
Reference in New Issue
Block a user