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