mirror of
https://github.com/casdoor/casdoor.git
synced 2025-07-10 01:56:49 +08:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
721a681ff1 | |||
8b1c4b0c75 | |||
540f22f8bd | |||
79f81f1356 | |||
4e145f71b5 | |||
104f975a2f | |||
71bb400559 | |||
93c3c78d42 |
@ -139,6 +139,10 @@ func (c *ApiController) GetUserApplication() {
|
|||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if application == nil {
|
||||||
|
c.ResponseError(fmt.Sprintf(c.T("general:The organization: %s should have one application at least"), user.Owner))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.ResponseOk(object.GetMaskedApplication(application, userId))
|
c.ResponseOk(object.GetMaskedApplication(application, userId))
|
||||||
}
|
}
|
||||||
|
@ -271,6 +271,14 @@ func (c *ApiController) RefreshToken() {
|
|||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ApiController) ResponseTokenError(errorMsg string) {
|
||||||
|
c.Data["json"] = &object.TokenError{
|
||||||
|
Error: errorMsg,
|
||||||
|
}
|
||||||
|
c.SetTokenErrorHttpStatus()
|
||||||
|
c.ServeJSON()
|
||||||
|
}
|
||||||
|
|
||||||
// IntrospectToken
|
// IntrospectToken
|
||||||
// @Title IntrospectToken
|
// @Title IntrospectToken
|
||||||
// @Tag Login API
|
// @Tag Login API
|
||||||
@ -293,40 +301,33 @@ func (c *ApiController) IntrospectToken() {
|
|||||||
clientId = c.Input().Get("client_id")
|
clientId = c.Input().Get("client_id")
|
||||||
clientSecret = c.Input().Get("client_secret")
|
clientSecret = c.Input().Get("client_secret")
|
||||||
if clientId == "" || clientSecret == "" {
|
if clientId == "" || clientSecret == "" {
|
||||||
c.ResponseError(c.T("token:Empty clientId or clientSecret"))
|
c.ResponseTokenError(object.InvalidRequest)
|
||||||
c.Data["json"] = &object.TokenError{
|
|
||||||
Error: object.InvalidRequest,
|
|
||||||
}
|
|
||||||
c.SetTokenErrorHttpStatus()
|
|
||||||
c.ServeJSON()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
application, err := object.GetApplicationByClientId(clientId)
|
application, err := object.GetApplicationByClientId(clientId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseTokenError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if application == nil || application.ClientSecret != clientSecret {
|
if application == nil || application.ClientSecret != clientSecret {
|
||||||
c.ResponseError(c.T("token:Invalid application or wrong clientSecret"))
|
c.ResponseTokenError(c.T("token:Invalid application or wrong clientSecret"))
|
||||||
c.Data["json"] = &object.TokenError{
|
|
||||||
Error: object.InvalidClient,
|
|
||||||
}
|
|
||||||
c.SetTokenErrorHttpStatus()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
token, err := object.GetTokenByTokenAndApplication(tokenValue, application.Name)
|
|
||||||
if err != nil {
|
|
||||||
c.ResponseError(err.Error())
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
token, err := object.GetTokenByTokenValue(tokenValue)
|
||||||
|
if err != nil {
|
||||||
|
c.ResponseTokenError(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
if token == nil {
|
if token == nil {
|
||||||
c.Data["json"] = &object.IntrospectionResponse{Active: false}
|
c.Data["json"] = &object.IntrospectionResponse{Active: false}
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
jwtToken, err := object.ParseJwtTokenByApplication(tokenValue, application)
|
jwtToken, err := object.ParseJwtTokenByApplication(tokenValue, application)
|
||||||
if err != nil || jwtToken.Valid() != nil {
|
if err != nil || jwtToken.Valid() != nil {
|
||||||
// and token revoked case. but we not implement
|
// and token revoked case. but we not implement
|
||||||
|
@ -186,6 +186,26 @@ func GetTokenByRefreshToken(refreshToken string) (*Token, error) {
|
|||||||
return &token, nil
|
return &token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetTokenByTokenValue(tokenValue string) (*Token, error) {
|
||||||
|
token, err := GetTokenByAccessToken(tokenValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err = GetTokenByRefreshToken(tokenValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if token != nil {
|
||||||
|
return token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func updateUsedByCode(token *Token) bool {
|
func updateUsedByCode(token *Token) bool {
|
||||||
affected, err := ormer.Engine.Where("code=?", token.Code).Cols("code_is_used").Update(token)
|
affected, err := ormer.Engine.Where("code=?", token.Code).Cols("code_is_used").Update(token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -283,20 +303,6 @@ func ExpireTokenByAccessToken(accessToken string) (bool, *Application, *Token, e
|
|||||||
return affected != 0, application, token, nil
|
return affected != 0, application, token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTokenByTokenAndApplication(token string, application string) (*Token, error) {
|
|
||||||
tokenResult := Token{}
|
|
||||||
existed, err := ormer.Engine.Where("(refresh_token = ? or access_token = ? ) and application = ?", token, token, application).Get(&tokenResult)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !existed {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &tokenResult, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CheckOAuthLogin(clientId string, responseType string, redirectUri string, scope string, state string, lang string) (string, *Application, error) {
|
func CheckOAuthLogin(clientId string, responseType string, redirectUri string, scope string, state string, lang string) (string, *Application, error) {
|
||||||
if responseType != "code" && responseType != "token" && responseType != "id_token" {
|
if responseType != "code" && responseType != "token" && responseType != "id_token" {
|
||||||
return fmt.Sprintf(i18n.Translate(lang, "token:Grant_type: %s is not supported in this application"), responseType), nil, nil
|
return fmt.Sprintf(i18n.Translate(lang, "token:Grant_type: %s is not supported in this application"), responseType), nil, nil
|
||||||
|
@ -40,7 +40,7 @@ type UserShort struct {
|
|||||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||||
Avatar string `xorm:"varchar(500)" json:"avatar"`
|
Avatar string `xorm:"varchar(500)" json:"avatar"`
|
||||||
Email string `xorm:"varchar(100) index" json:"email"`
|
Email string `xorm:"varchar(100) index" json:"email"`
|
||||||
Phone string `xorm:"varchar(20) index" json:"phone"`
|
Phone string `xorm:"varchar(100) index" json:"phone"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserWithoutThirdIdp struct {
|
type UserWithoutThirdIdp struct {
|
||||||
@ -62,7 +62,7 @@ type UserWithoutThirdIdp struct {
|
|||||||
PermanentAvatar string `xorm:"varchar(500)" json:"permanentAvatar"`
|
PermanentAvatar string `xorm:"varchar(500)" json:"permanentAvatar"`
|
||||||
Email string `xorm:"varchar(100) index" json:"email"`
|
Email string `xorm:"varchar(100) index" json:"email"`
|
||||||
EmailVerified bool `json:"emailVerified"`
|
EmailVerified bool `json:"emailVerified"`
|
||||||
Phone string `xorm:"varchar(20) index" json:"phone"`
|
Phone string `xorm:"varchar(100) index" json:"phone"`
|
||||||
CountryCode string `xorm:"varchar(6)" json:"countryCode"`
|
CountryCode string `xorm:"varchar(6)" json:"countryCode"`
|
||||||
Region string `xorm:"varchar(100)" json:"region"`
|
Region string `xorm:"varchar(100)" json:"region"`
|
||||||
Location string `xorm:"varchar(100)" json:"location"`
|
Location string `xorm:"varchar(100)" json:"location"`
|
||||||
|
@ -64,7 +64,7 @@ type User struct {
|
|||||||
PermanentAvatar string `xorm:"varchar(500)" json:"permanentAvatar"`
|
PermanentAvatar string `xorm:"varchar(500)" json:"permanentAvatar"`
|
||||||
Email string `xorm:"varchar(100) index" json:"email"`
|
Email string `xorm:"varchar(100) index" json:"email"`
|
||||||
EmailVerified bool `json:"emailVerified"`
|
EmailVerified bool `json:"emailVerified"`
|
||||||
Phone string `xorm:"varchar(20) index" json:"phone"`
|
Phone string `xorm:"varchar(100) index" json:"phone"`
|
||||||
CountryCode string `xorm:"varchar(6)" json:"countryCode"`
|
CountryCode string `xorm:"varchar(6)" json:"countryCode"`
|
||||||
Region string `xorm:"varchar(100)" json:"region"`
|
Region string `xorm:"varchar(100)" json:"region"`
|
||||||
Location string `xorm:"varchar(100)" json:"location"`
|
Location string `xorm:"varchar(100)" json:"location"`
|
||||||
@ -639,7 +639,7 @@ func UpdateUser(id string, user *User, columns []string, isAdmin bool) (bool, er
|
|||||||
if len(columns) == 0 {
|
if len(columns) == 0 {
|
||||||
columns = []string{
|
columns = []string{
|
||||||
"owner", "display_name", "avatar", "first_name", "last_name",
|
"owner", "display_name", "avatar", "first_name", "last_name",
|
||||||
"location", "address", "country_code", "region", "language", "affiliation", "title", "homepage", "bio", "tag", "language", "gender", "birthday", "education", "score", "karma", "ranking", "signup_application",
|
"location", "address", "country_code", "region", "language", "affiliation", "title", "id_card_type", "id_card", "homepage", "bio", "tag", "language", "gender", "birthday", "education", "score", "karma", "ranking", "signup_application",
|
||||||
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts",
|
"is_admin", "is_forbidden", "is_deleted", "hash", "is_default_avatar", "properties", "webauthnCredentials", "managedAccounts",
|
||||||
"signin_wrong_times", "last_signin_wrong_time", "groups", "access_key", "access_secret",
|
"signin_wrong_times", "last_signin_wrong_time", "groups", "access_key", "access_secret",
|
||||||
"github", "google", "qq", "wechat", "facebook", "dingtalk", "weibo", "gitee", "linkedin", "wecom", "lark", "gitlab", "adfs",
|
"github", "google", "qq", "wechat", "facebook", "dingtalk", "weibo", "gitee", "linkedin", "wecom", "lark", "gitlab", "adfs",
|
||||||
|
@ -122,6 +122,17 @@ class UserEditPage extends React.Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
applications: res.data || [],
|
applications: res.data || [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const applications = res.data;
|
||||||
|
if (this.state.user) {
|
||||||
|
if (this.state.user.signupApplication === "" || applications.filter(application => application.name === this.state.user.signupApplication).length === 0) {
|
||||||
|
if (applications.length > 0) {
|
||||||
|
this.updateUserField("signupApplication", applications[0].name);
|
||||||
|
} else {
|
||||||
|
this.updateUserField("signupApplication", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,11 +901,9 @@ class UserEditPage extends React.Component {
|
|||||||
</Space>
|
</Space>
|
||||||
{item.enabled ? (
|
{item.enabled ? (
|
||||||
<Space>
|
<Space>
|
||||||
{item.enabled ?
|
<Tag icon={<CheckCircleOutlined />} color="success">
|
||||||
<Tag icon={<CheckCircleOutlined />} color="success">
|
{i18next.t("general:Enabled")}
|
||||||
{i18next.t("general:Enabled")}
|
</Tag>
|
||||||
</Tag> : null
|
|
||||||
}
|
|
||||||
{item.isPreferred ?
|
{item.isPreferred ?
|
||||||
<Tag icon={<CheckCircleOutlined />} color="blue" style={{marginRight: 20}} >
|
<Tag icon={<CheckCircleOutlined />} color="blue" style={{marginRight: 20}} >
|
||||||
{i18next.t("mfa:preferred")}
|
{i18next.t("mfa:preferred")}
|
||||||
@ -916,18 +925,23 @@ class UserEditPage extends React.Component {
|
|||||||
{i18next.t("mfa:Set preferred")}
|
{i18next.t("mfa:Set preferred")}
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
|
{this.isSelf() ? <Button type={"default"} onClick={() => {
|
||||||
|
this.props.history.push(`/mfa/setup?mfaType=${item.mfaType}`);
|
||||||
|
}}>
|
||||||
|
{i18next.t("general:Edit")}
|
||||||
|
</Button> : null}
|
||||||
</Space>
|
</Space>
|
||||||
) :
|
) :
|
||||||
<Space>
|
<Space>
|
||||||
{item.mfaType !== TotpMfaType && Setting.isAdminUser(this.props.account) && window.location.href.indexOf("/users") !== -1 ?
|
{item.mfaType !== TotpMfaType && Setting.isLocalAdminUser(this.props.account) && !this.isSelf() ?
|
||||||
<EnableMfaModal user={this.state.user} mfaType={item.mfaType} onSuccess={() => {
|
<EnableMfaModal user={this.state.user} mfaType={item.mfaType} onSuccess={() => {
|
||||||
this.getUser();
|
this.getUser();
|
||||||
}} /> : null}
|
}} /> : null}
|
||||||
<Button type={"default"} onClick={() => {
|
{this.isSelf() ? <Button type={"default"} onClick={() => {
|
||||||
this.props.history.push(`/mfa/setup?mfaType=${item.mfaType}`);
|
this.props.history.push(`/mfa/setup?mfaType=${item.mfaType}`);
|
||||||
}}>
|
}}>
|
||||||
{i18next.t("mfa:Setup")}
|
{i18next.t("mfa:Setup")}
|
||||||
</Button>
|
</Button> : null}
|
||||||
</Space>}
|
</Space>}
|
||||||
</List.Item>
|
</List.Item>
|
||||||
)}
|
)}
|
||||||
|
@ -70,7 +70,7 @@ class UserListPage extends BaseListPage {
|
|||||||
password: "123",
|
password: "123",
|
||||||
passwordSalt: "",
|
passwordSalt: "",
|
||||||
displayName: `New User - ${randomName}`,
|
displayName: `New User - ${randomName}`,
|
||||||
avatar: `${Setting.StaticBaseUrl}/img/casbin.svg`,
|
avatar: this.state.organization.defaultAvatar ?? `${Setting.StaticBaseUrl}/img/casbin.svg`,
|
||||||
email: `${randomName}@example.com`,
|
email: `${randomName}@example.com`,
|
||||||
phone: Setting.getRandomNumber(),
|
phone: Setting.getRandomNumber(),
|
||||||
countryCode: this.state.organization.countryCodes?.length > 0 ? this.state.organization.countryCodes[0] : "",
|
countryCode: this.state.organization.countryCodes?.length > 0 ? this.state.organization.countryCodes[0] : "",
|
||||||
|
@ -98,7 +98,7 @@ class MfaSetupPage extends React.Component {
|
|||||||
|
|
||||||
renderMfaTypeSwitch() {
|
renderMfaTypeSwitch() {
|
||||||
const renderSmsLink = () => {
|
const renderSmsLink = () => {
|
||||||
if (this.state.mfaType === SmsMfaType || this.props.account.mfaPhoneEnabled) {
|
if (this.state.mfaType === SmsMfaType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (<Button type={"link"} onClick={() => {
|
return (<Button type={"link"} onClick={() => {
|
||||||
@ -112,7 +112,7 @@ class MfaSetupPage extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderEmailLink = () => {
|
const renderEmailLink = () => {
|
||||||
if (this.state.mfaType === EmailMfaType || this.props.account.mfaEmailEnabled) {
|
if (this.state.mfaType === EmailMfaType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (<Button type={"link"} onClick={() => {
|
return (<Button type={"link"} onClick={() => {
|
||||||
@ -126,7 +126,7 @@ class MfaSetupPage extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderTotpLink = () => {
|
const renderTotpLink = () => {
|
||||||
if (this.state.mfaType === TotpMfaType || this.props.account.totpSecret !== "") {
|
if (this.state.mfaType === TotpMfaType) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (<Button type={"link"} onClick={() => {
|
return (<Button type={"link"} onClick={() => {
|
||||||
@ -191,7 +191,9 @@ class MfaSetupPage extends React.Component {
|
|||||||
onSuccess={() => {
|
onSuccess={() => {
|
||||||
Setting.showMessage("success", i18next.t("general:Enabled successfully"));
|
Setting.showMessage("success", i18next.t("general:Enabled successfully"));
|
||||||
this.props.onfinish();
|
this.props.onfinish();
|
||||||
if (localStorage.getItem("mfaRedirectUrl") !== null) {
|
|
||||||
|
const mfaRedirectUrl = localStorage.getItem("mfaRedirectUrl");
|
||||||
|
if (mfaRedirectUrl !== undefined && mfaRedirectUrl !== null) {
|
||||||
Setting.goToLink(localStorage.getItem("mfaRedirectUrl"));
|
Setting.goToLink(localStorage.getItem("mfaRedirectUrl"));
|
||||||
localStorage.removeItem("mfaRedirectUrl");
|
localStorage.removeItem("mfaRedirectUrl");
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user