def delete_attachment(request, id): attachment = get_object_or_404(Attachment, id=id) problem = attachment.problem checker = ObjectPermissionChecker(request.user) if not checker.has_perm('edit_problem', problem) and problem.user != request.user: raise Http404 old_id = attachment.id old_filename = attachment.file.name attachment.file.delete(False) attachment.delete() # 해당 오브젝트에 대해 아무 퍼미션이나 있으면 처리됨. 문제의 경우 PUBLISHED 일 때는 이 권한을 사용하지 않아서 안전하다 visible_users = get_users_with_perms(problem, with_group_users=False) visible_groups = get_groups_with_perms(problem) publish("problem-attachment-delete-%s" % datetime.now().strftime('%s.%f'), "problem", "problem-attachment", actor=request.user, target=problem, timestamp=datetime.now(), visible_users=visible_users, visible_groups=visible_groups, verb=u"문제 {target}에서 첨부파일 %s 을 삭제했습니다." % os.path.basename(old_filename)) return HttpResponse("[]")
def get_perms(user_or_group, obj): """ Returns permissions for given user/group and object pair, as list of strings. """ check = ObjectPermissionChecker(user_or_group) return check.get_perms(obj)
def render(self, context): for_whom = self.for_whom.resolve(context) if isinstance(for_whom, get_user_model()): self.user = for_whom self.group = None elif isinstance(for_whom, AnonymousUser): self.user = get_user_model().get_anonymous() self.group = None elif isinstance(for_whom, Group): self.user = None self.group = for_whom elif isinstance(for_whom, Organization): self.user = None self.group = for_whom else: raise NotUserNorGroup("User or Group instance required (got %s)" % for_whom.__class__) obj = self.obj.resolve(context) if not obj: return '' check = ObjectPermissionChecker(for_whom) perms = check.get_perms( obj, include_group_perms=self.include_group_permissions) context[self.context_var] = perms return ''
def has_perm(self, user_obj, perm, obj=None): """ Returns ``True`` if given ``user_obj`` has ``perm`` for ``obj``. If no ``obj`` is given, ``False`` is returned. .. note:: Remember, that if user is not *active*, all checks would return ``False``. Main difference between Django's ``ModelBackend`` is that we can pass ``obj`` instance here and ``perm`` doesn't have to contain ``app_label`` as it can be retrieved from given ``obj``. **Inactive user support** If user is authenticated but inactive at the same time, all checks always returns ``False``. """ # check if user_obj and object are supported support, user_obj = check_support(user_obj, obj) if not support: return False if '.' in perm: app_label, perm = perm.split('.') if app_label != obj._meta.app_label: raise WrongAppError("Passed perm has app label of '%s' and " "given obj has '%s'" % (app_label, obj._meta.app_label)) check = ObjectPermissionChecker(user_obj) return check.has_perm(perm, obj)
def get_group_perms(user_or_group, obj): """ Returns permissions for given user/group and object pair, as list of strings. It returns only those which are inferred through groups. """ check = ObjectPermissionChecker(user_or_group) return check.get_group_perms(obj)
def bulk_assign_perm(self, perm, user_or_group, queryset): """ Bulk assigns permissions with given ``perm`` for an objects in ``queryset`` and ``user_or_group``. """ ctype = get_content_type(queryset.model) if not isinstance(perm, Permission): permission = Permission.objects.get(content_type=ctype, codename=perm) else: permission = perm checker = ObjectPermissionChecker(user_or_group) checker.prefetch_perms(queryset) assigned_perms = [] for instance in queryset: if not checker.has_perm(permission.codename, instance): kwargs = {'permission': permission, self.user_or_group_field: user_or_group} if self.is_generic(): kwargs['content_type'] = ctype kwargs['object_pk'] = instance.pk else: kwargs['content_object'] = instance assigned_perms.append(self.model(**kwargs)) self.model.objects.bulk_create(assigned_perms) return assigned_perms
def test_copyannotations_command_doesnt_add_permissions( self, annotation_set): user_from = annotation_set.grader user_to = UserFactory() call_command( "copyannotations", user_from.username, user_to.username, add_permissions=False, stdout=None, # suppress output ) checker = ObjectPermissionChecker(user_to) for model, _ in self.annotations: model_instance = model.objects.get(grader=user_to) children = [] if model == PolygonAnnotationSet: children = model_instance.singlepolygonannotation_set.all() if model == LandmarkAnnotationSet: children = model_instance.singlelandmarkannotation_set.all() perms = checker.get_perms(model_instance) assert len(perms) == 0 if children: checker.prefetch_perms(children) for child in children: perms = checker.get_perms(child) assert len(perms) == 0
def check_permissions(user, object, permissions): checker = ObjectPermissionChecker(user) perm = True for perm in permissions: if not checker.has_perm(perm, object): return False return perm
def update_stickynotes(request, id_chalkboard, id_stickynote): chlk = get_object_or_404(Chalkboard, id=id_chalkboard) checker = ObjectPermissionChecker(request.user) stickynote = get_object_or_404(StickyNote, id=id_stickynote) can_update = False if request.user == stickynote.user_created and checker.has_perm( 'stickynote_update_own', chlk): can_update = True elif checker.has_perm('stickynote_update_all', chlk): can_update = True if can_update: form = None if stickynote.type == StickyNoteType.IMAGE: image_stickynotes = get_object_or_404( ImageStickyNote, stickynote_ptr_id=stickynote.id) form = ImageStickyNoteForm(request.POST or None, instance=image_stickynotes) elif stickynote.type == StickyNoteType.VIDEO: video_stickynotes = get_object_or_404( VideoStickyNote, stickynote_ptr_id=stickynote.id) form = VideoStickyNoteForm(request.POST or None, instance=video_stickynotes) elif stickynote.type == StickyNoteType.TEXT: form = StickyNoteForm(request.POST or None, instance=stickynote) if form is None: raise Http404 if form.is_valid(): form.save() messages.success(request, 'Update succes') return redirect('details_chalkboard', id_chalkboard) else: messages.warning(request, 'You don\'t have permission') return redirect('details_chalkboard', id_chalkboard) return render(request, "notes/note_form.html", {'form': form})
def clean(self): if self.instance.id: checker = ObjectPermissionChecker(self.request_user) if not checker.has_perm('contacts.write_contact', self.instance): raise ValidationError("User %s has no write permissions" % self.request_user.username) return super(ContactAdminForm, self).clean()
def db_all_del(request): ret = { 'status': True, 'error': None, } if request.method == "POST": try: ids = request.POST.getlist('id', None) ids1 = [] for i in ids: user = User.objects.get(username=request.user) checker = ObjectPermissionChecker(user) assets = db_mysql.objects.get(id=i) if checker.has_perm( 'delete_db', assets, ) == True: ids1.append(i) idstring = ','.join(ids1) db_mysql.objects.extra(where=['id IN (' + idstring + ')']).delete() except Exception as e: ret['status'] = False ret['error'] = '删除请求错误,{}'.format(e) finally: return HttpResponse(json.dumps(ret))
def edit(request, id): problem = get_object_or_404(Problem, id=id) checker = ObjectPermissionChecker(request.user) if not checker.has_perm('edit_problem', problem) and problem.user != request.user: raise Http404 problem_revision = problem.last_revision form_class = (ProblemEditForm if request.user.is_superuser else RestrictedProblemEditForm) form = form_class(data=request.POST or None, instance=problem) if request.method == "POST": revision_form = ProblemRevisionEditForm(data=request.POST or None, instance=ProblemRevision()) if form.is_valid() and revision_form.is_valid(): form.save() new_revision = revision_form.save(problem, request.user, commit=False) if new_revision.different_from(problem_revision): revision_form.save(problem, request.user) return redirect( reverse("judge-problem-read", kwargs={"slug": form.cleaned_data["slug"]})) revision_form = ProblemRevisionEditForm(data=request.POST or None, instance=problem_revision) return render( request, "problem/edit.html", { "problem": problem, "form": form, "revision_form": revision_form, "editable": checker.has_perm("edit_problem", problem) })
def stat(request, slug, page=1): problem = get_object_or_404(Problem, slug=slug) checker = ObjectPermissionChecker(request.user) if (problem.state != Problem.PUBLISHED and not checker.has_perm('read_problem', problem) and problem.user != request.user): raise Http404 submissions = Submission.objects.filter(problem=problem) verdict_chart = Submission.get_verdict_distribution_graph(submissions) incorrect_tries_chart = Solver.get_incorrect_tries_chart(problem) solvers = Solver.objects.filter(problem=problem, solved=True) order_by = request.GET.get('order_by', 'shortest') if order_by.endswith('fastest'): solvers = solvers.order_by(order_by + '_submission__time') elif order_by.endswith('shortest'): solvers = solvers.order_by(order_by + '_submission__length') else: solvers = solvers.order_by(order_by) pagination = setup_paginator(solvers, page, 'judge-problem-stat', {'slug': slug}, request.GET) title = problem.slug + u': 해결한 사람들' return render( request, "problem/stat.html", { 'title': title, 'problem': problem, 'editable': checker.has_perm('edit_problem', problem), 'verdict_chart': verdict_chart, 'incorrects_chart': incorrect_tries_chart, 'pagination': pagination, })
def go(): problem = get_or_none(Problem, id=id) if not problem: return {"success": False, "error": u"존재하지 않는 문제입니다."} checker = ObjectPermissionChecker(request.user) if not checker.has_perm('edit_problem', problem) and problem.user != request.user: return {"success": False, "error": u"권한이 없습니다."} if request.method != "POST": return {"success": False, "error": u"POST 접근하셔야 합니다."} file = request.FILES["file"] md5 = md5file(file) target_path = os.path.join("judge-attachments", md5, file.name) storage = DefaultStorage() storage.save(target_path, file) new_attachment = Attachment(problem=problem, file=target_path) new_attachment.save() # 해당 오브젝트에 대해 아무 퍼미션이나 있으면 처리됨. 문제의 경우 PUBLISHED 일 때는 이 권한을 사용하지 않아서 안전하다 visible_users = get_users_with_perms(problem, with_group_users=False) visible_groups = get_groups_with_perms(problem) publish("problem-attachment-%s" % datetime.now().strftime('%s.%f'), "problem", "problem-attachment", actor=request.user, target=problem, timestamp=datetime.now(), visible_users=visible_users, visible_groups=visible_groups, verb=u"문제 {target}에 첨부파일 %s 을 추가했습니다." % file.name) return {"success": True}
def test_group_remove_perm(self): # assign perm first assign_perm("change_contenttype", self.group, self.ctype) remove_perm("change_contenttype", self.group, self.ctype) check = ObjectPermissionChecker(self.group) self.assertFalse(check.has_perm("change_contenttype", self.ctype))
def test_group_remove_perm_queryset(self): assign_perm("change_contenttype", self.group, self.ctype_qset) remove_perm("change_contenttype", self.group, self.ctype_qset) check = ObjectPermissionChecker(self.group) for obj in self.ctype_qset: self.assertFalse(check.has_perm("change_contenttype", obj))
def test_group_assign_perm(self): assign_perm("change_contenttype", self.group, self.ctype) assign_perm("delete_contenttype", self.group, self.ctype) check = ObjectPermissionChecker(self.group) self.assertTrue(check.has_perm("change_contenttype", self.ctype)) self.assertTrue(check.has_perm("delete_contenttype", self.ctype))
def asset_web_ssh(request): if request.method == 'POST': id = request.POST.get('id', None) obj = asset.objects.get(id=id) a = asset.objects.get(id=id) user = User.objects.get(username=request.user) checker = ObjectPermissionChecker(user) try: if checker.has_perm('task_asset', a) == True: ip = obj.network_ip + ":" + str(obj.port) username = obj.system_user.username password1 = obj.system_user.password password = decrypt_p(password1) ret = {"ip": ip, "username": username, 'password': password, "static": True} login_ip = request.META['REMOTE_ADDR'] web_history.objects.create(user=request.user, ip=login_ip, login_user=obj.system_user.username, host=ip) except Exception as e: ret['status'] = False ret['error'] = '请求错误,{}'.format(e) finally: return HttpResponse(json.dumps(ret))
def test_copyannotations_command_adds_permissions(self, annotation_set): user_from = annotation_set.grader user_to = UserFactory() call_command( "copyannotations", user_from.username, user_to.username, stdout=None, # suppress output ) checker = ObjectPermissionChecker(user_to) for model, _ in self.annotations: model_instance = model.objects.get(grader=user_to) children = [] if model == PolygonAnnotationSet: children = model_instance.singlepolygonannotation_set.all() if model == LandmarkAnnotationSet: children = model_instance.singlelandmarkannotation_set.all() perms = checker.get_perms(model_instance) for permission_type in model._meta.default_permissions: assert f"{permission_type}_{model._meta.model_name}" in perms if children: checker.prefetch_perms(children) for child in children: perms = checker.get_perms(child) child_model_name = children.first()._meta.model_name for permission_type in child._meta.default_permissions: assert f"{permission_type}_{child_model_name}" in perms
def read(request, id): post = get_object_or_404(Post, id=id) category = post.category checker = ObjectPermissionChecker(request.user) if not checker.has_perm('read_post', category): return HttpResponseForbidden("Restricted post") return render(request, "read.html", {"post": post, "category": category})
def test_save_first_minutes_document(self): # get the editor page and save the site response = self.app.get(reverse('documents:create', args=['minutesdocument']) + '?group={}'.format(self.group.id), user=self.user) self.assertEqual(response.status_code, 200) form = response.forms['document-form'] text = "Lorem ipsum" form.set('text_en', text) form.set('comment', text) form.set('url_title', slugify(text)) response = form.submit().follow() self.assertEqual(response.status_code, 200) document = MinutesDocument.objects.get(url_title=slugify(text)) # check whether number of versions is correct versions = Version.objects.get_for_object(document) self.assertEqual(len(versions), 1) # check whether the properties of the new document are correct self.assertEqual((document.title_en, document.title_de), MinutesDocument.generate_new_title()) self.assertEqual(document.author, self.user) self.assertEqual(document.moderator, self.user) self.assertEqual(document.text_en, text) self.assertEqual(versions[0].revision.get_comment(), text) self.assertListEqual(list(document.participants.all().order_by('username')), list(self.group.user_set.all().order_by('username'))) checker = ObjectPermissionChecker(self.group) self.assertTrue(checker.has_perm(document.edit_permission_name, document))
def details(request, id): from django.conf import settings checker = ObjectPermissionChecker(request.user) submission = get_object_or_404(Submission, id=id) problem = submission.problem if (not problem.was_solved_by(request.user) and submission.user != request.user and problem.user != request.user and not checker.has_perm('read_problem', problem)): return HttpResponseForbidden() message = '' if submission.state == Submission.ACCEPTED: now = datetime.now() for item in settings.SOLVED_CAMPAIGN: if (item['problem'] == problem.slug and item['begin'] <= now <= item['end']): message = item['message'] break return render( request, "submission/details.html", { "title": u"답안 보기", "submission": submission, "message": message, "problem": problem })
def get_user_perms(user, obj): """ Returns permissions for given user and object pair, as list of strings, only those assigned directly for the user. """ check = ObjectPermissionChecker(user) return check.get_user_perms(obj)
def allow_bulk_destroy_resources(self, user, resource_list): """User must have admin permissions to delete collections.""" checker = ObjectPermissionChecker(user) for collection in resource_list: if not checker.has_perm('admin_collection', collection): return False return True
def validate_permission(self, user_or_group, class_permission_key): def name(user_or_group): if isinstance(user_or_group, Group): return "Group {group_name}".format( group_name=user_or_group.name) else: user_groups = [g.name for g in user_or_group.groups.all()] if user_groups: user_groups_string = ', '.join() else: user_groups_string = '(No groups)' return "User {username} of groups {groups}".format( username=user_or_group.username, groups=user_groups_string) if not user_or_group.has_perm(class_permission_key, self): raise Exception( "%s lacks expected permission key %s to instance %s.\nThe user has permission to the following \ instances %s.\nThe user is a member of the following groups: %s.\nThe object permits the \ following groups: %s,\nand the following users: %s" % (name(user_or_group), class_permission_key, self.name, ', '.join( ObjectPermissionChecker(user_or_group).get_perms(self)), ', '.join( map( lambda group: group.name, user_or_group.groups.all() if not isinstance(user_or_group, Group) else [])), ', '.join( map(lambda user_group: name(user_group), list(get_groups_with_perms(self)))), ', '.join( map(lambda user_group: name(user_group), list(get_users_with_perms(self))))))
def check_user_role(user, project, roles) -> bool: """Check that a user has one of a set of roles for a project. Administrator role satisfies any requirement. """ # Prefetch all user permissions for project. checker = ObjectPermissionChecker(user) # Check for admin privs in all cases. has_role = checker.has_perm('can_administer', project) if not has_role: # Check the indicated role(s) if isinstance(roles, str): roles = [roles] for role in roles: if role == UserRole.Annotate: has_role = checker.has_perm('can_annotate', project) elif role == UserRole.Browse: has_role = checker.has_perm('can_browse', project) elif role == UserRole.Fork: has_role = checker.has_perm('can_fork', project) elif role == UserRole.Import: has_role = checker.has_perm('can_import', project) elif role == UserRole.QueueComputeTask: has_role = checker.has_perm('can_queue_compute_task', project) if has_role: break return has_role
def home(request): user = request.user clubs = Club.objects.all() orgs = Organization.objects.all() checker = ObjectPermissionChecker(user) checker.prefetch_perms(orgs) post_orgs = [] membership_orgs = [] post_clubs = [] membership_clubs = [] for org in orgs: if checker.has_perm('add_announcements', org): post_orgs.append(org) if checker.has_perm('attach_positions', org): membership_orgs.append(org) for club in clubs: if checker.has_perm('add_announcements', club): post_clubs.append(club) if checker.has_perm('attach_positions', club): membership_clubs.append(club) context_dict = { 'post_orgs': post_orgs, 'membership_orgs': membership_orgs, 'post_clubs': post_clubs, 'membership_clubs': membership_clubs } return render(request, 'tangent/index.html', context_dict)
def tenant_callback(sender, instance, **kwargs): logger.debug("Tenant saved: {instance}".format(instance=instance)) if instance.group is None: # Create group for Tenant instance.group = Group.objects.create( name="TenantGroup{}".format(instance.pk)) checker = ObjectPermissionChecker(instance.group) if not checker.has_perm('view_tenant', instance): assign_perm('view_tenant', instance.group, instance) if not checker.has_perm('change_tenant', instance): assign_perm('change_tenant', instance.group, instance) # sync users in group with current list usersInGroup = User.objects.filter(groups=instance.group) usersToRemove = set(usersInGroup).difference(set(instance.users.all())) usersToAdd = set(instance.users.all()).difference(set(usersInGroup)) logger.debug("Removing: {}, Adding {}".format(usersToRemove, usersToAdd)) for user in usersToRemove: user.groups.remove(instance.group) usersToRemove.update() for user in usersToAdd: user.groups.add(instance.group) usersToAdd.update() logger.debug("Removed: {}, Added {}".format(usersToRemove, usersToAdd))
def add_invitations_officer(request, stream_id): stream = get_object_or_404(ProductionStream.objects.ongoing(), pk=stream_id) checker = ObjectPermissionChecker(request.user) if not checker.has_perm('can_perform_supervisory_actions', stream): return redirect(reverse('production:production', args=(stream.id, ))) form = AssignInvitationsOfficerForm(request.POST or None, instance=stream) if form.is_valid(): form.save() officer = form.cleaned_data.get('invitations_officer') assign_perm('can_work_for_stream', officer.user, stream) messages.success( request, 'Invitations Officer {officer} has been assigned.'.format( officer=officer)) event = ProductionEvent( stream=stream, event='assignment', comments=' tasked Invitations Officer with invitations:', noted_to=officer, noted_by=request.user.production_user) event.save() # Temp fix. # TODO: Implement proper email ProductionUtils.load({'stream': stream}) ProductionUtils.email_assigned_invitation_officer() else: for key, error in form.errors.items(): messages.warning(request, error[0]) return redirect(reverse('production:production', args=(stream.id, )))
def get_permissions_for(user_or_group, app_label, model, obj=None): if isinstance(user_or_group, Group): perms = user_or_group.permissions.all() else: perms = user_or_group.get_all_permissions() results = [] for perm in perms: p = perm.split('_') if perm.startswith(app_label) and (len(p) > 0) and (p[1] == model): results.append(perm) if obj is not None: if isinstance(user_or_group, Group): perms = ObjectPermissionChecker(user_or_group).get_perms(obj=obj) else: perms = user_or_group.get_all_permissions(obj=obj) for perm in perms: p = perm.split('_') if perm.startswith(app_label) and (len(p) > 0) and (p[1] == model): if (len(p) == 2) and p[2] == 'true': results.append(perm) else: results.append(perm) return results