mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-20 10:30:34 +08:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0fc0ba0c76 | ||
![]() |
24459d852e | ||
![]() |
e3f5bf93b2 | ||
![]() |
879ca6a488 | ||
![]() |
544cd40a08 | ||
![]() |
99f7883c7d | ||
![]() |
88b0fb6e52 | ||
![]() |
fa9b49e25b | ||
![]() |
cd76e9372e | ||
![]() |
04b9e05244 |
@@ -15,11 +15,13 @@
|
||||
package idp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@@ -60,9 +62,38 @@ func (idp *GithubIdProvider) getConfig() *oauth2.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
type GithubToken struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
Scope string `json:"scope"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
func (idp *GithubIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, idp.Client)
|
||||
return idp.Config.Exchange(ctx, code)
|
||||
params := &struct {
|
||||
Code string `json:"code"`
|
||||
ClientId string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
}{code, idp.Config.ClientID, idp.Config.ClientSecret}
|
||||
data, err := idp.postWithBody(params, idp.Config.Endpoint.TokenURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pToken := &GithubToken{}
|
||||
if err = json.Unmarshal(data, pToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if pToken.Error != "" {
|
||||
return nil, fmt.Errorf("err: %s", pToken.Error)
|
||||
}
|
||||
|
||||
token := &oauth2.Token{
|
||||
AccessToken: pToken.AccessToken,
|
||||
TokenType: "Bearer",
|
||||
}
|
||||
|
||||
return token, nil
|
||||
|
||||
}
|
||||
|
||||
//{
|
||||
@@ -192,3 +223,30 @@ func (idp *GithubIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error)
|
||||
}
|
||||
return &userInfo, nil
|
||||
}
|
||||
|
||||
func (idp *GithubIdProvider) postWithBody(body interface{}, url string) ([]byte, error) {
|
||||
bs, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r := strings.NewReader(string(bs))
|
||||
req, _ := http.NewRequest("POST", url, r)
|
||||
req.Header.Set("Accept", "application/json")
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
resp, err := idp.Client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
@@ -231,6 +231,10 @@ func (idp *GothIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
value.Add("code", code)
|
||||
}
|
||||
accessToken, err := idp.Session.Authorize(idp.Provider, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//Get ExpiresAt's value
|
||||
valueOfExpire := reflect.ValueOf(idp.Session).Elem().FieldByName("ExpiresAt")
|
||||
if valueOfExpire.IsValid() {
|
||||
@@ -240,7 +244,8 @@ func (idp *GothIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
AccessToken: accessToken,
|
||||
Expiry: expireAt,
|
||||
}
|
||||
return &token, err
|
||||
|
||||
return &token, nil
|
||||
}
|
||||
|
||||
func (idp *GothIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
|
@@ -111,6 +111,7 @@ type WecomInternalUserInfo struct {
|
||||
Email string `json:"email"`
|
||||
Avatar string `json:"avatar"`
|
||||
OpenId string `json:"open_userid"`
|
||||
UserId string `json:"userid"`
|
||||
}
|
||||
|
||||
func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo, error) {
|
||||
@@ -156,7 +157,7 @@ func (idp *WeComInternalIdProvider) GetUserInfo(token *oauth2.Token) (*UserInfo,
|
||||
return nil, fmt.Errorf("userInfoResp.errcode = %d, userInfoResp.errmsg = %s", infoResp.Errcode, infoResp.Errmsg)
|
||||
}
|
||||
userInfo := UserInfo{
|
||||
Id: infoResp.OpenId,
|
||||
Id: infoResp.UserId,
|
||||
Username: infoResp.Name,
|
||||
DisplayName: infoResp.Name,
|
||||
Email: infoResp.Email,
|
||||
|
@@ -180,16 +180,15 @@ func CheckUserPassword(organization string, username string, password string) (*
|
||||
return nil, "the user is forbidden to sign in, please contact the administrator"
|
||||
}
|
||||
|
||||
msg := CheckPassword(user, password)
|
||||
if msg != "" {
|
||||
//for ldap users
|
||||
if user.Ldap != "" {
|
||||
return checkLdapUserPassword(user, password)
|
||||
if user.Ldap != "" {
|
||||
//ONLY for ldap users
|
||||
return checkLdapUserPassword(user, password)
|
||||
} else {
|
||||
msg := CheckPassword(user, password)
|
||||
if msg != "" {
|
||||
return nil, msg
|
||||
}
|
||||
|
||||
return nil, msg
|
||||
}
|
||||
|
||||
return user, ""
|
||||
}
|
||||
|
||||
|
@@ -439,14 +439,15 @@ func RefreshToken(grantType string, refreshToken string, scope string, clientId
|
||||
TokenType: "Bearer",
|
||||
}
|
||||
AddToken(newToken)
|
||||
DeleteToken(&token)
|
||||
|
||||
tokenWrapper := &TokenWrapper{
|
||||
AccessToken: token.AccessToken,
|
||||
IdToken: token.AccessToken,
|
||||
RefreshToken: token.RefreshToken,
|
||||
TokenType: token.TokenType,
|
||||
ExpiresIn: token.ExpiresIn,
|
||||
Scope: token.Scope,
|
||||
AccessToken: newToken.AccessToken,
|
||||
IdToken: newToken.AccessToken,
|
||||
RefreshToken: newToken.RefreshToken,
|
||||
TokenType: newToken.TokenType,
|
||||
ExpiresIn: newToken.ExpiresIn,
|
||||
Scope: newToken.Scope,
|
||||
}
|
||||
|
||||
return tokenWrapper
|
||||
@@ -521,7 +522,8 @@ func GetPasswordToken(application *Application, username string, password string
|
||||
if user == nil {
|
||||
return nil, errors.New("error: the user does not exist")
|
||||
}
|
||||
if user.Password != password {
|
||||
msg := CheckPassword(user, password)
|
||||
if msg != "" {
|
||||
return nil, errors.New("error: invalid username or password")
|
||||
}
|
||||
if user.IsForbidden {
|
||||
|
@@ -304,7 +304,7 @@ func UpdateUser(id string, user *User, columns []string, isGlobalAdmin bool) boo
|
||||
"is_admin", "is_global_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties"}
|
||||
}
|
||||
if isGlobalAdmin {
|
||||
columns = append(columns, "name")
|
||||
columns = append(columns, "name", "email", "phone")
|
||||
}
|
||||
|
||||
affected, err := adapter.Engine.ID(core.PK{owner, name}).Cols(columns...).Update(user)
|
||||
|
@@ -83,6 +83,10 @@ class ProductBuyPage extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
getPrice(product) {
|
||||
return `${this.getCurrencySymbol(product)}${product?.price} (${this.getCurrencyText(product)})`;
|
||||
}
|
||||
|
||||
getProviders(product) {
|
||||
if (this.state.providers.length === 0 || product.providers.length === 0) {
|
||||
return [];
|
||||
@@ -207,7 +211,9 @@ class ProductBuyPage extends React.Component {
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={i18next.t("product:Price")}>
|
||||
<span style={{fontSize: 28, color: "red", fontWeight: "bold"}}>
|
||||
{`${this.getCurrencySymbol(product)}${product?.price} (${this.getCurrencyText(product)})`}
|
||||
{
|
||||
this.getPrice(product)
|
||||
}
|
||||
</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={i18next.t("product:Quantity")}><span style={{fontSize: 16}}>{product?.quantity}</span></Descriptions.Item>
|
||||
|
@@ -22,6 +22,7 @@ import copy from "copy-to-clipboard";
|
||||
import {authConfig} from "./auth/Auth";
|
||||
import {Helmet} from "react-helmet";
|
||||
import moment from "moment";
|
||||
import * as Conf from "./Conf";
|
||||
|
||||
export let ServerUrl = "";
|
||||
|
||||
@@ -29,12 +30,17 @@ export let ServerUrl = "";
|
||||
export const StaticBaseUrl = "https://cdn.casbin.org";
|
||||
|
||||
// https://catamphetamine.gitlab.io/country-flag-icons/3x2/index.html
|
||||
export const CountryRegionData = getCountryRegionData()
|
||||
export const CountryRegionData = getCountryRegionData();
|
||||
|
||||
export function getCountryRegionData() {
|
||||
let language = i18next.language;
|
||||
if (language === null || language === "null") {
|
||||
language = Conf.DefaultLanguage;
|
||||
}
|
||||
|
||||
var countries = require("i18n-iso-countries");
|
||||
countries.registerLocale(require("i18n-iso-countries/langs/" + i18next.language + ".json"));
|
||||
var data = countries.getNames(i18next.language, {select: "official"});
|
||||
countries.registerLocale(require("i18n-iso-countries/langs/" + language + ".json"));
|
||||
var data = countries.getNames(language, {select: "official"});
|
||||
var result = []
|
||||
for (var i in data)
|
||||
result.push({code:i, name:data[i]})
|
||||
|
@@ -42,7 +42,7 @@ class SyncerListPage extends BaseListPage {
|
||||
affiliationTable: "",
|
||||
avatarBaseUrl: "",
|
||||
syncInterval: 10,
|
||||
isEnabled: true,
|
||||
isEnabled: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -224,7 +224,11 @@ class UserEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:Email"), i18next.t("general:Email - Tooltip"))} :
|
||||
</Col>
|
||||
<Col style={{paddingRight: '20px'}} span={11} >
|
||||
<Input value={this.state.user.email} disabled />
|
||||
<Input value={this.state.user.email}
|
||||
disabled={this.state.user.id === this.props.account?.id ? true : !Setting.isAdminUser(this.props.account)}
|
||||
onChange={e => {
|
||||
this.updateUserField('email', e.target.value);
|
||||
}} />
|
||||
</Col>
|
||||
<Col span={11} >
|
||||
{ this.state.user.id === this.props.account?.id ? (<ResetModal org={this.state.application?.organizationObj} buttonText={i18next.t("user:Reset Email...")} destType={"email"} />) : null}
|
||||
@@ -235,7 +239,11 @@ class UserEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:Phone"), i18next.t("general:Phone - Tooltip"))} :
|
||||
</Col>
|
||||
<Col style={{paddingRight: '20px'}} span={11} >
|
||||
<Input value={this.state.user.phone} addonBefore={`+${this.state.application?.organizationObj.phonePrefix}`} disabled />
|
||||
<Input value={this.state.user.phone} addonBefore={`+${this.state.application?.organizationObj.phonePrefix}`}
|
||||
disabled={this.state.user.id === this.props.account?.id ? true : !Setting.isAdminUser(this.props.account)}
|
||||
onChange={e => {
|
||||
this.updateUserField('phone', e.target.value);
|
||||
}}/>
|
||||
</Col>
|
||||
<Col span={11} >
|
||||
{ this.state.user.id === this.props.account?.id ? (<ResetModal org={this.state.application?.organizationObj} buttonText={i18next.t("user:Reset Phone...")} destType={"phone"} />) : null}
|
||||
|
Reference in New Issue
Block a user