Merge pull request #4373 from normanjaeckel/HistoryPermission

Added new permission to see the history.
This commit is contained in:
Emanuel Schütze 2019-02-21 13:07:07 +01:00 committed by GitHub
commit 650054dfc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 51 additions and 23 deletions

View File

@ -21,7 +21,7 @@ Core:
- Add a change-id system to get only new elements [#3938]. - Add a change-id system to get only new elements [#3938].
- Switch from Yarn back to npm [#3964]. - Switch from Yarn back to npm [#3964].
- Added password reset link (password reset via email) [#3914, #4199]. - Added password reset link (password reset via email) [#3914, #4199].
- Added global history mode [#3977, #4141]. - Added global history mode [#3977, #4141, #4369, #4373].
- Projector refactoring [4119, #4130]. - Projector refactoring [4119, #4130].
- Fixed logo configuration if logo file is deleted [#4374]. - Fixed logo configuration if logo file is deleted [#4374].

View File

@ -4,7 +4,10 @@
<!-- Menu --> <!-- Menu -->
<div class="menu-slot"> <div class="menu-slot">
<button type="button" mat-icon-button [matMenuTriggerFor]="historyMenu"><mat-icon>more_vert</mat-icon></button> <!-- Hidden for everyone but the superadmin -->
<button *osPerms="'superadmin'" type="button" mat-icon-button [matMenuTriggerFor]="historyMenu">
<mat-icon>more_vert</mat-icon>
</button>
</div> </div>
</os-head-bar> </os-head-bar>

View File

@ -10,6 +10,7 @@ import { History } from 'app/shared/models/core/history';
import { HistoryRepositoryService } from 'app/core/repositories/history/history-repository.service'; import { HistoryRepositoryService } from 'app/core/repositories/history/history-repository.service';
import { isDetailNavigable } from 'app/shared/models/base/detail-navigable'; import { isDetailNavigable } from 'app/shared/models/base/detail-navigable';
import { ListViewBaseComponent } from 'app/site/base/list-view-base'; import { ListViewBaseComponent } from 'app/site/base/list-view-base';
import { OperatorService } from 'app/core/core-services/operator.service';
import { ViewHistory } from '../../models/view-history'; import { ViewHistory } from '../../models/view-history';
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service'; import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
@ -36,6 +37,9 @@ export class HistoryListComponent extends ListViewBaseComponent<ViewHistory, His
* @param translate Handle translations * @param translate Handle translations
* @param matSnackBar Showing errors and messages * @param matSnackBar Showing errors and messages
* @param repo The history repository * @param repo The history repository
* @param viewModelStore Access view models
* @param router route to pages
* @param operator checks if the user is a super admin
*/ */
public constructor( public constructor(
titleService: Title, titleService: Title,
@ -43,7 +47,8 @@ export class HistoryListComponent extends ListViewBaseComponent<ViewHistory, His
matSnackBar: MatSnackBar, matSnackBar: MatSnackBar,
private repo: HistoryRepositoryService, private repo: HistoryRepositoryService,
private viewModelStore: ViewModelStoreService, private viewModelStore: ViewModelStoreService,
private router: Router private router: Router,
private operator: OperatorService
) { ) {
super(titleService, translate, matSnackBar); super(titleService, translate, matSnackBar);
} }
@ -105,17 +110,18 @@ export class HistoryListComponent extends ListViewBaseComponent<ViewHistory, His
* @param history Represents the selected element * @param history Represents the selected element
*/ */
public async onClickRow(history: ViewHistory): Promise<void> { public async onClickRow(history: ViewHistory): Promise<void> {
await this.repo.browseHistory(history); if (this.operator.isInGroupIds(2)) {
const element = this.viewModelStore.get(history.getCollectionString(), history.getModelId()); await this.repo.browseHistory(history);
let message = this.translate.instant('OpenSlides is temporarily reset to following timestamp:'); const element = this.viewModelStore.get(history.getCollectionString(), history.getModelId());
console.log(message); let message = this.translate.instant('OpenSlides is temporarily reset to following timestamp:');
message += ' ' + history.getLocaleString('DE-de'); message += ' ' + history.getLocaleString('DE-de');
if (isDetailNavigable(element)) { if (isDetailNavigable(element)) {
this.raiseError(message); this.raiseError(message);
this.router.navigate([element.getDetailStateURL()]); this.router.navigate([element.getDetailStateURL()]);
} else { } else {
this.raiseError(message); this.raiseError(message);
}
} }
} }
@ -123,7 +129,9 @@ export class HistoryListComponent extends ListViewBaseComponent<ViewHistory, His
* Handler for the delete all button * Handler for the delete all button
*/ */
public onDeleteAllButton(): void { public onDeleteAllButton(): void {
this.repo.delete(); if (this.operator.isInGroupIds(2)) {
this.repo.delete();
}
} }
/** /**

View File

@ -23,7 +23,7 @@ export const HistoryAppConfig: AppConfig = {
displayName: 'History', displayName: 'History',
icon: 'history', icon: 'history',
weight: 1200, weight: 1200,
permission: 'core.view_history' permission: 'core.can_see_history'
} }
] ]
}; };

View File

@ -1,5 +1,4 @@
from ..utils.access_permissions import BaseAccessPermissions from ..utils.access_permissions import BaseAccessPermissions
from ..utils.auth import GROUP_ADMIN_PK, async_in_some_groups
class ProjectorAccessPermissions(BaseAccessPermissions): class ProjectorAccessPermissions(BaseAccessPermissions):
@ -52,9 +51,4 @@ class HistoryAccessPermissions(BaseAccessPermissions):
Access permissions container for the Histroy. Access permissions container for the Histroy.
""" """
async def async_check_permissions(self, user_id: int) -> bool: base_permission = "core.can_see_history"
"""
Returns True if the user is in admin group and has read access to
model instances.
"""
return await async_in_some_groups(user_id, [GROUP_ADMIN_PK])

View File

@ -0,0 +1,18 @@
# Generated by Django 2.1.5 on 2019-02-19 19:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [("core", "0016_projector_reference_projector")]
operations = [
migrations.AlterModelOptions(
name="history",
options={
"default_permissions": (),
"permissions": (("can_see_history", "Can see history"),),
},
)
]

View File

@ -355,3 +355,4 @@ class History(RESTModelMixin, models.Model):
class Meta: class Meta:
default_permissions = () default_permissions = ()
permissions = (("can_see_history", "Can see history"),)

View File

@ -501,8 +501,10 @@ class HistoryViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
""" """
Returns True if the user has required permissions. Returns True if the user has required permissions.
""" """
if self.action in ("list", "retrieve", "clear_history"): if self.action in ("list", "retrieve"):
result = self.get_access_permissions().check_permissions(self.request.user) result = self.get_access_permissions().check_permissions(self.request.user)
elif self.action == "clear_history":
result = in_some_groups(self.request.user.pk or 0, [GROUP_ADMIN_PK])
else: else:
result = False result = False
return result return result

View File

@ -47,6 +47,7 @@ def create_builtin_groups_and_admin(**kwargs):
"core.can_manage_tags", "core.can_manage_tags",
"core.can_manage_chat", "core.can_manage_chat",
"core.can_see_frontpage", "core.can_see_frontpage",
"core.can_see_history",
"core.can_see_projector", "core.can_see_projector",
"core.can_use_chat", "core.can_use_chat",
"mediafiles.can_manage", "mediafiles.can_manage",
@ -134,6 +135,7 @@ def create_builtin_groups_and_admin(**kwargs):
permission_dict["assignments.can_nominate_other"], permission_dict["assignments.can_nominate_other"],
permission_dict["assignments.can_nominate_self"], permission_dict["assignments.can_nominate_self"],
permission_dict["core.can_see_frontpage"], permission_dict["core.can_see_frontpage"],
permission_dict["core.can_see_history"],
permission_dict["core.can_see_projector"], permission_dict["core.can_see_projector"],
permission_dict["core.can_manage_projector"], permission_dict["core.can_manage_projector"],
permission_dict["core.can_manage_tags"], permission_dict["core.can_manage_tags"],