mirror of
https://github.com/casdoor/casdoor.git
synced 2025-08-30 19:50:27 +08:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2077db9091 | ||
![]() |
800f0ed249 | ||
![]() |
6161040c67 | ||
![]() |
1d785e61c6 | ||
![]() |
0329d24867 | ||
![]() |
fb6f3623ee | ||
![]() |
eb448bd043 | ||
![]() |
ea88839db9 |
@@ -16,6 +16,7 @@ ARG USER=casdoor
|
|||||||
|
|
||||||
RUN sed -i 's/https/http/' /etc/apk/repositories
|
RUN sed -i 's/https/http/' /etc/apk/repositories
|
||||||
RUN apk add --update sudo
|
RUN apk add --update sudo
|
||||||
|
RUN apk add tzdata
|
||||||
RUN apk add curl
|
RUN apk add curl
|
||||||
RUN apk add ca-certificates && update-ca-certificates
|
RUN apk add ca-certificates && update-ca-certificates
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@ socks5Proxy = "127.0.0.1:10808"
|
|||||||
verificationCodeTimeout = 10
|
verificationCodeTimeout = 10
|
||||||
initScore = 0
|
initScore = 0
|
||||||
logPostOnly = true
|
logPostOnly = true
|
||||||
|
isUsernameLowered = false
|
||||||
origin =
|
origin =
|
||||||
originFrontend =
|
originFrontend =
|
||||||
staticBaseUrl = "https://cdn.casbin.org"
|
staticBaseUrl = "https://cdn.casbin.org"
|
||||||
|
@@ -141,6 +141,20 @@ func (c *ApiController) GetProvider() {
|
|||||||
c.ResponseOk(object.GetMaskedProvider(provider, isMaskEnabled))
|
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
|
// UpdateProvider
|
||||||
// @Title UpdateProvider
|
// @Title UpdateProvider
|
||||||
// @Tag Provider API
|
// @Tag Provider API
|
||||||
@@ -159,6 +173,11 @@ func (c *ApiController) UpdateProvider() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok := c.requireProviderPermission(&provider)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.Data["json"] = wrapActionResponse(object.UpdateProvider(id, &provider))
|
c.Data["json"] = wrapActionResponse(object.UpdateProvider(id, &provider))
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
@@ -184,11 +203,17 @@ func (c *ApiController) AddProvider() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := checkQuotaForProvider(int(count)); err != nil {
|
err = checkQuotaForProvider(int(count))
|
||||||
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok := c.requireProviderPermission(&provider)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.Data["json"] = wrapActionResponse(object.AddProvider(&provider))
|
c.Data["json"] = wrapActionResponse(object.AddProvider(&provider))
|
||||||
c.ServeJSON()
|
c.ServeJSON()
|
||||||
}
|
}
|
||||||
@@ -208,6 +233,11 @@ func (c *ApiController) DeleteProvider() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok := c.requireProviderPermission(&provider)
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
c.Data["json"] = wrapActionResponse(object.DeleteProvider(&provider))
|
c.Data["json"] = wrapActionResponse(object.DeleteProvider(&provider))
|
||||||
c.ServeJSON()
|
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)
|
affected, err := ormer.Engine.Insert(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
@@ -846,6 +851,8 @@ func AddUsers(users []*User) (bool, error) {
|
|||||||
return false, fmt.Errorf("no users are provided")
|
return false, fmt.Errorf("no users are provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isUsernameLowered := conf.GetConfigBool("isUsernameLowered")
|
||||||
|
|
||||||
// organization := GetOrganizationByUser(users[0])
|
// organization := GetOrganizationByUser(users[0])
|
||||||
for _, user := range users {
|
for _, user := range users {
|
||||||
// this function is only used for syncer or batch upload, so no need to encrypt the password
|
// 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
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isUsernameLowered {
|
||||||
|
user.Name = strings.ToLower(user.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
affected, err := ormer.Engine.Insert(users)
|
affected, err := ormer.Engine.Insert(users)
|
||||||
|
@@ -374,6 +374,7 @@ class App extends Component {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
onLoginSuccess={(redirectUrl) => {
|
onLoginSuccess={(redirectUrl) => {
|
||||||
|
window.google?.accounts?.id?.cancel();
|
||||||
if (redirectUrl) {
|
if (redirectUrl) {
|
||||||
localStorage.setItem("mfaRedirectUrl", redirectUrl);
|
localStorage.setItem("mfaRedirectUrl", redirectUrl);
|
||||||
}
|
}
|
||||||
|
@@ -35,26 +35,48 @@ class VerificationListPage extends BaseListPage {
|
|||||||
renderTable(verifications) {
|
renderTable(verifications) {
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: i18next.t("general:Name"),
|
title: i18next.t("general:Organization"),
|
||||||
dataIndex: "name",
|
dataIndex: "owner",
|
||||||
key: "name",
|
key: "owner",
|
||||||
width: "150px",
|
width: "120px",
|
||||||
fixed: "left",
|
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("name"),
|
...this.getColumnSearchProps("owner"),
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
|
if (text === "admin") {
|
||||||
|
return `(${i18next.t("general:empty")})`;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link to={`/syncers/${text}`}>
|
<Link to={`/organizations/${text}`}>
|
||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Name"),
|
||||||
|
dataIndex: "name",
|
||||||
|
key: "name",
|
||||||
|
width: "260px",
|
||||||
|
fixed: "left",
|
||||||
|
sorter: true,
|
||||||
|
...this.getColumnSearchProps("name"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18next.t("general:Created time"),
|
||||||
|
dataIndex: "createdTime",
|
||||||
|
key: "createdTime",
|
||||||
|
width: "160px",
|
||||||
|
sorter: true,
|
||||||
|
render: (text, record, index) => {
|
||||||
|
return Setting.getFormattedDate(text);
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("provider:Type"),
|
title: i18next.t("provider:Type"),
|
||||||
dataIndex: "type",
|
dataIndex: "type",
|
||||||
key: "type",
|
key: "type",
|
||||||
width: "120px",
|
width: "90px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("type"),
|
...this.getColumnSearchProps("type"),
|
||||||
},
|
},
|
||||||
@@ -67,7 +89,7 @@ class VerificationListPage extends BaseListPage {
|
|||||||
...this.getColumnSearchProps("user"),
|
...this.getColumnSearchProps("user"),
|
||||||
render: (text, record, index) => {
|
render: (text, record, index) => {
|
||||||
return (
|
return (
|
||||||
<Link to={`/users/${record.owner}/${text}`}>
|
<Link to={`/users/${text}`}>
|
||||||
{text}
|
{text}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
@@ -100,30 +122,10 @@ class VerificationListPage extends BaseListPage {
|
|||||||
title: i18next.t("login:Verification code"),
|
title: i18next.t("login:Verification code"),
|
||||||
dataIndex: "code",
|
dataIndex: "code",
|
||||||
key: "code",
|
key: "code",
|
||||||
width: "120px",
|
width: "150px",
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps("code"),
|
...this.getColumnSearchProps("code"),
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: i18next.t("general:Timestamp"),
|
|
||||||
dataIndex: "time",
|
|
||||||
key: "time",
|
|
||||||
width: "160px",
|
|
||||||
sorter: true,
|
|
||||||
render: (text, record, index) => {
|
|
||||||
return Setting.getFormattedDate(text * 1000);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18next.t("general:Created time"),
|
|
||||||
dataIndex: "createdTime",
|
|
||||||
key: "createdTime",
|
|
||||||
width: "160px",
|
|
||||||
sorter: true,
|
|
||||||
render: (text, record, index) => {
|
|
||||||
return Setting.getFormattedDate(text);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const paginationProps = {
|
const paginationProps = {
|
||||||
@@ -156,7 +158,7 @@ class VerificationListPage extends BaseListPage {
|
|||||||
value = params.type;
|
value = params.type;
|
||||||
}
|
}
|
||||||
this.setState({loading: true});
|
this.setState({loading: true});
|
||||||
VerificationBackend.getVerifications("admin", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
VerificationBackend.getVerifications("", Setting.isDefaultOrganizationSelected(this.props.account) ? "" : Setting.getRequestOrganization(this.props.account), params.pagination.current, params.pagination.pageSize, field, value, sortField, sortOrder)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
|
@@ -21,7 +21,7 @@ import * as Setting from "../Setting";
|
|||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
import {SendCodeInput} from "../common/SendCodeInput";
|
import {SendCodeInput} from "../common/SendCodeInput";
|
||||||
import * as UserBackend from "../backend/UserBackend";
|
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 CustomGithubCorner from "../common/CustomGithubCorner";
|
||||||
import {withRouter} from "react-router-dom";
|
import {withRouter} from "react-router-dom";
|
||||||
import * as PasswordChecker from "../common/PasswordChecker";
|
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() {
|
render() {
|
||||||
const application = this.getApplicationObj();
|
const application = this.getApplicationObj();
|
||||||
if (application === undefined) {
|
if (application === undefined) {
|
||||||
@@ -456,6 +468,9 @@ class ForgetPage extends React.Component {
|
|||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<CustomGithubCorner />
|
<CustomGithubCorner />
|
||||||
<div className="forget-content" style={{padding: Setting.isMobile() ? "0" : null, boxShadow: Setting.isMobile() ? "none" : null}}>
|
<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>
|
<Row>
|
||||||
<Col span={24} style={{justifyContent: "center"}}>
|
<Col span={24} style={{justifyContent: "center"}}>
|
||||||
<Row>
|
<Row>
|
||||||
|
@@ -52,7 +52,7 @@ export function GoogleOneTapLoginVirtualButton(prop) {
|
|||||||
redirectUri = `${redirectUri}?state=${state}&code=${encodeURIComponent(code)}`;
|
redirectUri = `${redirectUri}?state=${state}&code=${encodeURIComponent(code)}`;
|
||||||
Setting.goToLink(redirectUri);
|
Setting.goToLink(redirectUri);
|
||||||
},
|
},
|
||||||
disableCancelOnUnmount: true,
|
disableCancelOnUnmount: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user