fix(项目设置): 全局用户组权限可以被修改

--bug=1014839 --user=李玉号 【项目设置】项目设置中系统级别的全局用户组权限可以被修改
https://www.tapd.cn/55049933/s/1203887
This commit is contained in:
shiziyuan9527 2022-07-19 10:56:49 +08:00 committed by shiziyuan9527
parent b9dbe6d431
commit ef87cce866
14 changed files with 124 additions and 101 deletions

View File

@ -41,6 +41,23 @@
</foreach>
</if>
</where>
union distinct
select g.*, p.name as scopeName from `group` g, project p
<where>
and g.scope_id = p.id
<if test="request.types != null and request.types.size() > 0">
AND g.type in
<foreach collection="request.types" item="type" separator="," open="(" close=")">
#{type}
</foreach>
</if>
<if test="request.scopes != null and request.scopes.size() > 0">
AND g.scope_id in
<foreach collection="request.scopes" item="scope" separator="," open="(" close=")">
#{scope}
</foreach>
</if>
</where>
) temp
<if test="request.name != null and request.name!=''">
where temp.name like CONCAT('%', #{request.name},'%')

View File

@ -5,5 +5,6 @@ import lombok.Data;
@Data
public class GroupRequest {
private String resourceId;
private String projectId;
private String type;
}

View File

@ -28,4 +28,5 @@ public class EditGroupRequest extends Group {
private String userGroupId;
private List<OrderRequest> orders;
private boolean onlyQueryCurrentProject = false;
private boolean onlyQueryGlobal = false;
}

View File

@ -26,7 +26,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.poi.ss.formula.functions.T;
import org.mybatis.spring.SqlSessionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -229,6 +228,9 @@ public class GroupService {
if (!StringUtils.equals(type, UserGroupType.SYSTEM)) {
criteria.andTypeEqualTo(type);
}
if (BooleanUtils.isTrue(request.isOnlyQueryGlobal())) {
criteria.andScopeIdEqualTo(GLOBAL);
}
return groupMapper.selectByExample(example);
}
@ -262,6 +264,9 @@ public class GroupService {
String resourceId = request.getResourceId();
String type = request.getType();
List<String> scopeList = Arrays.asList(GLOBAL, resourceId);
if (StringUtils.equals(type, UserGroupType.PROJECT) && StringUtils.isNotBlank(request.getProjectId())) {
scopeList = Arrays.asList(GLOBAL, resourceId, request.getProjectId());
}
GroupExample groupExample = new GroupExample();
groupExample.createCriteria().andScopeIdIn(scopeList)
.andTypeEqualTo(type);
@ -313,7 +318,8 @@ public class GroupService {
private Pager<List<GroupDTO>> getUserGroup(String groupType, EditGroupRequest request) {
List<String> types;
String workspaceId = SessionUtils.getCurrentWorkspaceId();
List<String> scopes = Arrays.asList(GLOBAL, workspaceId);
String projectId = SessionUtils.getCurrentProjectId();
List<String> scopes = Arrays.asList(GLOBAL, workspaceId, projectId);
int goPage = request.getGoPage();
int pageSize = request.getPageSize();
Page<Object> page = PageHelper.startPage(goPage, pageSize, true);
@ -323,7 +329,6 @@ public class GroupService {
types = map.get(groupType);
request.setTypes(types);
request.setScopes(scopes);
// request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
List<GroupDTO> groups = extGroupMapper.getGroupList(request);
buildUserInfo(groups);
return PageUtils.setPageInfo(page, groups);
@ -341,36 +346,17 @@ public class GroupService {
}
public List<?> getResource(String type, String groupId) {
List<T> resource = new ArrayList<>();
Group group = groupMapper.selectByPrimaryKey(groupId);
String workspaceId = group.getScopeId();
if (group == null) {
return new ArrayList<>();
}
if (StringUtils.equals(UserGroupType.WORKSPACE, type)) {
WorkspaceExample workspaceExample = new WorkspaceExample();
WorkspaceExample.Criteria criteria = workspaceExample.createCriteria();
if (!StringUtils.equals(workspaceId, GLOBAL)) {
criteria.andIdEqualTo(workspaceId);
return workspaceService.getWorkspaceGroupResource(group.getScopeId());
}
return workspaceMapper.selectByExample(workspaceExample);
}
if (StringUtils.equals(UserGroupType.PROJECT, type)) {
ProjectExample projectExample = new ProjectExample();
ProjectExample.Criteria pc = projectExample.createCriteria();
WorkspaceExample workspaceExample = new WorkspaceExample();
WorkspaceExample.Criteria criteria = workspaceExample.createCriteria();
if (!StringUtils.equals(workspaceId, GLOBAL)) {
criteria.andIdEqualTo(workspaceId);
List<Workspace> workspaces = workspaceMapper.selectByExample(workspaceExample);
List<String> list = workspaces.stream().map(Workspace::getId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(list)) {
pc.andWorkspaceIdIn(list);
return workspaceService.getProjectGroupResource(group.getScopeId());
}
}
return projectMapper.selectByExample(projectExample);
}
return resource;
return new ArrayList<>();
}
public List<User> getGroupUser(EditGroupRequest request) {

View File

@ -60,6 +60,8 @@ public class WorkspaceService {
@Resource
private EnvironmentGroupService environmentGroupService;
private static final String GLOBAL = "global";
public Workspace saveWorkspace(Workspace workspace) {
if (StringUtils.isBlank(workspace.getName())) {
MSException.throwException(Translator.get("workspace_name_is_null"));
@ -299,36 +301,46 @@ public class WorkspaceService {
public WorkspaceResource listResource(String groupId, String type) {
Group group = groupMapper.selectByPrimaryKey(groupId);
String workspaceId = group.getScopeId();
WorkspaceResource resource = new WorkspaceResource();
if (StringUtils.equals(UserGroupType.WORKSPACE, type)) {
WorkspaceExample workspaceExample = new WorkspaceExample();
WorkspaceExample.Criteria criteria = workspaceExample.createCriteria();
if (!StringUtils.equals(workspaceId, "global")) {
criteria.andIdEqualTo(workspaceId);
}
List<Workspace> workspaces = workspaceMapper.selectByExample(workspaceExample);
resource.setWorkspaces(workspaces);
}
if (StringUtils.equals(UserGroupType.PROJECT, type)) {
ProjectExample projectExample = new ProjectExample();
ProjectExample.Criteria pc = projectExample.createCriteria();
WorkspaceExample workspaceExample = new WorkspaceExample();
WorkspaceExample.Criteria criteria = workspaceExample.createCriteria();
if (!StringUtils.equals(workspaceId, "global")) {
criteria.andIdEqualTo(workspaceId);
List<Workspace> workspaces = workspaceMapper.selectByExample(workspaceExample);
List<String> list = workspaces.stream().map(Workspace::getId).collect(Collectors.toList());
pc.andWorkspaceIdIn(list);
}
List<Project> projects = projectMapper.selectByExample(projectExample);
resource.setProjects(projects);
}
if (group == null) {
return resource;
}
if (StringUtils.equals(UserGroupType.WORKSPACE, type)) {
resource.setWorkspaces(getWorkspaceGroupResource(group.getScopeId()));
}
if (StringUtils.equals(UserGroupType.PROJECT, type)) {
resource.setProjects(getProjectGroupResource(group.getScopeId()));
}
return resource;
}
public List<Workspace> getWorkspaceGroupResource(String scopeId) {
WorkspaceExample workspaceExample = new WorkspaceExample();
WorkspaceExample.Criteria criteria = workspaceExample.createCriteria();
if (!StringUtils.equals(scopeId, GLOBAL)) {
criteria.andIdEqualTo(scopeId);
}
return workspaceMapper.selectByExample(workspaceExample);
}
public List<Project> getProjectGroupResource(String scopeId) {
ProjectExample projectExample = new ProjectExample();
ProjectExample.Criteria criteria = projectExample.createCriteria();
if (StringUtils.equals(scopeId, GLOBAL)) {
return projectMapper.selectByExample(projectExample);
}
Workspace workspace = workspaceMapper.selectByPrimaryKey(scopeId);
if (workspace != null) {
criteria.andWorkspaceIdEqualTo(workspace.getId());
return projectMapper.selectByExample(projectExample);
}
Project project = projectMapper.selectByPrimaryKey(scopeId);
List<Project> list = new ArrayList<>();
if (project != null) {
list.add(project);
}
return list;
}
public List<String> getWorkspaceIds() {
return extWorkspaceMapper.getWorkspaceIds();

View File

@ -23,11 +23,9 @@
<el-form-item :label="$t('group.description')" prop="description">
<el-input type="textarea" v-model="form.description" style="width: 83%"></el-input>
</el-form-item>
<el-form-item :label="$t('group.global_group')">
<el-switch v-model="form.global" :disabled="dialogType === 'edit'"
@change="change(form.global)"></el-switch>
<el-form-item :label="form.scopeId === 'global' ? $t('group.global_group') : $t('group.ws_share')">
<el-switch v-model="isShare" :disabled="dialogType === 'edit'" @change="change"/>
</el-form-item>
</el-form>
<template v-slot:footer>
@ -39,7 +37,7 @@
<script>
import {GROUP_SYSTEM} from "@/common/js/constants";
import {getCurrentUserId, getCurrentWorkspaceId} from "@/common/js/utils";
import {getCurrentProjectID, getCurrentWorkspaceId} from "@/common/js/utils";
export default {
name: "EditUserGroup",
@ -69,7 +67,7 @@ export default {
show: true,
workspaces: [],
title: this.$t('group.create'),
flag: false
isShare: false
}
},
props: {
@ -95,7 +93,9 @@ export default {
create() {
this.$refs['form'].validate(valid => {
if (valid) {
this.form.scopeId = getCurrentWorkspaceId();
if (!this.form.scopeId) {
this.form.scopeId = getCurrentProjectID();
}
this.$post("/user/group/add", this.form, () => {
this.$success(this.$t('commons.save_success'));
this.$emit("refresh")
@ -125,28 +125,16 @@ export default {
this.show = true;
this.dialogVisible = true;
this.dialogType = type;
this.form = Object.assign({type: 'PROJECT' ,global: false , scopeId: getCurrentWorkspaceId()}, row);
if (row) {
this.isShare = row.scopeId === getCurrentWorkspaceId();
}
this.form = Object.assign({type: 'PROJECT' ,global: false , scopeId: ''}, row);
},
cancel() {
this.dialogVisible = false;
},
change(global) {
this.$get("/user/group/list/ws/" + getCurrentWorkspaceId() + "/" + getCurrentUserId(), res => {
let data = res.data;
if (data) {
data.forEach(row => {
if (row.id === 'ws_admin') {
this.flag = true;
}
})
}
if (this.flag === true) {
this.show = this.isSystem ? false : !global;
} else {
this.form.global = false;
this.$warning(this.$t('group.ws_admin_global'))
}
})
change(share) {
this.form.scopeId = share ? getCurrentWorkspaceId() : getCurrentProjectID();
},
changeGroup(val) {
if (val === GROUP_SYSTEM) {

View File

@ -48,15 +48,14 @@
<ms-table-operator :edit-permission="['PROJECT_GROUP:READ+EDIT']"
:delete-permission="['PROJECT_GROUP:READ+DELETE']"
@editClick="edit(scope.row)" @deleteClick="del(scope.row)"
:isShow="flagChange(scope.row.scopeId ==='global')">
:isShow="isDisable(scope.row.scopeId)">
<template v-slot:middle>
<!-- <ms-table-operator-button tip="复制" icon="el-icon-document-copy" @exec="copy(scope.row)"/>-->
<ms-table-operator-button
v-permission="['PROJECT_GROUP:READ+SETTING_PERMISSION']"
:tip="$t('group.set_permission')"
icon="el-icon-s-tools"
@exec="setPermission(scope.row)"
:disabled="flagChange(scope.row.scopeId ==='global')"/>
:disabled="isDisable(scope.row.scopeId)"/>
<ms-table-operator-button :tip="$t('group.view_permission')" icon="el-icon-view" @exec="viewPermission(scope.row)"/>
</template>
</ms-table-operator>
@ -116,18 +115,20 @@ export default {
screenHeight: 'calc(100vh - 160px)',
groups: [],
currentGroup: {},
flag: false
isWorkspaceAdmin: false
};
},
created() {
this.$get("/user/group/list/ws/" + getCurrentWorkspaceId() + "/" + getCurrentUserId(), res => {
let data = res.data;
if (data) {
data.forEach(row => {
if (row.id === 'ws_admin') {
this.flag = true;
if (!data) {
return;
}
for (let da of data) {
if (da.id === 'ws_admin') {
this.isWorkspaceAdmin = true;
break;
}
})
}
})
},
@ -156,13 +157,12 @@ export default {
});
}
},
flagChange(data) {
if (this.flag) {
return false;
} else if (data) {
return true;
isDisable(scopeId) {
if (scopeId === 'global') {
return true; //
} else {
return false;
// .
return scopeId === getCurrentProjectID() ? false : !this.isWorkspaceAdmin;
}
},
viewPermission(row) {

View File

@ -48,6 +48,8 @@
<script>
import UserOptionItem from "@/business/components/settings/common/UserOptionItem";
import {GROUP_PROJECT} from "@/common/js/constants";
import {getCurrentProjectID} from "@/common/js/utils";
export default {
name: "AddMember",
@ -82,6 +84,12 @@ export default {
return '';
}
},
projectId: {
type: String,
default() {
return '';
}
},
userResourceUrl: {
type: String,
default() {
@ -112,9 +120,13 @@ export default {
this.userList = response.data;
this.copyUserList = response.data;
})
this.result = this.$post('/user/group/list', {type: this.groupType, resourceId: this.groupScopeId}, response => {
let param = {type: this.groupType, resourceId: this.groupScopeId};
if (this.groupType === GROUP_PROJECT) {
param.projectId = this.projectId || getCurrentProjectID();
}
this.result = this.$post('/user/group/list', param, response => {
this.$set(this.form, "groups", response.data);
})
});
},
close() {
this.dialogVisible = false;

View File

@ -43,7 +43,7 @@
<script>
import ElUploadList from "element-ui/packages/upload/src/upload-list";
import MsTableButton from '../../../../components/common/components/MsTableButton';
import {getCurrentProjectID, getCurrentWorkspaceId, listenGoBack, removeGoBackListener} from "@/common/js/utils";
import {getCurrentWorkspaceId, listenGoBack, removeGoBackListener} from "@/common/js/utils";
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
import {GROUP_PROJECT} from "@/common/js/constants";
@ -171,7 +171,7 @@ export default {
getProjectUserGroup() {
//
if (this.cascaderLevel === 2) {
this.$post("/user/group/get", {type: GROUP_PROJECT}, (res) => {
this.$post("/user/group/get", {type: GROUP_PROJECT, onlyQueryGlobal: true}, (res) => {
this.projectUserGroups = res.data ? res.data : [];
});
} else if (this.cascaderLevel === 1) {

View File

@ -132,7 +132,7 @@ export default {
})
},
getWorkspaceUserGroup() {
this.$post("/user/group/get", {type: GROUP_WORKSPACE}, (res) => {
this.$post("/user/group/get", {type: GROUP_WORKSPACE, onlyQueryGlobal: true}, (res) => {
this.workspaceUserGroups = res.data ? res.data : [];
})
}

View File

@ -171,6 +171,7 @@
<add-member
:group-type="'PROJECT'"
:group-scope-id="workspaceId"
:project-id="rowProjectId"
ref="addMember"
:user-resource-url="'user/ws/current/member/list'"
@submit="submitForm"/>
@ -268,7 +269,8 @@ export default {
dialogTotal: 0,
currentProjectId: "",
userList: [],
labelWidth: '150px'
labelWidth: '150px',
rowProjectId: ""
};
},
props: {
@ -408,6 +410,7 @@ export default {
return path + "/" + this.dialogCurrentPage + "/" + this.dialogPageSize;
},
cellClick(row) {
this.rowProjectId = row.id;
// currentRow
this.currentWorkspaceRow = row;
this.currentProjectId = row.id;

View File

@ -936,7 +936,8 @@ export default {
please_select_group: 'Please Select Group',
global: 'Global',
unable_to_remove_current_member: 'Unable to remove currently logged in user!',
ws_admin_global: 'Only workspace administrators can create global user groups'
ws_admin_global: 'Only workspace administrators can create global user groups',
ws_share: 'Workspace sharing'
},
role: {
please_choose_role: 'Please Choose Role',

View File

@ -943,7 +943,8 @@ export default {
please_select_group: '请选择用户组',
global: '全局',
unable_to_remove_current_member: '无法移除当前登录用户!',
ws_admin_global: '工作空间管理员才可以创建全局用户组'
ws_admin_global: '工作空间管理员才可以创建全局用户组',
ws_share: '工作空间共享'
},
role: {
please_choose_role: '请选择角色',

View File

@ -940,7 +940,8 @@ export default {
please_select_group: '請選擇用戶組',
global: '全局',
unable_to_remove_current_member: '無法移除當前登錄用戶!',
ws_admin_global: '工作空間管理員才可以創建全局用戶組'
ws_admin_global: '工作空間管理員才可以創建全局用戶組',
ws_share: '工作空間共享'
},
role: {
please_choose_role: '請選擇角色',