mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-19 16:40:36 +08:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
cdcc0b39e2 | ||
![]() |
8eb68ba817 | ||
![]() |
8d1ae4ea08 | ||
![]() |
9c8ea027ef | ||
![]() |
aaa56d3354 | ||
![]() |
b45c49d3a4 | ||
![]() |
5b3202cc89 | ||
![]() |
5280f872dc |
@@ -84,6 +84,7 @@ func (c *ApiController) GetUsers() {
|
||||
// @Param owner query string false "The owner of the user"
|
||||
// @Param email query string false "The email of the user"
|
||||
// @Param phone query string false "The phone of the user"
|
||||
// @Param userId query string false "The userId of the user"
|
||||
// @Success 200 {object} object.User The Response object
|
||||
// @router /get-user [get]
|
||||
func (c *ApiController) GetUser() {
|
||||
|
@@ -108,8 +108,8 @@ func (idp *CasdoorIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
|
||||
type CasdoorUserInfo struct {
|
||||
Id string `json:"sub"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"preferred_username"`
|
||||
Name string `json:"preferred_username,omitempty"`
|
||||
DisplayName string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
AvatarUrl string `json:"picture"`
|
||||
Status string `json:"status"`
|
||||
|
@@ -61,8 +61,8 @@ func (idp *CustomIdProvider) GetToken(code string) (*oauth2.Token, error) {
|
||||
|
||||
type CustomUserInfo struct {
|
||||
Id string `json:"sub"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"preferred_username"`
|
||||
Name string `json:"preferred_username,omitempty"`
|
||||
DisplayName string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
AvatarUrl string `json:"picture"`
|
||||
Status string `json:"status"`
|
||||
|
@@ -88,7 +88,7 @@ type GothIdProvider struct {
|
||||
Session goth.Session
|
||||
}
|
||||
|
||||
func NewGothIdProvider(providerType string, clientId string, clientSecret string, redirectUrl string) *GothIdProvider {
|
||||
func NewGothIdProvider(providerType string, clientId string, clientSecret string, redirectUrl string, hostUrl string) *GothIdProvider {
|
||||
var idp GothIdProvider
|
||||
switch providerType {
|
||||
case "Amazon":
|
||||
@@ -102,8 +102,13 @@ func NewGothIdProvider(providerType string, clientId string, clientSecret string
|
||||
Session: &apple.Session{},
|
||||
}
|
||||
case "AzureAD":
|
||||
domain := "common"
|
||||
if hostUrl != "" {
|
||||
domain = hostUrl
|
||||
}
|
||||
|
||||
idp = GothIdProvider{
|
||||
Provider: azureadv2.New(clientId, clientSecret, redirectUrl, azureadv2.ProviderOptions{Tenant: "common"}),
|
||||
Provider: azureadv2.New(clientId, clientSecret, redirectUrl, azureadv2.ProviderOptions{Tenant: azureadv2.TenantType(domain)}),
|
||||
Session: &azureadv2.Session{},
|
||||
}
|
||||
case "Auth0":
|
||||
|
@@ -90,7 +90,7 @@ func GetIdProvider(typ string, subType string, clientId string, clientSecret str
|
||||
} else if typ == "Douyin" {
|
||||
return NewDouyinIdProvider(clientId, clientSecret, redirectUrl)
|
||||
} else if isGothSupport(typ) {
|
||||
return NewGothIdProvider(typ, clientId, clientSecret, redirectUrl)
|
||||
return NewGothIdProvider(typ, clientId, clientSecret, redirectUrl, hostUrl)
|
||||
} else if typ == "Bilibili" {
|
||||
return NewBilibiliIdProvider(clientId, clientSecret, redirectUrl)
|
||||
}
|
||||
|
@@ -86,19 +86,30 @@ func NewSamlResponse(user *User, host string, certificate string, destination st
|
||||
authnStatement.CreateElement("saml:AuthnContext").CreateElement("saml:AuthnContextClassRef").SetText("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport")
|
||||
|
||||
attributes := assertion.CreateElement("saml:AttributeStatement")
|
||||
|
||||
email := attributes.CreateElement("saml:Attribute")
|
||||
email.CreateAttr("Name", "Email")
|
||||
email.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
|
||||
email.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.Email)
|
||||
|
||||
name := attributes.CreateElement("saml:Attribute")
|
||||
name.CreateAttr("Name", "Name")
|
||||
name.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
|
||||
name.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.Name)
|
||||
|
||||
displayName := attributes.CreateElement("saml:Attribute")
|
||||
displayName.CreateAttr("Name", "DisplayName")
|
||||
displayName.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
|
||||
displayName.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(user.DisplayName)
|
||||
|
||||
roles := attributes.CreateElement("saml:Attribute")
|
||||
roles.CreateAttr("Name", "Roles")
|
||||
roles.CreateAttr("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:basic")
|
||||
ExtendUserWithRolesAndPermissions(user)
|
||||
for _, role := range user.Roles {
|
||||
roles.CreateElement("saml:AttributeValue").CreateAttr("xsi:type", "xs:string").Element().SetText(role.Name)
|
||||
}
|
||||
|
||||
return samlResponse, nil
|
||||
}
|
||||
|
||||
|
@@ -51,7 +51,7 @@ type Token struct {
|
||||
Organization string `xorm:"varchar(100)" json:"organization"`
|
||||
User string `xorm:"varchar(100)" json:"user"`
|
||||
|
||||
Code string `xorm:"varchar(100)" json:"code"`
|
||||
Code string `xorm:"varchar(100) index" json:"code"`
|
||||
AccessToken string `xorm:"mediumtext" json:"accessToken"`
|
||||
RefreshToken string `xorm:"mediumtext" json:"refreshToken"`
|
||||
ExpiresIn int `json:"expiresIn"`
|
||||
@@ -362,7 +362,8 @@ func GetOAuthToken(grantType string, clientId string, clientSecret string, code
|
||||
}
|
||||
|
||||
token.CodeIsUsed = true
|
||||
updateUsedByCode(token)
|
||||
go updateUsedByCode(token)
|
||||
|
||||
tokenWrapper := &TokenWrapper{
|
||||
AccessToken: token.AccessToken,
|
||||
IdToken: token.AccessToken,
|
||||
|
@@ -2171,6 +2171,12 @@
|
||||
"name": "phone",
|
||||
"description": "The phone of the user",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "userId",
|
||||
"description": "The userId of the user",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -3638,11 +3644,11 @@
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"2306.0xc0000a7410.false": {
|
||||
"2306.0xc0003a4480.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
"2340.0xc0000a7440.false": {
|
||||
"2340.0xc0003a44b0.false": {
|
||||
"title": "false",
|
||||
"type": "object"
|
||||
},
|
||||
@@ -3776,10 +3782,10 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/definitions/2306.0xc0000a7410.false"
|
||||
"$ref": "#/definitions/2306.0xc0003a4480.false"
|
||||
},
|
||||
"data2": {
|
||||
"$ref": "#/definitions/2340.0xc0000a7440.false"
|
||||
"$ref": "#/definitions/2340.0xc0003a44b0.false"
|
||||
},
|
||||
"msg": {
|
||||
"type": "string"
|
||||
|
@@ -1417,6 +1417,10 @@ paths:
|
||||
name: phone
|
||||
description: The phone of the user
|
||||
type: string
|
||||
- in: query
|
||||
name: userId
|
||||
description: The userId of the user
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: The Response object
|
||||
@@ -2381,10 +2385,10 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/Response'
|
||||
definitions:
|
||||
2306.0xc0000a7410.false:
|
||||
2306.0xc0003a4480.false:
|
||||
title: "false"
|
||||
type: object
|
||||
2340.0xc0000a7440.false:
|
||||
2340.0xc0003a44b0.false:
|
||||
title: "false"
|
||||
type: object
|
||||
LaravelResponse:
|
||||
@@ -2476,9 +2480,9 @@ definitions:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/definitions/2306.0xc0000a7410.false'
|
||||
$ref: '#/definitions/2306.0xc0003a4480.false'
|
||||
data2:
|
||||
$ref: '#/definitions/2340.0xc0000a7440.false'
|
||||
$ref: '#/definitions/2340.0xc0003a44b0.false'
|
||||
msg:
|
||||
type: string
|
||||
name:
|
||||
|
@@ -867,6 +867,8 @@ class ApplicationEditPage extends React.Component {
|
||||
|
||||
submitApplicationEdit(willExist) {
|
||||
const application = Setting.deepCopy(this.state.application);
|
||||
application.providers = application.providers?.filter(provider => this.state.providers.map(provider => provider.name).includes(provider.name));
|
||||
|
||||
ApplicationBackend.updateApplication("admin", this.state.applicationName, application)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
|
@@ -614,7 +614,7 @@ class UserEditPage extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
submitUserEdit(willExist) {
|
||||
submitUserEdit(needExit) {
|
||||
const user = Setting.deepCopy(this.state.user);
|
||||
UserBackend.updateUser(this.state.organizationName, this.state.userName, user)
|
||||
.then((res) => {
|
||||
@@ -626,13 +626,18 @@ class UserEditPage extends React.Component {
|
||||
});
|
||||
|
||||
if (this.props.history !== undefined) {
|
||||
if (willExist) {
|
||||
this.props.history.push("/users");
|
||||
if (needExit) {
|
||||
const userListUrl = sessionStorage.getItem("userListUrl");
|
||||
if (userListUrl !== null) {
|
||||
this.props.history.push(userListUrl);
|
||||
} else {
|
||||
this.props.history.push("/users");
|
||||
}
|
||||
} else {
|
||||
this.props.history.push(`/users/${this.state.user.owner}/${this.state.user.name}`);
|
||||
}
|
||||
} else {
|
||||
if (willExist) {
|
||||
if (needExit) {
|
||||
if (this.state.returnUrl) {
|
||||
window.location.href = this.state.returnUrl;
|
||||
}
|
||||
|
@@ -70,6 +70,7 @@ class UserListPage extends BaseListPage {
|
||||
UserBackend.addUser(newUser)
|
||||
.then((res) => {
|
||||
if (res.status === "ok") {
|
||||
sessionStorage.setItem("userListUrl", window.location.pathname);
|
||||
this.props.history.push({pathname: `/users/${newUser.owner}/${newUser.name}`, mode: "add"});
|
||||
Setting.showMessage("success", i18next.t("general:Successfully added"));
|
||||
} else {
|
||||
@@ -341,7 +342,10 @@ class UserListPage extends BaseListPage {
|
||||
const disabled = (record.owner === this.props.account.owner && record.name === this.props.account.name);
|
||||
return (
|
||||
<div>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => this.props.history.push(`/users/${record.owner}/${record.name}`)}>{i18next.t("general:Edit")}</Button>
|
||||
<Button style={{marginTop: "10px", marginBottom: "10px", marginRight: "10px"}} type="primary" onClick={() => {
|
||||
sessionStorage.setItem("userListUrl", window.location.pathname);
|
||||
this.props.history.push(`/users/${record.owner}/${record.name}`);
|
||||
}}>{i18next.t("general:Edit")}</Button>
|
||||
<PopconfirmModal
|
||||
title={i18next.t("general:Sure to delete") + `: ${record.name} ?`}
|
||||
onConfirm={() => this.deleteUser(index)}
|
||||
@@ -402,6 +406,8 @@ class UserListPage extends BaseListPage {
|
||||
const users = res.data;
|
||||
if (users.length > 0) {
|
||||
this.getOrganization(users[0].owner);
|
||||
} else {
|
||||
this.getOrganization(this.state.organizationName);
|
||||
}
|
||||
} else {
|
||||
if (Setting.isResponseDenied(res)) {
|
||||
@@ -430,6 +436,8 @@ class UserListPage extends BaseListPage {
|
||||
const users = res.data;
|
||||
if (users.length > 0) {
|
||||
this.getOrganization(users[0].owner);
|
||||
} else {
|
||||
this.getOrganization(this.state.organizationName);
|
||||
}
|
||||
} else {
|
||||
if (Setting.isResponseDenied(res)) {
|
||||
|
@@ -386,11 +386,11 @@ class SignupPage extends React.Component {
|
||||
},
|
||||
({getFieldValue}) => ({
|
||||
validator: (_, value) => {
|
||||
if (!required && value === "") {
|
||||
if (!required && !value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
if (value !== "" && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
|
||||
if (value && !Setting.isValidPhone(value, getFieldValue("countryCode"))) {
|
||||
this.setState({validPhone: false});
|
||||
return Promise.reject(i18next.t("signup:The input is not valid Phone!"));
|
||||
}
|
||||
|
@@ -55,11 +55,10 @@ export function getUserApplication(owner, name) {
|
||||
}
|
||||
|
||||
export function updateApplication(owner, name, application) {
|
||||
const newApplication = Setting.deepCopy(application);
|
||||
return fetch(`${Setting.ServerUrl}/api/update-application?id=${owner}/${encodeURIComponent(name)}`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
body: JSON.stringify(newApplication),
|
||||
body: JSON.stringify(application),
|
||||
headers: {
|
||||
"Accept-Language": Setting.getAcceptLanguage(),
|
||||
},
|
||||
|
Reference in New Issue
Block a user