mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-22 11:43:51 +08:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
ade64693e4 | |||
5f8924ed4e | |||
1a6d98d029 | |||
447dd1c534 | |||
86b5d72e5d | |||
6bc4e646e5 | |||
0841eb5c30 | |||
4015c221f7 | |||
dcd6328498 | |||
8080927890 | |||
a95c5b05a9 | |||
865a65d399 | |||
e8b9c67671 |
@ -15,7 +15,6 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casbin/casbin/v2"
|
||||
"github.com/casbin/casbin/v2/model"
|
||||
xormadapter "github.com/casbin/xorm-adapter/v2"
|
||||
@ -28,8 +27,8 @@ var Enforcer *casbin.Enforcer
|
||||
func InitAuthz() {
|
||||
var err error
|
||||
|
||||
tableNamePrefix := beego.AppConfig.String("tableNamePrefix")
|
||||
a, err := xormadapter.NewAdapterWithTableName(beego.AppConfig.String("driverName"), conf.GetBeegoConfDataSourceName()+beego.AppConfig.String("dbName"), "casbin_rule", tableNamePrefix, true)
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
a, err := xormadapter.NewAdapterWithTableName(conf.GetConfigString("driverName"), conf.GetBeegoConfDataSourceName()+conf.GetConfigString("dbName"), "casbin_rule", tableNamePrefix, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
37
conf/conf.go
37
conf/conf.go
@ -15,14 +15,49 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
func GetConfigString(key string) string {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
return value
|
||||
}
|
||||
return beego.AppConfig.String(key)
|
||||
}
|
||||
|
||||
func GetConfigBool(key string) (bool, error) {
|
||||
value := GetConfigString(key)
|
||||
if value == "true" {
|
||||
return true, nil
|
||||
} else if value == "false" {
|
||||
return false, nil
|
||||
}
|
||||
return false, fmt.Errorf("value %s cannot be converted into bool", value)
|
||||
}
|
||||
|
||||
func GetConfigInt64(key string) (int64, error) {
|
||||
value := GetConfigString(key)
|
||||
num, err := strconv.ParseInt(value, 10, 64)
|
||||
return num, err
|
||||
}
|
||||
|
||||
func init() {
|
||||
//this array contains the beego configuration items that may be modified via env
|
||||
var presetConfigItems = []string{"httpport", "appname"}
|
||||
for _, key := range presetConfigItems {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
beego.AppConfig.Set(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetBeegoConfDataSourceName() string {
|
||||
dataSourceName := beego.AppConfig.String("dataSourceName")
|
||||
dataSourceName := GetConfigString("dataSourceName")
|
||||
|
||||
runningInDocker := os.Getenv("RUNNING_IN_DOCKER")
|
||||
if runningInDocker == "true" {
|
||||
|
98
conf/conf_test.go
Normal file
98
conf/conf_test.go
Normal file
@ -0,0 +1,98 @@
|
||||
// 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 conf
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetConfString(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
description string
|
||||
input string
|
||||
expected interface{}
|
||||
}{
|
||||
{"Should be return casbin", "appname", "casbin"},
|
||||
{"Should be return 8000", "httpport", "8000"},
|
||||
{"Should be return value", "key", "value"},
|
||||
}
|
||||
|
||||
//do some set up job
|
||||
|
||||
os.Setenv("appname", "casbin")
|
||||
os.Setenv("key", "value")
|
||||
|
||||
err := beego.LoadAppConfig("ini", "app.conf")
|
||||
assert.Nil(t, err)
|
||||
|
||||
for _, scenery := range scenarios {
|
||||
t.Run(scenery.description, func(t *testing.T) {
|
||||
actual := GetConfigString(scenery.input)
|
||||
assert.Equal(t, scenery.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetConfInt(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
description string
|
||||
input string
|
||||
expected interface{}
|
||||
}{
|
||||
{"Should be return 8000", "httpport", 8001},
|
||||
{"Should be return 8000", "verificationCodeTimeout", 10},
|
||||
}
|
||||
|
||||
//do some set up job
|
||||
os.Setenv("httpport", "8001")
|
||||
|
||||
err := beego.LoadAppConfig("ini", "app.conf")
|
||||
assert.Nil(t, err)
|
||||
|
||||
for _, scenery := range scenarios {
|
||||
t.Run(scenery.description, func(t *testing.T) {
|
||||
actual, err := GetConfigInt64(scenery.input)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, scenery.expected, int(actual))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetConfBool(t *testing.T) {
|
||||
scenarios := []struct {
|
||||
description string
|
||||
input string
|
||||
expected interface{}
|
||||
}{
|
||||
{"Should be return false", "SessionOn", false},
|
||||
{"Should be return false", "copyrequestbody", true},
|
||||
}
|
||||
|
||||
//do some set up job
|
||||
os.Setenv("SessionOn", "false")
|
||||
|
||||
err := beego.LoadAppConfig("ini", "app.conf")
|
||||
assert.Nil(t, err)
|
||||
for _, scenery := range scenarios {
|
||||
t.Run(scenery.description, func(t *testing.T) {
|
||||
actual, err := GetConfigBool(scenery.input)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, scenery.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
@ -225,10 +225,15 @@ func (c *ApiController) Logout() {
|
||||
user := c.GetSessionUsername()
|
||||
util.LogInfo(c.Ctx, "API: [%s] logged out", user)
|
||||
|
||||
application := c.GetSessionApplication()
|
||||
c.SetSessionUsername("")
|
||||
c.SetSessionData(nil)
|
||||
|
||||
c.ResponseOk(user)
|
||||
if application == nil || application.Name == "app-built-in" || application.HomepageUrl == "" {
|
||||
c.ResponseOk(user)
|
||||
return
|
||||
}
|
||||
c.ResponseOk(user, application.HomepageUrl)
|
||||
}
|
||||
|
||||
// GetAccount
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/idp"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/proxy"
|
||||
@ -267,8 +267,8 @@ func (c *ApiController) Login() {
|
||||
|
||||
setHttpClient(idProvider, provider.Type)
|
||||
|
||||
if form.State != beego.AppConfig.String("authState") && form.State != application.Name {
|
||||
c.ResponseError(fmt.Sprintf("state expected: \"%s\", but got: \"%s\"", beego.AppConfig.String("authState"), form.State))
|
||||
if form.State != conf.GetConfigString("authState") && form.State != application.Name {
|
||||
c.ResponseError(fmt.Sprintf("state expected: \"%s\", but got: \"%s\"", conf.GetConfigString("authState"), form.State))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,15 @@ func (c *ApiController) GetSessionUsername() string {
|
||||
return user.(string)
|
||||
}
|
||||
|
||||
func (c *ApiController) GetSessionApplication() *object.Application {
|
||||
clientId := c.GetSession("aud")
|
||||
if clientId == nil {
|
||||
return nil
|
||||
}
|
||||
application := object.GetApplicationByClientId(clientId.(string))
|
||||
return application
|
||||
}
|
||||
|
||||
func (c *ApiController) GetSessionOidc() (string, string) {
|
||||
sessionData := c.GetSessionData()
|
||||
if sessionData != nil &&
|
||||
|
@ -178,7 +178,7 @@ func (c *ApiController) UpdateLdap() {
|
||||
}
|
||||
if ldap.AutoSync != 0 {
|
||||
object.GetLdapAutoSynchronizer().StartAutoSync(ldap.Id)
|
||||
} else if ldap.AutoSync == 0 && prevLdap.AutoSync != 0{
|
||||
} else if ldap.AutoSync == 0 && prevLdap.AutoSync != 0 {
|
||||
object.GetLdapAutoSynchronizer().StopAutoSync(ldap.Id)
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
@ -62,7 +62,7 @@ func (c *ApiController) RequireSignedIn() (string, bool) {
|
||||
}
|
||||
|
||||
func getInitScore() int {
|
||||
score, err := strconv.Atoi(beego.AppConfig.String("initScore"))
|
||||
score, err := strconv.Atoi(conf.GetConfigString("initScore"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
@ -88,7 +88,7 @@ func (idp *AdfsIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@ -97,7 +97,7 @@ func (idp *BaiduIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
158
idp/casdoor.go
Normal file
158
idp/casdoor.go
Normal file
@ -0,0 +1,158 @@
|
||||
// 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 CasdoorIdProvider struct {
|
||||
Client *http.Client
|
||||
Config *oauth2.Config
|
||||
Host string
|
||||
}
|
||||
|
||||
func NewCasdoorIdProvider(clientId string, clientSecret string, redirectUrl string, hostUrl string) *CasdoorIdProvider {
|
||||
idp := &CasdoorIdProvider{}
|
||||
config := idp.getConfig(hostUrl)
|
||||
config.ClientID = clientId
|
||||
config.ClientSecret = clientSecret
|
||||
config.RedirectURL = redirectUrl
|
||||
idp.Config = config
|
||||
idp.Host = hostUrl
|
||||
return idp
|
||||
}
|
||||
|
||||
func (idp *CasdoorIdProvider) SetHttpClient(client *http.Client) {
|
||||
idp.Client = client
|
||||
}
|
||||
|
||||
func (idp *CasdoorIdProvider) getConfig(hostUrl string) *oauth2.Config {
|
||||
return &oauth2.Config{
|
||||
Endpoint: oauth2.Endpoint{
|
||||
TokenURL: hostUrl + "/api/login/oauth/access_token",
|
||||
},
|
||||
Scopes: []string{"openid email profile"},
|
||||
}
|
||||
}
|
||||
|
||||
type CasdoorToken struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
}
|
||||
|
||||
func (idp *CasdoorIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
resp, err := http.PostForm(idp.Config.Endpoint.TokenURL, url.Values{
|
||||
"client_id": {idp.Config.ClientID},
|
||||
"client_secret": {idp.Config.ClientSecret},
|
||||
"code": {code},
|
||||
"grant_type": {"authorization_code"},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pToken := &CasdoorToken{}
|
||||
err = json.Unmarshal(body, pToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//check if token is expired
|
||||
if pToken.ExpiresIn <= 0 {
|
||||
return nil, fmt.Errorf("%s", pToken.AccessToken)
|
||||
}
|
||||
token := &oauth2.Token{
|
||||
AccessToken: pToken.AccessToken,
|
||||
Expiry: time.Unix(time.Now().Unix()+int64(pToken.ExpiresIn), 0),
|
||||
}
|
||||
return token, nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
{
|
||||
"sub": "2f80c349-4beb-407f-b1f0-528aac0f1acd",
|
||||
"iss": "https://door.casbin.com",
|
||||
"aud": "7a11****0fa2172",
|
||||
"name": "admin",
|
||||
"preferred_username": "Admin",
|
||||
"email": "admin@example.com",
|
||||
"picture": "https://casbin.org/img/casbin.svg",
|
||||
"address": "Guangdong",
|
||||
"phone": "12345678910"
|
||||
}
|
||||
*/
|
||||
|
||||
type CasdoorUserInfo struct {
|
||||
Id string `json:"sub"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"preferred_username"`
|
||||
Email string `json:"email"`
|
||||
AvatarUrl string `json:"picture"`
|
||||
Status string `json:"status"`
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
|
||||
func (idp *CasdoorIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
cdUserinfo := &CasdoorUserInfo{}
|
||||
accessToken := token.AccessToken
|
||||
request, err := http.NewRequest("GET", fmt.Sprintf("%s/api/userinfo", idp.Host), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//add accesstoken to bearer token
|
||||
request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken))
|
||||
resp, err := idp.Client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, cdUserinfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if cdUserinfo.Status != "" {
|
||||
return nil, fmt.Errorf("err: %s", cdUserinfo.Msg)
|
||||
}
|
||||
|
||||
userInfo := &UserInfo{
|
||||
Id: cdUserinfo.Id,
|
||||
Username: cdUserinfo.Name,
|
||||
DisplayName: cdUserinfo.DisplayName,
|
||||
Email: cdUserinfo.Email,
|
||||
AvatarUrl: cdUserinfo.AvatarUrl,
|
||||
}
|
||||
return userInfo, nil
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@ -143,7 +144,7 @@ func (idp *DingTalkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -178,7 +179,7 @@ func (idp *DingTalkIdProvider) postWithBody(body interface{}, url string) ([]byt
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@ -92,7 +93,7 @@ func (idp *GiteeIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rbs, err := io.ReadAll(resp.Body)
|
||||
rbs, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
@ -172,7 +172,7 @@ func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@ -85,7 +85,7 @@ func (idp *GitlabIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -209,7 +209,7 @@ func (idp *GitlabIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@ -95,7 +95,7 @@ func (idp *GoogleIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@ -69,7 +69,7 @@ func (idp *InfoflowInternalIdProvider) GetToken(code string) (*oauth2.Token, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -147,7 +147,7 @@ func (idp *InfoflowInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserIn
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -165,7 +165,7 @@ func (idp *InfoflowInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserIn
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@ -143,7 +144,7 @@ func (idp *InfoflowIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -161,7 +162,7 @@ func (idp *InfoflowIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, erro
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -196,7 +197,7 @@ func (idp *InfoflowIdProvider) postWithBody(body interface{}, url string) ([]byt
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@ -168,7 +169,7 @@ func (idp *LarkIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
req.Header.Set("Authorization", "Bearer "+token.AccessToken)
|
||||
|
||||
resp, err := idp.Client.Do(req)
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -200,7 +201,7 @@ func (idp *LarkIdProvider) postWithBody(body interface{}, url string) ([]byte, e
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
@ -84,7 +85,7 @@ func (idp *LinkedInIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rbs, err := io.ReadAll(resp.Body)
|
||||
rbs, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -322,7 +323,7 @@ func (idp *LinkedInIdProvider) GetUrlRespWithAuthorization(url, token string) ([
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
bs, err := io.ReadAll(resp.Body)
|
||||
bs, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -78,6 +78,8 @@ func GetIdProvider(typ string, subType string, clientId string, clientSecret str
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
} else if typ == "Casdoor" {
|
||||
return NewCasdoorIdProvider(clientId, clientSecret, redirectUrl, hostUrl)
|
||||
} else if isGothSupport(typ) {
|
||||
return NewGothIdProvider(typ, clientId, clientSecret, redirectUrl)
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
@ -75,7 +75,7 @@ func (idp *QqIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
tokenContent, err := io.ReadAll(resp.Body)
|
||||
tokenContent, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
re := regexp.MustCompile("token=(.*?)&")
|
||||
matched := re.FindAllStringSubmatch(string(tokenContent), -1)
|
||||
@ -145,7 +145,7 @@ func (idp *QqIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
openIdBody, err := io.ReadAll(resp.Body)
|
||||
openIdBody, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
re := regexp.MustCompile("\"openid\":\"(.*?)\"}")
|
||||
matched := re.FindAllStringSubmatch(string(openIdBody), -1)
|
||||
@ -161,7 +161,7 @@ func (idp *QqIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
userInfoBody, err := io.ReadAll(resp.Body)
|
||||
userInfoBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ package idp
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
@ -72,7 +72,7 @@ func (idp *WeComInternalIdProvider) GetToken(code string) (*oauth2.Token, error)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -122,7 +122,7 @@ func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -143,7 +143,7 @@ func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err = io.ReadAll(resp.Body)
|
||||
data, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
@ -194,7 +195,7 @@ func (idp *WeComIdProvider) postWithBody(body interface{}, url string) ([]byte,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@ -91,7 +92,7 @@ func (idp *WeiBoIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
return
|
||||
}
|
||||
}(resp.Body)
|
||||
bs, err := io.ReadAll(resp.Body)
|
||||
bs, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
6
main.go
6
main.go
@ -22,6 +22,7 @@ import (
|
||||
"github.com/astaxie/beego/logs"
|
||||
_ "github.com/astaxie/beego/session/redis"
|
||||
"github.com/casdoor/casdoor/authz"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/object"
|
||||
"github.com/casdoor/casdoor/proxy"
|
||||
"github.com/casdoor/casdoor/routers"
|
||||
@ -31,6 +32,7 @@ import (
|
||||
func main() {
|
||||
createDatabase := flag.Bool("createDatabase", false, "true if you need casdoor to create database")
|
||||
flag.Parse()
|
||||
|
||||
object.InitAdapter(*createDatabase)
|
||||
object.InitDb()
|
||||
object.InitDefaultStorageProvider()
|
||||
@ -52,12 +54,12 @@ func main() {
|
||||
beego.InsertFilter("*", beego.BeforeRouter, routers.RecordMessage)
|
||||
|
||||
beego.BConfig.WebConfig.Session.SessionName = "casdoor_session_id"
|
||||
if beego.AppConfig.String("redisEndpoint") == "" {
|
||||
if conf.GetConfigString("redisEndpoint") == "" {
|
||||
beego.BConfig.WebConfig.Session.SessionProvider = "file"
|
||||
beego.BConfig.WebConfig.Session.SessionProviderConfig = "./tmp"
|
||||
} else {
|
||||
beego.BConfig.WebConfig.Session.SessionProvider = "redis"
|
||||
beego.BConfig.WebConfig.Session.SessionProviderConfig = beego.AppConfig.String("redisEndpoint")
|
||||
beego.BConfig.WebConfig.Session.SessionProviderConfig = conf.GetConfigString("redisEndpoint")
|
||||
}
|
||||
beego.BConfig.WebConfig.Session.SessionCookieLifeTime = 3600 * 24 * 30
|
||||
//beego.BConfig.WebConfig.Session.SessionCookieSameSite = http.SameSiteNoneMode
|
||||
|
@ -41,7 +41,7 @@ func InitConfig() {
|
||||
|
||||
func InitAdapter(createDatabase bool) {
|
||||
|
||||
adapter = NewAdapter(beego.AppConfig.String("driverName"), conf.GetBeegoConfDataSourceName(), beego.AppConfig.String("dbName"))
|
||||
adapter = NewAdapter(conf.GetConfigString("driverName"), conf.GetBeegoConfDataSourceName(), conf.GetConfigString("dbName"))
|
||||
if createDatabase {
|
||||
adapter.CreateDatabase()
|
||||
}
|
||||
@ -111,10 +111,10 @@ func (a *Adapter) close() {
|
||||
}
|
||||
|
||||
func (a *Adapter) createTable() {
|
||||
showSql, _ := beego.AppConfig.Bool("showSql")
|
||||
showSql, _ := conf.GetConfigBool("showSql")
|
||||
a.Engine.ShowSQL(showSql)
|
||||
|
||||
tableNamePrefix := beego.AppConfig.String("tableNamePrefix")
|
||||
tableNamePrefix := conf.GetConfigString("tableNamePrefix")
|
||||
tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, tableNamePrefix)
|
||||
a.Engine.SetTableMapper(tbMapper)
|
||||
|
||||
|
@ -229,7 +229,7 @@ func GetMaskedApplication(application *Application, userId string) *Application
|
||||
application.OrganizationObj.PasswordSalt = "***"
|
||||
}
|
||||
}
|
||||
return application
|
||||
return application
|
||||
}
|
||||
|
||||
func GetMaskedApplications(applications []*Application, userId string) []*Application {
|
||||
|
@ -19,14 +19,14 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/proxy"
|
||||
)
|
||||
|
||||
var defaultStorageProvider *Provider = nil
|
||||
|
||||
func InitDefaultStorageProvider() {
|
||||
defaultStorageProviderStr := beego.AppConfig.String("defaultStorageProvider")
|
||||
defaultStorageProviderStr := conf.GetConfigString("defaultStorageProvider")
|
||||
if defaultStorageProviderStr != "" {
|
||||
defaultStorageProvider = getProvider("admin", defaultStorageProviderStr)
|
||||
}
|
||||
|
@ -15,17 +15,11 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
//go:embed token_jwt_key.pem
|
||||
var tokenJwtPublicKey string
|
||||
|
||||
//go:embed token_jwt_key.key
|
||||
var tokenJwtPrivateKey string
|
||||
|
||||
func InitDb() {
|
||||
initBuiltInOrganization()
|
||||
initBuiltInUser()
|
||||
@ -122,7 +116,22 @@ func initBuiltInApplication() {
|
||||
AddApplication(application)
|
||||
}
|
||||
|
||||
func readTokenFromFile() (string, string) {
|
||||
pemPath := "./object/token_jwt_key.pem"
|
||||
keyPath := "./object/token_jwt_key.key"
|
||||
pem, err := ioutil.ReadFile(pemPath)
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
key, err := ioutil.ReadFile(keyPath)
|
||||
if err != nil {
|
||||
return "", ""
|
||||
}
|
||||
return string(pem), string(key)
|
||||
}
|
||||
|
||||
func initBuiltInCert() {
|
||||
tokenJwtPublicKey, tokenJwtPrivateKey := readTokenFromFile()
|
||||
cert := getCert("admin", "cert-built-in")
|
||||
if cert != nil {
|
||||
return
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"gopkg.in/square/go-jose.v2"
|
||||
)
|
||||
|
||||
@ -58,7 +58,7 @@ func getOriginFromHost(host string) (string, string) {
|
||||
func GetOidcDiscovery(host string) OidcDiscovery {
|
||||
originFrontend, originBackend := getOriginFromHost(host)
|
||||
|
||||
origin := beego.AppConfig.String("origin")
|
||||
origin := conf.GetConfigString("origin")
|
||||
if origin != "" {
|
||||
originFrontend = origin
|
||||
originBackend = origin
|
||||
|
@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
//go:build !skipCi
|
||||
// +build !skipCi
|
||||
|
||||
package object
|
||||
|
||||
|
@ -18,8 +18,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
|
||||
@ -27,7 +27,7 @@ var logPostOnly bool
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
logPostOnly, err = beego.AppConfig.Bool("logPostOnly")
|
||||
logPostOnly, err = conf.GetConfigBool("logPostOnly")
|
||||
if err != nil {
|
||||
//panic(err)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
saml2 "github.com/russellhaering/gosaml2"
|
||||
dsig "github.com/russellhaering/goxmldsig"
|
||||
)
|
||||
@ -73,7 +73,7 @@ func buildSp(provider *Provider, samlResponse string) (*saml2.SAMLServiceProvide
|
||||
certStore := dsig.MemoryX509CertificateStore{
|
||||
Roots: []*x509.Certificate{},
|
||||
}
|
||||
origin := beego.AppConfig.String("origin")
|
||||
origin := conf.GetConfigString("origin")
|
||||
certEncodedData := ""
|
||||
if samlResponse != "" {
|
||||
certEncodedData = parseSamlResponse(samlResponse, provider.Type)
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/storage"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
)
|
||||
@ -28,7 +28,7 @@ var isCloudIntranet bool
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
isCloudIntranet, err = beego.AppConfig.Bool("isCloudIntranet")
|
||||
isCloudIntranet, err = conf.GetConfigBool("isCloudIntranet")
|
||||
if err != nil {
|
||||
//panic(err)
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
// 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.
|
||||
|
||||
//go:build !skipCi
|
||||
// +build !skipCi
|
||||
|
||||
|
@ -15,11 +15,10 @@
|
||||
package object
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
@ -67,7 +66,7 @@ func generateJwtToken(application *Application, user *User, nonce string, scope
|
||||
refreshExpireTime := nowTime.Add(time.Duration(application.RefreshExpireInHours) * time.Hour)
|
||||
|
||||
user.Password = ""
|
||||
origin := beego.AppConfig.String("origin")
|
||||
origin := conf.GetConfigString("origin")
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
if origin != "" {
|
||||
originBackend = origin
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"xorm.io/core"
|
||||
)
|
||||
@ -85,6 +85,7 @@ type User struct {
|
||||
Gitlab string `xorm:"gitlab varchar(100)" json:"gitlab"`
|
||||
Adfs string `xorm:"adfs varchar(100)" json:"adfs"`
|
||||
Baidu string `xorm:"baidu varchar(100)" json:"baidu"`
|
||||
Casdoor string `xorm:"casdoor varchar(100)" json:"casdoor"`
|
||||
Infoflow string `xorm:"infoflow varchar(100)" json:"infoflow"`
|
||||
Apple string `xorm:"apple varchar(100)" json:"apple"`
|
||||
AzureAD string `xorm:"azuread varchar(100)" json:"azuread"`
|
||||
@ -428,7 +429,7 @@ func GetUserInfo(userId string, scope string, aud string, host string) (*Userinf
|
||||
if user == nil {
|
||||
return nil, fmt.Errorf("the user: %s doesn't exist", userId)
|
||||
}
|
||||
origin := beego.AppConfig.String("origin")
|
||||
origin := conf.GetConfigString("origin")
|
||||
_, originBackend := getOriginFromHost(host)
|
||||
if origin != "" {
|
||||
originBackend = origin
|
||||
|
@ -52,8 +52,8 @@ func UploadUsers(owner string, fileId string) bool {
|
||||
|
||||
oldUserMap := getUserMap(owner)
|
||||
newUsers := []*User{}
|
||||
for _, line := range table {
|
||||
if parseLineItem(&line, 0) == "" {
|
||||
for index, line := range table {
|
||||
if index == 0 || parseLineItem(&line, 0) == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -67,38 +67,42 @@ func UploadUsers(owner string, fileId string) bool {
|
||||
Password: parseLineItem(&line, 6),
|
||||
PasswordSalt: parseLineItem(&line, 7),
|
||||
DisplayName: parseLineItem(&line, 8),
|
||||
Avatar: parseLineItem(&line, 9),
|
||||
FirstName: parseLineItem(&line, 9),
|
||||
LastName: parseLineItem(&line, 10),
|
||||
Avatar: parseLineItem(&line, 11),
|
||||
PermanentAvatar: "",
|
||||
Email: parseLineItem(&line, 10),
|
||||
Phone: parseLineItem(&line, 11),
|
||||
Location: parseLineItem(&line, 12),
|
||||
Address: []string{parseLineItem(&line, 13)},
|
||||
Affiliation: parseLineItem(&line, 14),
|
||||
Title: parseLineItem(&line, 15),
|
||||
IdCardType: parseLineItem(&line, 16),
|
||||
IdCard: parseLineItem(&line, 17),
|
||||
Homepage: parseLineItem(&line, 18),
|
||||
Bio: parseLineItem(&line, 19),
|
||||
Tag: parseLineItem(&line, 20),
|
||||
Region: parseLineItem(&line, 21),
|
||||
Language: parseLineItem(&line, 22),
|
||||
Gender: parseLineItem(&line, 23),
|
||||
Birthday: parseLineItem(&line, 24),
|
||||
Education: parseLineItem(&line, 25),
|
||||
Score: parseLineItemInt(&line, 26),
|
||||
Ranking: parseLineItemInt(&line, 27),
|
||||
Email: parseLineItem(&line, 12),
|
||||
Phone: parseLineItem(&line, 13),
|
||||
Location: parseLineItem(&line, 14),
|
||||
Address: []string{parseLineItem(&line, 15)},
|
||||
Affiliation: parseLineItem(&line, 16),
|
||||
Title: parseLineItem(&line, 17),
|
||||
IdCardType: parseLineItem(&line, 18),
|
||||
IdCard: parseLineItem(&line, 19),
|
||||
Homepage: parseLineItem(&line, 20),
|
||||
Bio: parseLineItem(&line, 21),
|
||||
Tag: parseLineItem(&line, 22),
|
||||
Region: parseLineItem(&line, 23),
|
||||
Language: parseLineItem(&line, 24),
|
||||
Gender: parseLineItem(&line, 25),
|
||||
Birthday: parseLineItem(&line, 26),
|
||||
Education: parseLineItem(&line, 27),
|
||||
Score: parseLineItemInt(&line, 28),
|
||||
Karma: parseLineItemInt(&line, 29),
|
||||
Ranking: parseLineItemInt(&line, 30),
|
||||
IsDefaultAvatar: false,
|
||||
IsOnline: parseLineItemBool(&line, 28),
|
||||
IsAdmin: parseLineItemBool(&line, 29),
|
||||
IsGlobalAdmin: parseLineItemBool(&line, 30),
|
||||
IsForbidden: parseLineItemBool(&line, 31),
|
||||
IsDeleted: parseLineItemBool(&line, 32),
|
||||
SignupApplication: parseLineItem(&line, 33),
|
||||
IsOnline: parseLineItemBool(&line, 31),
|
||||
IsAdmin: parseLineItemBool(&line, 32),
|
||||
IsGlobalAdmin: parseLineItemBool(&line, 33),
|
||||
IsForbidden: parseLineItemBool(&line, 34),
|
||||
IsDeleted: parseLineItemBool(&line, 35),
|
||||
SignupApplication: parseLineItem(&line, 36),
|
||||
Hash: "",
|
||||
PreHash: "",
|
||||
CreatedIp: parseLineItem(&line, 34),
|
||||
LastSigninTime: parseLineItem(&line, 35),
|
||||
LastSigninIp: parseLineItem(&line, 36),
|
||||
CreatedIp: parseLineItem(&line, 37),
|
||||
LastSigninTime: parseLineItem(&line, 38),
|
||||
LastSigninIp: parseLineItem(&line, 39),
|
||||
Ldap: "",
|
||||
Properties: map[string]string{},
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
"xorm.io/core"
|
||||
)
|
||||
@ -129,7 +129,7 @@ func CheckVerificationCode(dest, code string) string {
|
||||
return "Code has not been sent yet!"
|
||||
}
|
||||
|
||||
timeout, err := beego.AppConfig.Int64("verificationCodeTimeout")
|
||||
timeout, err := conf.GetConfigInt64("verificationCodeTimeout")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/casdoor/casdoor/conf"
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
@ -54,7 +54,7 @@ func isAddressOpen(address string) bool {
|
||||
}
|
||||
|
||||
func getProxyHttpClient() *http.Client {
|
||||
sock5Proxy := beego.AppConfig.String("sock5Proxy")
|
||||
sock5Proxy := conf.GetConfigString("sock5Proxy")
|
||||
if sock5Proxy == "" {
|
||||
return &http.Client{}
|
||||
}
|
||||
|
@ -478,6 +478,39 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/buy-product": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Product API"
|
||||
],
|
||||
"description": "buy product",
|
||||
"operationId": "ApiController.BuyProduct",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "id",
|
||||
"description": "The id of the product",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "providerName",
|
||||
"description": "The name of the provider",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/check-ldap-users-exist": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -1710,6 +1743,49 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-user-payments": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Payment API"
|
||||
],
|
||||
"description": "get payments for a user",
|
||||
"operationId": "ApiController.GetUserPayments",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
"name": "owner",
|
||||
"description": "The owner of payments",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "organization",
|
||||
"description": "The organization of the user",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "user",
|
||||
"description": "The username of the user",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/object.Payment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/get-users": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -1936,6 +2012,36 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/login/oauth/introspect": {
|
||||
"post": {
|
||||
"description": "The introspection endpoint is an OAuth 2.0 endpoint that takes a",
|
||||
"operationId": "ApiController.IntrospectToken",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "formData",
|
||||
"name": "token",
|
||||
"description": "access_token's value or refresh_token's value",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "formData",
|
||||
"name": "token_type_hint",
|
||||
"description": "the token type access_token or refresh_token",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.IntrospectionResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/login/oauth/logout": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -2015,7 +2121,6 @@
|
||||
"in": "query",
|
||||
"name": "client_secret",
|
||||
"description": "OAuth client secret",
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
@ -2046,6 +2151,34 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/notify-payment": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Payment API"
|
||||
],
|
||||
"description": "notify payment",
|
||||
"operationId": "ApiController.NotifyPayment",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "body",
|
||||
"name": "body",
|
||||
"description": "The details of the payment",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/object.Payment"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The Response object",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/controllers.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/send-verification-code": {
|
||||
"post": {
|
||||
"tags": [
|
||||
@ -2664,11 +2797,11 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"2015.0xc0000edb90.false": {
|
||||
"2026.0xc000380de0.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
"2049.0xc0000edbc0.false": {
|
||||
"2060.0xc000380e10.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
@ -2685,10 +2818,10 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/2015.0xc0000edb90.false"
|
||||
"$ref": "#/definitions/2026.0xc000380de0.false"
|
||||
},
|
||||
"data2": {
|
||||
"$ref": "#/definitions/2049.0xc0000edbc0.false"
|
||||
"$ref": "#/definitions/2060.0xc000380e10.false"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
@ -2709,10 +2842,10 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/2015.0xc0000edb90.false"
|
||||
"$ref": "#/definitions/2026.0xc000380de0.false"
|
||||
},
|
||||
"data2": {
|
||||
"$ref": "#/definitions/2049.0xc0000edbc0.false"
|
||||
"$ref": "#/definitions/2060.0xc000380e10.false"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
@ -2864,6 +2997,12 @@
|
||||
"title": "Cert",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"authorityPublicKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"authorityRootPublicKey": {
|
||||
"type": "string"
|
||||
},
|
||||
"bitSize": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
@ -2913,6 +3052,54 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.IntrospectionResponse": {
|
||||
"title": "IntrospectionResponse",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"active": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"aud": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"client_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"exp": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"iat": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"iss": {
|
||||
"type": "string"
|
||||
},
|
||||
"jti": {
|
||||
"type": "string"
|
||||
},
|
||||
"nbf": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"scope": {
|
||||
"type": "string"
|
||||
},
|
||||
"sub": {
|
||||
"type": "string"
|
||||
},
|
||||
"token_type": {
|
||||
"type": "string"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"object.Organization": {
|
||||
"title": "Organization",
|
||||
"type": "object",
|
||||
@ -2950,6 +3137,12 @@
|
||||
"phonePrefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"websiteUrl": {
|
||||
"type": "string"
|
||||
}
|
||||
@ -2959,19 +3152,19 @@
|
||||
"title": "Payment",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"amount": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdTime": {
|
||||
"type": "string"
|
||||
},
|
||||
"currency": {
|
||||
"type": "string"
|
||||
},
|
||||
"detail": {
|
||||
"type": "string"
|
||||
},
|
||||
"displayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"good": {
|
||||
"message": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
@ -2983,12 +3176,31 @@
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"payUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"productDisplayName": {
|
||||
"type": "string"
|
||||
},
|
||||
"productName": {
|
||||
"type": "string"
|
||||
},
|
||||
"provider": {
|
||||
"type": "string"
|
||||
},
|
||||
"returnUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3074,8 +3286,8 @@
|
||||
"type": "string"
|
||||
},
|
||||
"price": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
"type": "number",
|
||||
"format": "double"
|
||||
},
|
||||
"providers": {
|
||||
"type": "array",
|
||||
@ -3087,6 +3299,9 @@
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"returnUrl": {
|
||||
"type": "string"
|
||||
},
|
||||
"sold": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
@ -3112,6 +3327,9 @@
|
||||
"category": {
|
||||
"type": "string"
|
||||
},
|
||||
"cert": {
|
||||
"type": "string"
|
||||
},
|
||||
"clientId": {
|
||||
"type": "string"
|
||||
},
|
||||
@ -3482,6 +3700,9 @@
|
||||
"birthday": {
|
||||
"type": "string"
|
||||
},
|
||||
"casdoor": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdIp": {
|
||||
"type": "string"
|
||||
},
|
||||
|
@ -309,6 +309,28 @@ paths:
|
||||
description: object
|
||||
schema:
|
||||
$ref: '#/definitions/Response'
|
||||
/api/buy-product:
|
||||
post:
|
||||
tags:
|
||||
- Product API
|
||||
description: buy product
|
||||
operationId: ApiController.BuyProduct
|
||||
parameters:
|
||||
- in: query
|
||||
name: id
|
||||
description: The id of the product
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: providerName
|
||||
description: The name of the provider
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/check-ldap-users-exist:
|
||||
post:
|
||||
tags:
|
||||
@ -1111,6 +1133,35 @@ paths:
|
||||
responses:
|
||||
"200":
|
||||
description: '{int} int The count of filtered users for an organization'
|
||||
/api/get-user-payments:
|
||||
get:
|
||||
tags:
|
||||
- Payment API
|
||||
description: get payments for a user
|
||||
operationId: ApiController.GetUserPayments
|
||||
parameters:
|
||||
- in: query
|
||||
name: owner
|
||||
description: The owner of payments
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: organization
|
||||
description: The organization of the user
|
||||
required: true
|
||||
type: string
|
||||
- in: query
|
||||
name: user
|
||||
description: The username of the user
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/object.Payment'
|
||||
/api/get-users:
|
||||
get:
|
||||
tags:
|
||||
@ -1262,6 +1313,26 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/object.TokenWrapper'
|
||||
/api/login/oauth/introspect:
|
||||
post:
|
||||
description: The introspection endpoint is an OAuth 2.0 endpoint that takes a
|
||||
operationId: ApiController.IntrospectToken
|
||||
parameters:
|
||||
- in: formData
|
||||
name: token
|
||||
description: access_token's value or refresh_token's value
|
||||
required: true
|
||||
type: string
|
||||
- in: formData
|
||||
name: token_type_hint
|
||||
description: the token type access_token or refresh_token
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/object.IntrospectionResponse'
|
||||
/api/login/oauth/logout:
|
||||
get:
|
||||
tags:
|
||||
@ -1318,7 +1389,6 @@ paths:
|
||||
- in: query
|
||||
name: client_secret
|
||||
description: OAuth client secret
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
@ -1336,6 +1406,24 @@ paths:
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/notify-payment:
|
||||
post:
|
||||
tags:
|
||||
- Payment API
|
||||
description: notify payment
|
||||
operationId: ApiController.NotifyPayment
|
||||
parameters:
|
||||
- in: body
|
||||
name: body
|
||||
description: The details of the payment
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/object.Payment'
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
schema:
|
||||
$ref: '#/definitions/controllers.Response'
|
||||
/api/send-verification-code:
|
||||
post:
|
||||
tags:
|
||||
@ -1743,10 +1831,10 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/object.Userinfo'
|
||||
definitions:
|
||||
2015.0xc0000edb90.false:
|
||||
2026.0xc000380de0.false:
|
||||
title: "false"
|
||||
type: object
|
||||
2049.0xc0000edbc0.false:
|
||||
2060.0xc000380e10.false:
|
||||
title: "false"
|
||||
type: object
|
||||
RequestForm:
|
||||
@ -1760,9 +1848,9 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/2015.0xc0000edb90.false'
|
||||
$ref: '#/definitions/2026.0xc000380de0.false'
|
||||
data2:
|
||||
$ref: '#/definitions/2049.0xc0000edbc0.false'
|
||||
$ref: '#/definitions/2060.0xc000380e10.false'
|
||||
msg:
|
||||
type: string
|
||||
name:
|
||||
@ -1776,9 +1864,9 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/2015.0xc0000edb90.false'
|
||||
$ref: '#/definitions/2026.0xc000380de0.false'
|
||||
data2:
|
||||
$ref: '#/definitions/2049.0xc0000edbc0.false'
|
||||
$ref: '#/definitions/2060.0xc000380e10.false'
|
||||
msg:
|
||||
type: string
|
||||
name:
|
||||
@ -1880,6 +1968,10 @@ definitions:
|
||||
title: Cert
|
||||
type: object
|
||||
properties:
|
||||
authorityPublicKey:
|
||||
type: string
|
||||
authorityRootPublicKey:
|
||||
type: string
|
||||
bitSize:
|
||||
type: integer
|
||||
format: int64
|
||||
@ -1912,6 +2004,39 @@ definitions:
|
||||
type: string
|
||||
value:
|
||||
type: string
|
||||
object.IntrospectionResponse:
|
||||
title: IntrospectionResponse
|
||||
type: object
|
||||
properties:
|
||||
active:
|
||||
type: boolean
|
||||
aud:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
client_id:
|
||||
type: string
|
||||
exp:
|
||||
type: integer
|
||||
format: int64
|
||||
iat:
|
||||
type: integer
|
||||
format: int64
|
||||
iss:
|
||||
type: string
|
||||
jti:
|
||||
type: string
|
||||
nbf:
|
||||
type: integer
|
||||
format: int64
|
||||
scope:
|
||||
type: string
|
||||
sub:
|
||||
type: string
|
||||
token_type:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
object.Organization:
|
||||
title: Organization
|
||||
type: object
|
||||
@ -1938,21 +2063,25 @@ definitions:
|
||||
type: string
|
||||
phonePrefix:
|
||||
type: string
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
websiteUrl:
|
||||
type: string
|
||||
object.Payment:
|
||||
title: Payment
|
||||
type: object
|
||||
properties:
|
||||
amount:
|
||||
type: string
|
||||
createdTime:
|
||||
type: string
|
||||
currency:
|
||||
type: string
|
||||
detail:
|
||||
type: string
|
||||
displayName:
|
||||
type: string
|
||||
good:
|
||||
message:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
@ -1960,10 +2089,23 @@ definitions:
|
||||
type: string
|
||||
owner:
|
||||
type: string
|
||||
payUrl:
|
||||
type: string
|
||||
price:
|
||||
type: number
|
||||
format: double
|
||||
productDisplayName:
|
||||
type: string
|
||||
productName:
|
||||
type: string
|
||||
provider:
|
||||
type: string
|
||||
returnUrl:
|
||||
type: string
|
||||
state:
|
||||
type: string
|
||||
tag:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
user:
|
||||
@ -2021,8 +2163,8 @@ definitions:
|
||||
owner:
|
||||
type: string
|
||||
price:
|
||||
type: integer
|
||||
format: int64
|
||||
type: number
|
||||
format: double
|
||||
providers:
|
||||
type: array
|
||||
items:
|
||||
@ -2030,6 +2172,8 @@ definitions:
|
||||
quantity:
|
||||
type: integer
|
||||
format: int64
|
||||
returnUrl:
|
||||
type: string
|
||||
sold:
|
||||
type: integer
|
||||
format: int64
|
||||
@ -2047,6 +2191,8 @@ definitions:
|
||||
type: string
|
||||
category:
|
||||
type: string
|
||||
cert:
|
||||
type: string
|
||||
clientId:
|
||||
type: string
|
||||
clientId2:
|
||||
@ -2296,6 +2442,8 @@ definitions:
|
||||
type: string
|
||||
birthday:
|
||||
type: string
|
||||
casdoor:
|
||||
type: string
|
||||
createdIp:
|
||||
type: string
|
||||
createdTime:
|
||||
|
@ -39,4 +39,4 @@ func IsPhoneCnValid(phone string) bool {
|
||||
|
||||
func getMaskedPhone(phone string) string {
|
||||
return rePhone.ReplaceAllString(phone, "$1****$2")
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -162,7 +162,7 @@ func GetMinLenStr(strs ...string) string {
|
||||
}
|
||||
|
||||
func ReadStringFromPath(path string) string {
|
||||
data, err := os.ReadFile(path)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -171,7 +171,7 @@ func ReadStringFromPath(path string) string {
|
||||
}
|
||||
|
||||
func WriteStringToPath(s string, path string) {
|
||||
err := os.WriteFile(path, []byte(s), 0644)
|
||||
err := ioutil.WriteFile(path, []byte(s), 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -220,7 +220,7 @@ func GetMaskedEmail(email string) string {
|
||||
username := maskString(tokens[0])
|
||||
domain := tokens[1]
|
||||
domainTokens := strings.Split(domain, ".")
|
||||
domainTokens[len(domainTokens) - 2] = maskString(domainTokens[len(domainTokens) - 2])
|
||||
domainTokens[len(domainTokens)-2] = maskString(domainTokens[len(domainTokens)-2])
|
||||
return fmt.Sprintf("%s@%s", username, strings.Join(domainTokens, "."))
|
||||
}
|
||||
|
||||
@ -228,6 +228,6 @@ func maskString(str string) string {
|
||||
if len(str) <= 2 {
|
||||
return str
|
||||
} else {
|
||||
return fmt.Sprintf("%c%s%c", str[0], strings.Repeat("*", len(str) - 2), str[len(str) - 1])
|
||||
return fmt.Sprintf("%c%s%c", str[0], strings.Repeat("*", len(str)-2), str[len(str)-1])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -245,3 +245,4 @@ func TestSnakeString(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,8 +235,12 @@ class App extends Component {
|
||||
});
|
||||
|
||||
Setting.showMessage("success", `Logged out successfully`);
|
||||
|
||||
Setting.goToLinkSoft(this, "/");
|
||||
let redirectUri = res.data2;
|
||||
if (redirectUri !== null && redirectUri !== undefined && redirectUri !== "") {
|
||||
Setting.goToLink(redirectUri);
|
||||
}else{
|
||||
Setting.goToLinkSoft(this, "/");
|
||||
}
|
||||
} else {
|
||||
Setting.showMessage("error", `Failed to log out: ${res.msg}`);
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ class ProviderEditPage extends React.Component {
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.provider.type !== "Adfs" ? null : (
|
||||
this.state.provider.type !== "Adfs" && this.state.provider.type !== "Casdoor" ? null : (
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={2}>
|
||||
{Setting.getLabel(i18next.t("provider:Domain"), i18next.t("provider:Domain - Tooltip"))} :
|
||||
|
@ -70,15 +70,7 @@ export function isProviderVisible(providerItem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (providerItem.provider.type === "GitHub") {
|
||||
if (isLocalhost()) {
|
||||
return providerItem.provider.name.includes("localhost");
|
||||
} else {
|
||||
return !providerItem.provider.name.includes("localhost");
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function isProviderVisibleForSignUp(providerItem) {
|
||||
@ -404,6 +396,7 @@ export function getProviderTypeOptions(category) {
|
||||
{id: 'GitLab', name: 'GitLab'},
|
||||
{id: 'Adfs', name: 'Adfs'},
|
||||
{id: 'Baidu', name: 'Baidu'},
|
||||
{id: 'Casdoor', name: 'Casdoor'},
|
||||
{id: 'Infoflow', name: 'Infoflow'},
|
||||
{id: 'Apple', name: 'Apple'},
|
||||
{id: 'AzureAD', name: 'AzureAD'},
|
||||
|
@ -106,6 +106,7 @@ class AuthCallback extends React.Component {
|
||||
method: method,
|
||||
};
|
||||
const oAuthParams = Util.getOAuthGetParameters(innerParams);
|
||||
const concatChar = oAuthParams?.redirectUri?.includes('?') ? '&' : '?';
|
||||
AuthBackend.login(body, oAuthParams)
|
||||
.then((res) => {
|
||||
if (res.status === 'ok') {
|
||||
@ -118,11 +119,11 @@ class AuthCallback extends React.Component {
|
||||
Setting.goToLink(link);
|
||||
} else if (responseType === "code") {
|
||||
const code = res.data;
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
|
||||
// Util.showMessage("success", `Authorization code: ${res.data}`);
|
||||
} else if (responseType === "token" || responseType === "id_token"){
|
||||
const token = res.data;
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}?${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}${responseType}=${token}&state=${oAuthParams.state}&token_type=bearer`);
|
||||
} else if (responseType === "link") {
|
||||
const from = innerParams.get("from");
|
||||
Setting.goToLinkSoft(this, from);
|
||||
|
32
web/src/auth/CasdoorLoginButton.js
Normal file
32
web/src/auth/CasdoorLoginButton.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/casdoor.svg`} alt="Sign in with Casdoor" style={{width: 24, height: 24}} />;
|
||||
}
|
||||
|
||||
const config = {
|
||||
text: "Sign in with Casdoor",
|
||||
icon: Icon,
|
||||
iconFormat: name => `fa fa-${name}`,
|
||||
style: {background: "#ffffff", color: "#000000"},
|
||||
activeStyle: {background: "#ededee"},
|
||||
};
|
||||
|
||||
const CasdoorLoginButton = createButton(config);
|
||||
|
||||
export default CasdoorLoginButton;
|
@ -36,6 +36,7 @@ import LarkLoginButton from "./LarkLoginButton";
|
||||
import GitLabLoginButton from "./GitLabLoginButton";
|
||||
import AdfsLoginButton from "./AdfsLoginButton";
|
||||
import BaiduLoginButton from "./BaiduLoginButton";
|
||||
import CasdoorLoginButton from "./CasdoorLoginButton";
|
||||
import InfoflowLoginButton from "./InfoflowLoginButton";
|
||||
import AppleLoginButton from "./AppleLoginButton"
|
||||
import AzureADLoginButton from "./AzureADLoginButton";
|
||||
@ -56,7 +57,9 @@ class LoginPage extends React.Component {
|
||||
isCodeSignin: false,
|
||||
msg: null,
|
||||
username: null,
|
||||
validEmailOrPhone: false
|
||||
validEmailOrPhone: false,
|
||||
validEmail: false,
|
||||
validPhone: false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -135,6 +138,7 @@ class LoginPage extends React.Component {
|
||||
Setting.goToLink(link);
|
||||
} else if (responseType === "code") {
|
||||
const code = res.data;
|
||||
const concatChar = oAuthParams?.redirectUri?.includes('?') ? '&' : '?';
|
||||
|
||||
if (Setting.hasPromptPage(application)) {
|
||||
AuthBackend.getAccount("")
|
||||
@ -147,7 +151,7 @@ class LoginPage extends React.Component {
|
||||
this.onUpdateAccount(account);
|
||||
|
||||
if (Setting.isPromptAnswered(account, application)) {
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
|
||||
} else {
|
||||
Setting.goToLinkSoft(ths, `/prompt/${application.name}?redirectUri=${oAuthParams.redirectUri}&code=${code}&state=${oAuthParams.state}`);
|
||||
}
|
||||
@ -156,7 +160,7 @@ class LoginPage extends React.Component {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}?code=${code}&state=${oAuthParams.state}`);
|
||||
Setting.goToLink(`${oAuthParams.redirectUri}${concatChar}code=${code}&state=${oAuthParams.state}`);
|
||||
}
|
||||
|
||||
// Util.showMessage("success", `Authorization code: ${res.data}`);
|
||||
@ -198,6 +202,8 @@ class LoginPage extends React.Component {
|
||||
return <GitLabLoginButton text={text} align={"center"} />
|
||||
} else if (type === "Adfs") {
|
||||
return <AdfsLoginButton text={text} align={"center"} />
|
||||
} else if (type === "Casdoor") {
|
||||
return <CasdoorLoginButton text={text} align={"center"} />
|
||||
} else if (type === "Baidu") {
|
||||
return <BaiduLoginButton text={text} align={"center"} />
|
||||
} else if (type === "Infoflow") {
|
||||
@ -344,6 +350,12 @@ class LoginPage extends React.Component {
|
||||
return Promise.reject(i18next.t("login:The input is not valid Email or Phone!"));
|
||||
}
|
||||
}
|
||||
if (Setting.isValidPhone(this.state.username)) {
|
||||
this.setState({validPhone: true})
|
||||
}
|
||||
if (Setting.isValidEmail(this.state.username)) {
|
||||
this.setState({validEmail: true})
|
||||
}
|
||||
this.setState({validEmailOrPhone: true});
|
||||
return Promise.resolve();
|
||||
}
|
||||
@ -369,7 +381,7 @@ class LoginPage extends React.Component {
|
||||
>
|
||||
<CountDownInput
|
||||
disabled={this.state.username?.length === 0 || !this.state.validEmailOrPhone}
|
||||
onButtonClickArgs={[this.state.username, "", Setting.getApplicationOrgName(application), true]}
|
||||
onButtonClickArgs={[this.state.username, this.state.validEmail ? "email" : "phone", Setting.getApplicationOrgName(application)]}
|
||||
/>
|
||||
</Form.Item>
|
||||
) : (
|
||||
|
@ -147,7 +147,10 @@ class PromptPage extends React.Component {
|
||||
if (res.status === 'ok') {
|
||||
this.onUpdateAccount(null);
|
||||
|
||||
const redirectUrl = this.getRedirectUrl();
|
||||
let redirectUrl = this.getRedirectUrl();
|
||||
if (redirectUrl === "") {
|
||||
redirectUrl = res.data2
|
||||
}
|
||||
if (redirectUrl !== "") {
|
||||
Setting.goToLink(redirectUrl);
|
||||
} else {
|
||||
|
@ -15,7 +15,7 @@
|
||||
import React from "react";
|
||||
import {Tooltip} from "antd";
|
||||
import * as Util from "./Util";
|
||||
import {StaticBaseUrl} from "../Setting";
|
||||
import * as Setting from "../Setting";
|
||||
|
||||
const authInfo = {
|
||||
Google: {
|
||||
@ -78,6 +78,10 @@ const authInfo = {
|
||||
scope: "basic",
|
||||
endpoint: "http://openapi.baidu.com/oauth/2.0/authorize",
|
||||
},
|
||||
Casdoor: {
|
||||
scope: "openid%20profile%20email",
|
||||
endpoint: "http://example.com",
|
||||
},
|
||||
Infoflow: {
|
||||
endpoint: "https://xpc.im.baidu.com/oauth2/authorize",
|
||||
},
|
||||
@ -101,71 +105,71 @@ const authInfo = {
|
||||
const otherProviderInfo = {
|
||||
SMS: {
|
||||
"Aliyun SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_aliyun.png`,
|
||||
url: "https://aliyun.com/product/sms",
|
||||
},
|
||||
"Tencent Cloud SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_tencent_cloud.jpg`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_tencent_cloud.jpg`,
|
||||
url: "https://cloud.tencent.com/product/sms",
|
||||
},
|
||||
"Volc Engine SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_volc_engine.jpg`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_volc_engine.jpg`,
|
||||
url: "https://www.volcengine.com/products/cloud-sms",
|
||||
},
|
||||
"Huawei Cloud SMS": {
|
||||
logo: `${StaticBaseUrl}/img/social_huawei.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_huawei.png`,
|
||||
url: "https://www.huaweicloud.com/product/msgsms.html",
|
||||
},
|
||||
},
|
||||
Email: {
|
||||
"Default": {
|
||||
logo: `${StaticBaseUrl}/img/social_default.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_default.png`,
|
||||
url: "",
|
||||
},
|
||||
},
|
||||
Storage: {
|
||||
"Local File System": {
|
||||
logo: `${StaticBaseUrl}/img/social_file.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_file.png`,
|
||||
url: "",
|
||||
},
|
||||
"AWS S3": {
|
||||
logo: `${StaticBaseUrl}/img/social_aws.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_aws.png`,
|
||||
url: "https://aws.amazon.com/s3",
|
||||
},
|
||||
"Aliyun OSS": {
|
||||
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_aliyun.png`,
|
||||
url: "https://aliyun.com/product/oss",
|
||||
},
|
||||
"Tencent Cloud COS": {
|
||||
logo: `${StaticBaseUrl}/img/social_tencent_cloud.jpg`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_tencent_cloud.jpg`,
|
||||
url: "https://cloud.tencent.com/product/cos",
|
||||
},
|
||||
},
|
||||
SAML: {
|
||||
"Aliyun IDaaS": {
|
||||
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_aliyun.png`,
|
||||
url: "https://aliyun.com/product/idaas"
|
||||
},
|
||||
"Keycloak": {
|
||||
logo: `${StaticBaseUrl}/img/social_keycloak.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/social_keycloak.png`,
|
||||
url: "https://www.keycloak.org/"
|
||||
},
|
||||
},
|
||||
Payment: {
|
||||
"Alipay": {
|
||||
logo: `${StaticBaseUrl}/img/payment_alipay.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/payment_alipay.png`,
|
||||
url: "https://www.alipay.com/"
|
||||
},
|
||||
"WeChat Pay": {
|
||||
logo: `${StaticBaseUrl}/img/payment_wechat_pay.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/payment_wechat_pay.png`,
|
||||
url: "https://pay.weixin.qq.com/"
|
||||
},
|
||||
"PayPal": {
|
||||
logo: `${StaticBaseUrl}/img/payment_paypal.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/payment_paypal.png`,
|
||||
url: "https://www.paypal.com/"
|
||||
},
|
||||
"GC": {
|
||||
logo: `${StaticBaseUrl}/img/payment_gc.png`,
|
||||
logo: `${Setting.StaticBaseUrl}/img/payment_gc.png`,
|
||||
url: "https://gc.org"
|
||||
},
|
||||
},
|
||||
@ -173,7 +177,7 @@ const otherProviderInfo = {
|
||||
|
||||
export function getProviderLogo(provider) {
|
||||
if (provider.category === "OAuth") {
|
||||
return `${StaticBaseUrl}/img/social_${provider.type.toLowerCase()}.png`;
|
||||
return `${Setting.StaticBaseUrl}/img/social_${provider.type.toLowerCase()}.png`;
|
||||
} else {
|
||||
return otherProviderInfo[provider.category][provider.type].logo;
|
||||
}
|
||||
@ -283,6 +287,8 @@ export function getAuthUrl(application, provider, method) {
|
||||
return `${provider.domain}/adfs/oauth2/authorize?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&nonce=casdoor&scope=openid`;
|
||||
} else if (provider.type === "Baidu") {
|
||||
return `${endpoint}?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}&display=popup`;
|
||||
} else if (provider.type === "Casdoor") {
|
||||
return `${provider.domain}/login/oauth/authorize?client_id=${provider.clientId}&redirect_uri=${redirectUri}&state=${state}&response_type=code&scope=${scope}`;
|
||||
} else if (provider.type === "Infoflow"){
|
||||
return `${endpoint}?appid=${provider.clientId}&redirect_uri=${redirectUri}?state=${state}`
|
||||
} else if (provider.type === "Apple") {
|
||||
|
@ -20,8 +20,8 @@
|
||||
"Password ON": "开启密码",
|
||||
"Password ON - Tooltip": "是否允许密码登录",
|
||||
"Please select a HTML file": "请选择一个HTML文件",
|
||||
"Redirect URL": "回调URL",
|
||||
"Redirect URLs": "回调URLs",
|
||||
"Redirect URL": "重定向 URL",
|
||||
"Redirect URLs": "重定向 URLs",
|
||||
"Redirect URLs - Tooltip": "登录成功后重定向地址列表",
|
||||
"Refresh token expire": "Refresh Token过期时间",
|
||||
"Refresh token expire - Tooltip": "Refresh Token过期时间",
|
||||
@ -304,7 +304,7 @@
|
||||
"Pay": "支付方式",
|
||||
"Payment providers": "支付提供商",
|
||||
"Payment providers - Tooltip": "支付提供商 - 工具提示",
|
||||
"Paypal": "Paypal",
|
||||
"Paypal": "PayPal(贝宝)",
|
||||
"Placing order...": "正在下单...",
|
||||
"Price": "价格",
|
||||
"Price - Tooltip": "价格 - 工具提示",
|
||||
|
BIN
xlsx/user_test.xlsx
Normal file
BIN
xlsx/user_test.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user