mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-11-13 02:17:25 +01:00
filter taglist scope visibility by role, add global tag handling to support role
This commit is contained in:
parent
bc434ee8cb
commit
e3104c61cb
@ -309,7 +309,7 @@ func (r *JobRepository) checkScopeAuth(ctx context.Context, operation string, sc
|
||||
}
|
||||
return false, nil
|
||||
case operation == "write" && scope == "global":
|
||||
if user.HasRole(schema.RoleAdmin) || (len(user.Roles) == 1 && user.HasRole(schema.RoleApi)) {
|
||||
if user.HasAnyRole([]schema.Role{schema.RoleAdmin, schema.RoleSupport}) || (len(user.Roles) == 1 && user.HasRole(schema.RoleApi)) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
|
@ -128,7 +128,6 @@ func setupAnalysisRoute(i InfoType, r *http.Request) InfoType {
|
||||
|
||||
func setupTaglistRoute(i InfoType, r *http.Request) InfoType {
|
||||
jobRepo := repository.GetJobRepository()
|
||||
|
||||
tags, counts, err := jobRepo.CountTags(r.Context())
|
||||
tagMap := make(map[string][]map[string]interface{})
|
||||
if err != nil {
|
||||
@ -136,17 +135,34 @@ func setupTaglistRoute(i InfoType, r *http.Request) InfoType {
|
||||
i["tagmap"] = tagMap
|
||||
return i
|
||||
}
|
||||
|
||||
// Reduces displayed tags for unauth'd users
|
||||
userAuthlevel := repository.GetUserFromContext(r.Context()).GetAuthLevel()
|
||||
// Uses tag.ID as second Map-Key component to differentiate tags with identical names
|
||||
for _, tag := range tags {
|
||||
tagItem := map[string]interface{}{
|
||||
"id": tag.ID,
|
||||
"name": tag.Name,
|
||||
"scope": tag.Scope,
|
||||
"count": counts[fmt.Sprint(tag.Name, tag.ID)],
|
||||
if userAuthlevel >= 4 { // Support+ : Show tags for all scopes, regardless of count
|
||||
for _, tag := range tags {
|
||||
tagItem := map[string]interface{}{
|
||||
"id": tag.ID,
|
||||
"name": tag.Name,
|
||||
"scope": tag.Scope,
|
||||
"count": counts[fmt.Sprint(tag.Name, tag.ID)],
|
||||
}
|
||||
tagMap[tag.Type] = append(tagMap[tag.Type], tagItem)
|
||||
}
|
||||
tagMap[tag.Type] = append(tagMap[tag.Type], tagItem)
|
||||
}
|
||||
} else if userAuthlevel < 4 && userAuthlevel >= 2 { // User+ : Show global and admin scope only if at least 1 tag used, private scope regardless of count
|
||||
for _, tag := range tags {
|
||||
tagCount := counts[fmt.Sprint(tag.Name, tag.ID)]
|
||||
if ((tag.Scope == "global" || tag.Scope == "admin") && tagCount >= 1) || (tag.Scope != "global" && tag.Scope != "admin") {
|
||||
tagItem := map[string]interface{}{
|
||||
"id": tag.ID,
|
||||
"name": tag.Name,
|
||||
"scope": tag.Scope,
|
||||
"count": tagCount,
|
||||
}
|
||||
tagMap[tag.Type] = append(tagMap[tag.Type], tagItem)
|
||||
}
|
||||
}
|
||||
} // auth < 2 return nothing for this route
|
||||
|
||||
i["tagmap"] = tagMap
|
||||
return i
|
||||
}
|
||||
|
@ -48,7 +48,8 @@
|
||||
let filterTerm = "";
|
||||
let pendingChange = false;
|
||||
let isOpen = false;
|
||||
const isAdmin = (roles && authlevel >= roles.admin);
|
||||
const isAdmin = (roles && authlevel == roles.admin);
|
||||
const isSupport = (roles && authlevel == roles.support);
|
||||
|
||||
const client = getContextClient();
|
||||
|
||||
@ -104,8 +105,8 @@
|
||||
};
|
||||
|
||||
$: allTagsFiltered = ($initialized, fuzzySearchTags(filterTerm, allTags));
|
||||
$: usedTagsFiltered = matchJobTags(jobTags, allTagsFiltered, 'used', isAdmin);
|
||||
$: unusedTagsFiltered = matchJobTags(jobTags, allTagsFiltered, 'unused', isAdmin);
|
||||
$: usedTagsFiltered = matchJobTags(jobTags, allTagsFiltered, 'used', isAdmin, isSupport);
|
||||
$: unusedTagsFiltered = matchJobTags(jobTags, allTagsFiltered, 'unused', isAdmin, isSupport);
|
||||
|
||||
$: {
|
||||
newTagType = "";
|
||||
@ -117,16 +118,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
function matchJobTags(tags, availableTags, type, isAdmin) {
|
||||
function matchJobTags(tags, availableTags, type, isAdmin, isSupport) {
|
||||
const jobTagIds = tags.map((t) => t.id)
|
||||
if (type == 'used') {
|
||||
if (isAdmin || type == 'used') { // Always show used tags, admin also show all unused
|
||||
return availableTags.filter((at) => jobTagIds.includes(at.id))
|
||||
} else if (type == 'unused' && isAdmin) {
|
||||
return availableTags.filter((at) => !jobTagIds.includes(at.id))
|
||||
} else if (type == 'unused' && !isAdmin) { // Normal Users should not see unused global tags here
|
||||
return availableTags.filter((at) => !jobTagIds.includes(at.id) && at.scope !== "global")
|
||||
} else { // ... for unused
|
||||
if (isSupport) { // ... show global tags for support
|
||||
return availableTags.filter((at) => !jobTagIds.includes(at.id) && at.scope !== "admin")
|
||||
} else { // ... show only private tags for user, manager
|
||||
return availableTags.filter((at) => !jobTagIds.includes(at.id) && at.scope !== "admin" && at.scope !== "global")
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
function isNewTag(type, name) {
|
||||
@ -223,7 +225,7 @@
|
||||
Private Tag
|
||||
{/if}
|
||||
</Button>
|
||||
{#if isAdmin || (utag.scope !== 'global' && utag.scope !== 'admin')}
|
||||
{#if isAdmin || (isSupport && utag.scope == 'global') || (utag.scope !== 'global' && utag.scope !== 'admin')}
|
||||
<Button
|
||||
size="sm"
|
||||
color="danger"
|
||||
@ -273,7 +275,7 @@
|
||||
Private Tag
|
||||
{/if}
|
||||
</Button>
|
||||
{#if isAdmin || (uutag.scope !== 'global' && uutag.scope !== 'admin')}
|
||||
{#if isAdmin || (isSupport && uutag.scope == 'global') || (uutag.scope !== 'global' && uutag.scope !== 'admin')}
|
||||
<Button
|
||||
size="sm"
|
||||
color="success"
|
||||
@ -304,7 +306,7 @@
|
||||
|
||||
{#if newTagType && newTagName && isNewTag(newTagType, newTagName)}
|
||||
<Row>
|
||||
<Col xs={isAdmin ? 7 : 12} md={12} lg={isAdmin ? 7 : 12} xl={12} xxl={isAdmin ? 7 : 12} class="mb-2">
|
||||
<Col xs={(isAdmin || isSupport) ? 7 : 12} md={12} lg={(isAdmin || isSupport) ? 7 : 12} xl={12} xxl={(isAdmin || isSupport) ? 7 : 12} class="mb-2">
|
||||
<Button
|
||||
outline
|
||||
style="width:100%;"
|
||||
@ -317,12 +319,14 @@
|
||||
<Tag tag={{ type: newTagType, name: newTagName, scope: newTagScope }} clickable={false}/>
|
||||
</Button>
|
||||
</Col>
|
||||
{#if isAdmin}
|
||||
{#if isSupport || isAdmin}
|
||||
<Col xs={5} md={12} lg={5} xl={12} xxl={5} class="mb-2" style="align-content:center;">
|
||||
<Input type="select" bind:value={newTagScope}>
|
||||
<option value={username}>Scope: Private</option>
|
||||
<option value={"global"}>Scope: Global</option>
|
||||
<option value={"admin"}>Scope: Admin</option>
|
||||
{#if isAdmin}
|
||||
<option value={"admin"}>Scope: Admin</option>
|
||||
{/if}
|
||||
</Input>
|
||||
</Col>
|
||||
{/if}
|
||||
|
Loading…
Reference in New Issue
Block a user