mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
feat: add isProfilePublic setting for accessing user info (#656)
* feat: add isProfilePublic setting for accessing user info Signed-off-by: Yixiang Zhao <seriouszyx@foxmail.com> * fix: requested changes Signed-off-by: Yixiang Zhao <seriouszyx@foxmail.com>
This commit is contained in:
parent
70a1428972
commit
530330bd66
@ -87,6 +87,17 @@ func (c *ApiController) GetUser() {
|
||||
id := c.Input().Get("id")
|
||||
owner := c.Input().Get("owner")
|
||||
email := c.Input().Get("email")
|
||||
userOwner, _ := util.GetOwnerAndNameFromId(id)
|
||||
organization := object.GetOrganization(fmt.Sprintf("%s/%s", "admin", userOwner))
|
||||
|
||||
if !organization.IsProfilePublic {
|
||||
requestUserId := c.GetSessionUsername()
|
||||
hasPermission, err := object.CheckUserPermission(requestUserId, id, false)
|
||||
if !hasPermission {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var user *object.User
|
||||
if email == "" {
|
||||
@ -233,39 +244,15 @@ func (c *ApiController) SetPassword() {
|
||||
newPassword := c.Ctx.Request.Form.Get("newPassword")
|
||||
|
||||
requestUserId := c.GetSessionUsername()
|
||||
if requestUserId == "" {
|
||||
c.ResponseError("Please login first")
|
||||
return
|
||||
}
|
||||
|
||||
userId := fmt.Sprintf("%s/%s", userOwner, userName)
|
||||
targetUser := object.GetUser(userId)
|
||||
if targetUser == nil {
|
||||
c.ResponseError(fmt.Sprintf("The user: %s doesn't exist", userId))
|
||||
|
||||
hasPermission, err := object.CheckUserPermission(requestUserId, userId, true)
|
||||
if !hasPermission {
|
||||
c.ResponseError(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
hasPermission := false
|
||||
if strings.HasPrefix(requestUserId, "app/") {
|
||||
hasPermission = true
|
||||
} else {
|
||||
requestUser := object.GetUser(requestUserId)
|
||||
if requestUser == nil {
|
||||
c.ResponseError("Session outdated. Please login again.")
|
||||
return
|
||||
}
|
||||
if requestUser.IsGlobalAdmin {
|
||||
hasPermission = true
|
||||
} else if requestUserId == userId {
|
||||
hasPermission = true
|
||||
} else if targetUser.Owner == requestUser.Owner && requestUser.IsAdmin {
|
||||
hasPermission = true
|
||||
}
|
||||
}
|
||||
if !hasPermission {
|
||||
c.ResponseError("You don't have the permission to do this.")
|
||||
return
|
||||
}
|
||||
targetUser := object.GetUser(userId)
|
||||
|
||||
if oldPassword != "" {
|
||||
msg := object.CheckPassword(targetUser, oldPassword)
|
||||
|
@ -17,6 +17,7 @@ package object
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/casdoor/casdoor/cred"
|
||||
"github.com/casdoor/casdoor/util"
|
||||
@ -195,3 +196,37 @@ func CheckUserPassword(organization string, username string, password string) (*
|
||||
func filterField(field string) bool {
|
||||
return reFieldWhiteList.MatchString(field)
|
||||
}
|
||||
|
||||
func CheckUserPermission(requestUserId, userId string, strict bool) (bool, error) {
|
||||
if requestUserId == "" {
|
||||
return false, fmt.Errorf("please login first")
|
||||
}
|
||||
|
||||
targetUser := GetUser(userId)
|
||||
if targetUser == nil {
|
||||
return false, fmt.Errorf("the user: %s doesn't exist", userId)
|
||||
}
|
||||
|
||||
hasPermission := false
|
||||
if strings.HasPrefix(requestUserId, "app/") {
|
||||
hasPermission = true
|
||||
} else {
|
||||
requestUser := GetUser(requestUserId)
|
||||
if requestUser == nil {
|
||||
return false, fmt.Errorf("session outdated, please login again")
|
||||
}
|
||||
if requestUser.IsGlobalAdmin {
|
||||
hasPermission = true
|
||||
} else if requestUserId == userId {
|
||||
hasPermission = true
|
||||
} else if targetUser.Owner == requestUser.Owner {
|
||||
if strict {
|
||||
hasPermission = requestUser.IsAdmin
|
||||
} else {
|
||||
hasPermission = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasPermission, fmt.Errorf("you don't have the permission to do this")
|
||||
}
|
@ -35,6 +35,7 @@ type Organization struct {
|
||||
Tags []string `xorm:"mediumtext" json:"tags"`
|
||||
MasterPassword string `xorm:"varchar(100)" json:"masterPassword"`
|
||||
EnableSoftDeletion bool `json:"enableSoftDeletion"`
|
||||
IsProfilePublic bool `json:"isProfilePublic"`
|
||||
}
|
||||
|
||||
func GetOrganizationCount(owner, field, value string) int {
|
||||
|
@ -240,6 +240,16 @@ class OrganizationEditPage extends React.Component {
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: '20px'}} >
|
||||
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 19 : 2}>
|
||||
{Setting.getLabel(i18next.t("organization:Is profile public"), i18next.t("organization:Is profile public - Tooltip"))} :
|
||||
</Col>
|
||||
<Col span={1} >
|
||||
<Switch checked={this.state.organization.isProfilePublic} onChange={checked => {
|
||||
this.updateOrganizationField('isProfilePublic', checked);
|
||||
}} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row style={{marginTop: '20px'}}>
|
||||
<Col style={{marginTop: '5px'}} span={(Setting.isMobile()) ? 22 : 2}>
|
||||
{Setting.getLabel(i18next.t("general:LDAPs"), i18next.t("general:LDAPs - Tooltip"))} :
|
||||
|
@ -39,6 +39,7 @@ class OrganizationListPage extends BaseListPage {
|
||||
tags: [],
|
||||
masterPassword: "",
|
||||
enableSoftDeletion: false,
|
||||
isProfilePublic: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from "react";
|
||||
import {Button, Card, Col, Input, Row, Select, Switch} from 'antd';
|
||||
import {Button, Card, Col, Input, Result, Row, Select, Spin, Switch} from 'antd';
|
||||
import * as UserBackend from "./backend/UserBackend";
|
||||
import * as OrganizationBackend from "./backend/OrganizationBackend";
|
||||
import * as Setting from "./Setting";
|
||||
@ -47,6 +47,7 @@ class UserEditPage extends React.Component {
|
||||
organizations: [],
|
||||
applications: [],
|
||||
mode: props.location.mode !== undefined ? props.location.mode : "edit",
|
||||
loading: true,
|
||||
};
|
||||
}
|
||||
|
||||
@ -59,9 +60,14 @@ class UserEditPage extends React.Component {
|
||||
|
||||
getUser() {
|
||||
UserBackend.getUser(this.state.organizationName, this.state.userName)
|
||||
.then((user) => {
|
||||
.then((data) => {
|
||||
if (data.status === null || data.status !== "error") {
|
||||
this.setState({
|
||||
user: data,
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
user: user,
|
||||
loading: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -423,6 +429,8 @@ class UserEditPage extends React.Component {
|
||||
)
|
||||
}
|
||||
</Card>
|
||||
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
@ -469,13 +477,24 @@ class UserEditPage extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
{
|
||||
this.state.user !== null ? this.renderUser() : null
|
||||
this.state.loading ? <Spin loading={this.state.loading} size="large" /> : (
|
||||
this.state.user !== null ? this.renderUser() :
|
||||
<Result
|
||||
status="404"
|
||||
title="404 NOT FOUND"
|
||||
subTitle={i18next.t("general:Sorry, the user you visited does not exist or you are not authorized to access this user.")}
|
||||
extra={<a href="/"><Button type="primary">{i18next.t("general:Back Home")}</Button></a>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
this.state.user === null ? null :
|
||||
<div style={{marginTop: '20px', marginLeft: '40px'}}>
|
||||
<Button size="large" onClick={() => this.submitUserEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||
<Button style={{marginLeft: '20px'}} type="primary" size="large" onClick={() => this.submitUserEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||
{this.state.mode === "add" ? <Button style={{marginLeft: '20px'}} size="large" onClick={() => this.deleteUser()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||
</div>
|
||||
}
|
||||
<div style={{marginTop: '20px', marginLeft: '40px'}}>
|
||||
<Button size="large" onClick={() => this.submitUserEdit(false)}>{i18next.t("general:Save")}</Button>
|
||||
<Button style={{marginLeft: '20px'}} type="primary" size="large" onClick={() => this.submitUserEdit(true)}>{i18next.t("general:Save & Exit")}</Button>
|
||||
{this.state.mode === "add" ? <Button style={{marginLeft: '20px'}} size="large" onClick={() => this.deleteUser()}>{i18next.t("general:Cancel")}</Button> : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -171,6 +171,7 @@
|
||||
"Signup application": "注册应用",
|
||||
"Signup application - Tooltip": "表示用户注册时通过哪个应用注册的",
|
||||
"Sorry, the page you visited does not exist.": "抱歉,您访问的页面不存在",
|
||||
"Sorry, the user you visited does not exist or you are not authorized to access this user.": "抱歉,您访问的用户不存在或您无权访问该用户",
|
||||
"State": "状态",
|
||||
"State - Tooltip": "状态",
|
||||
"Swagger": "API文档",
|
||||
@ -252,7 +253,9 @@
|
||||
"Tags": "标签集合",
|
||||
"Tags - Tooltip": "可供用户选择的标签的集合",
|
||||
"Website URL": "网页地址",
|
||||
"Website URL - Tooltip": "网页地址"
|
||||
"Website URL - Tooltip": "网页地址",
|
||||
"Is profile public": "公开用户信息",
|
||||
"Is profile public - Tooltip": "关闭后,只有全局管理员或同组织才能访问用户信息"
|
||||
},
|
||||
"payment": {
|
||||
"Currency": "币种",
|
||||
|
Loading…
x
Reference in New Issue
Block a user