mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-26 09:10:22 +08:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
800f0ed249 | ||
![]() |
6161040c67 | ||
![]() |
1d785e61c6 | ||
![]() |
0329d24867 | ||
![]() |
fb6f3623ee | ||
![]() |
eb448bd043 | ||
![]() |
ea88839db9 | ||
![]() |
cb95f6977a | ||
![]() |
9067df92a7 | ||
![]() |
bfa2ab63ad |
@@ -16,6 +16,7 @@ ARG USER=casdoor
|
||||
|
||||
RUN sed -i 's/https/http/' /etc/apk/repositories
|
||||
RUN apk add --update sudo
|
||||
RUN apk add tzdata
|
||||
RUN apk add curl
|
||||
RUN apk add ca-certificates && update-ca-certificates
|
||||
|
||||
|
@@ -15,6 +15,7 @@ socks5Proxy = "127.0.0.1:10808"
|
||||
verificationCodeTimeout = 10
|
||||
initScore = 0
|
||||
logPostOnly = true
|
||||
isUsernameLowered = false
|
||||
origin =
|
||||
originFrontend =
|
||||
staticBaseUrl = "https://cdn.casbin.org"
|
||||
|
@@ -141,6 +141,20 @@ func (c *ApiController) GetProvider() {
|
||||
c.ResponseOk(object.GetMaskedProvider(provider, isMaskEnabled))
|
||||
}
|
||||
|
||||
func (c *ApiController) requireProviderPermission(provider *object.Provider) bool {
|
||||
isGlobalAdmin, user := c.isGlobalAdmin()
|
||||
if isGlobalAdmin {
|
||||
return true
|
||||
}
|
||||
|
||||
if provider.Owner == "admin" || user.Owner != provider.Owner {
|
||||
c.ResponseError(c.T("auth:Unauthorized operation"))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// UpdateProvider
|
||||
// @Title UpdateProvider
|
||||
// @Tag Provider API
|
||||
@@ -159,6 +173,11 @@ func (c *ApiController) UpdateProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
ok := c.requireProviderPermission(&provider)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.UpdateProvider(id, &provider))
|
||||
c.ServeJSON()
|
||||
}
|
||||
@@ -184,11 +203,17 @@ func (c *ApiController) AddProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
if err := checkQuotaForProvider(int(count)); err != nil {
|
||||
err = checkQuotaForProvider(int(count))
|
||||
if err != nil {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
ok := c.requireProviderPermission(&provider)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.AddProvider(&provider))
|
||||
c.ServeJSON()
|
||||
}
|
||||
@@ -208,6 +233,11 @@ func (c *ApiController) DeleteProvider() {
|
||||
return
|
||||
}
|
||||
|
||||
ok := c.requireProviderPermission(&provider)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
c.Data["json"] = wrapActionResponse(object.DeleteProvider(&provider))
|
||||
c.ServeJSON()
|
||||
}
|
||||
|
@@ -833,6 +833,11 @@ func AddUser(user *User) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
|
||||
if isUsernameLowered {
|
||||
user.Name = strings.ToLower(user.Name)
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.Insert(user)
|
||||
if err != nil {
|
||||
return false, err
|
||||
@@ -846,6 +851,8 @@ func AddUsers(users []*User) (bool, error) {
|
||||
return false, fmt.Errorf("no users are provided")
|
||||
}
|
||||
|
||||
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
|
||||
|
||||
// organization := GetOrganizationByUser(users[0])
|
||||
for _, user := range users {
|
||||
// this function is only used for syncer or batch upload, so no need to encrypt the password
|
||||
@@ -869,6 +876,10 @@ func AddUsers(users []*User) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
if isUsernameLowered {
|
||||
user.Name = strings.ToLower(user.Name)
|
||||
}
|
||||
}
|
||||
|
||||
affected, err := ormer.Engine.Insert(users)
|
||||
|
@@ -374,6 +374,7 @@ class App extends Component {
|
||||
});
|
||||
}}
|
||||
onLoginSuccess={(redirectUrl) => {
|
||||
window.google?.accounts?.id?.cancel();
|
||||
if (redirectUrl) {
|
||||
localStorage.setItem("mfaRedirectUrl", redirectUrl);
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Form, Input, InputNumber, List, Result, Row, Select, Space, Spin, Switch, Tag} from "antd";
|
||||
import {Button, Card, Col, Form, Input, InputNumber, List, Result, Row, Select, Space, Spin, Switch, Tag, Tooltip} from "antd";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import {TotpMfaType} from "./auth/MfaSetupPage";
|
||||
import * as GroupBackend from "./backend/GroupBackend";
|
||||
@@ -407,7 +407,17 @@ class UserEditPage extends React.Component {
|
||||
{Setting.getLabel(i18next.t("general:Password"), i18next.t("general:Password - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={22} >
|
||||
<PasswordModal user={this.state.user} userName={this.state.userName} organization={this.getUserOrganization()} account={this.props.account} disabled={disabled} />
|
||||
{
|
||||
(this.state.user.name === this.state.userName) ? (
|
||||
<PasswordModal user={this.state.user} userName={this.state.userName} organization={this.getUserOrganization()} account={this.props.account} disabled={disabled} />
|
||||
) : (
|
||||
<Tooltip placement={"topLeft"} title={i18next.t("user:You have changed the username, please save your change first before modifying the password")}>
|
||||
<span>
|
||||
<PasswordModal user={this.state.user} userName={this.state.userName} organization={this.getUserOrganization()} account={this.props.account} disabled={true} />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
|
@@ -21,7 +21,7 @@ import * as Setting from "../Setting";
|
||||
import i18next from "i18next";
|
||||
import {SendCodeInput} from "../common/SendCodeInput";
|
||||
import * as UserBackend from "../backend/UserBackend";
|
||||
import {CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import {ArrowLeftOutlined, CheckCircleOutlined, KeyOutlined, LockOutlined, SolutionOutlined, UserOutlined} from "@ant-design/icons";
|
||||
import CustomGithubCorner from "../common/CustomGithubCorner";
|
||||
import {withRouter} from "react-router-dom";
|
||||
import * as PasswordChecker from "../common/PasswordChecker";
|
||||
@@ -443,6 +443,18 @@ class ForgetPage extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
stepBack() {
|
||||
if (this.state.current > 0) {
|
||||
this.setState({
|
||||
current: this.state.current - 1,
|
||||
});
|
||||
} else if (this.props.history.length > 1) {
|
||||
this.props.history.goBack();
|
||||
} else {
|
||||
Setting.redirectToLoginPage(this.getApplicationObj(), this.props.history);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const application = this.getApplicationObj();
|
||||
if (application === undefined) {
|
||||
@@ -456,6 +468,9 @@ class ForgetPage extends React.Component {
|
||||
<React.Fragment>
|
||||
<CustomGithubCorner />
|
||||
<div className="forget-content" style={{padding: Setting.isMobile() ? "0" : null, boxShadow: Setting.isMobile() ? "none" : null}}>
|
||||
<Button type="text" style={{position: "relative", left: Setting.isMobile() ? "10px" : "-90px", top: 0}} size={"large"} onClick={() => {this.stepBack();}}>
|
||||
<ArrowLeftOutlined style={{fontSize: "24px"}} />
|
||||
</Button>
|
||||
<Row>
|
||||
<Col span={24} style={{justifyContent: "center"}}>
|
||||
<Row>
|
||||
|
@@ -52,7 +52,7 @@ export function GoogleOneTapLoginVirtualButton(prop) {
|
||||
redirectUri = `${redirectUri}?state=${state}&code=${encodeURIComponent(code)}`;
|
||||
Setting.goToLink(redirectUri);
|
||||
},
|
||||
disableCancelOnUnmount: true,
|
||||
disableCancelOnUnmount: false,
|
||||
});
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user