From 530330bd661b394b7942f4d822601ffccc714861 Mon Sep 17 00:00:00 2001 From: Yixiang Zhao Date: Sat, 16 Apr 2022 15:10:03 +0800 Subject: [PATCH] feat: add isProfilePublic setting for accessing user info (#656) * feat: add isProfilePublic setting for accessing user info Signed-off-by: Yixiang Zhao * fix: requested changes Signed-off-by: Yixiang Zhao --- controllers/user.go | 45 ++++++++++++--------------------- object/check.go | 35 +++++++++++++++++++++++++ object/organization.go | 1 + web/src/OrganizationEditPage.js | 10 ++++++++ web/src/OrganizationListPage.js | 1 + web/src/UserEditPage.js | 37 ++++++++++++++++++++------- web/src/locales/zh/data.json | 5 +++- 7 files changed, 95 insertions(+), 39 deletions(-) diff --git a/controllers/user.go b/controllers/user.go index 26b9e6c4..ec3d8395 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -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) diff --git a/object/check.go b/object/check.go index d817b3aa..649d8b33 100644 --- a/object/check.go +++ b/object/check.go @@ -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") +} \ No newline at end of file diff --git a/object/organization.go b/object/organization.go index 0c903ddd..cbad48ab 100644 --- a/object/organization.go +++ b/object/organization.go @@ -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 { diff --git a/web/src/OrganizationEditPage.js b/web/src/OrganizationEditPage.js index 0538c586..1322bfc5 100644 --- a/web/src/OrganizationEditPage.js +++ b/web/src/OrganizationEditPage.js @@ -240,6 +240,16 @@ class OrganizationEditPage extends React.Component { }} /> + + + {Setting.getLabel(i18next.t("organization:Is profile public"), i18next.t("organization:Is profile public - Tooltip"))} : + + + { + this.updateOrganizationField('isProfilePublic', checked); + }} /> + + {Setting.getLabel(i18next.t("general:LDAPs"), i18next.t("general:LDAPs - Tooltip"))} : diff --git a/web/src/OrganizationListPage.js b/web/src/OrganizationListPage.js index ad8354c2..a3f6d8fa 100644 --- a/web/src/OrganizationListPage.js +++ b/web/src/OrganizationListPage.js @@ -39,6 +39,7 @@ class OrganizationListPage extends BaseListPage { tags: [], masterPassword: "", enableSoftDeletion: false, + isProfilePublic: true, } } diff --git a/web/src/UserEditPage.js b/web/src/UserEditPage.js index c9c81747..01bfb2b4 100644 --- a/web/src/UserEditPage.js +++ b/web/src/UserEditPage.js @@ -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 { ) } + + ) } @@ -469,13 +477,24 @@ class UserEditPage extends React.Component { return (
{ - this.state.user !== null ? this.renderUser() : null + this.state.loading ? : ( + this.state.user !== null ? this.renderUser() : + } + /> + ) + } + { + this.state.user === null ? null : +
+ + + {this.state.mode === "add" ? : null} +
} -
- - - {this.state.mode === "add" ? : null} -
); } diff --git a/web/src/locales/zh/data.json b/web/src/locales/zh/data.json index d771a30d..1bdd7b74 100644 --- a/web/src/locales/zh/data.json +++ b/web/src/locales/zh/data.json @@ -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": "币种",