def assign_object_to_member(group_member, obj, **kwargs): """Assign an object to a GroupMember instance object. :Parameters: - `group_member`: groups_manager.model.GroupMember instance - `obj`: object to set permissions :Kwargs: - `custom_permissions`: updates settings.GROUPS_MANAGER['PERMISSIONS'] """ from groups_manager.settings import GROUPS_MANAGER if GROUPS_MANAGER['AUTH_MODELS_SYNC'] and \ group_member.group.django_group and group_member.member.django_user: roles_attr = kwargs.get('roles_attr', 'roles') permissions = copy.deepcopy(GROUPS_MANAGER['PERMISSIONS']) permissions.update(kwargs.get('custom_permissions', {})) # owner if isinstance(permissions['owner'], dict): roles = getattr(group_member, roles_attr).values_list('codename', flat=True) owner_perms = [] for role in list(set(roles).intersection(set(permissions['owner'].keys()))) + ['default']: owner_perms += permissions['owner'].get(role, []) else: owner_perms = permissions['owner'] for permission in list(set(owner_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, group_member.member.django_user, obj) # group group_perms = permissions.get('group', []) for permission in list(set(group_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, group_member.group.django_group, obj) # groups_upstream upstream_groups = [group.django_group for group in group_member.group.get_ancestors()] upstream_perms = permissions.get('groups_upstream', []) for django_group in upstream_groups: for permission in list(set(upstream_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj) # groups_downstream downstream_groups = \ [group.django_group for group in group_member.group.get_descendants()] downstream_perms = permissions.get('groups_downstream', []) for django_group in downstream_groups: for permission in list(set(downstream_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj) # groups_siblings siblings_groups = [group.django_group for group in group_member.group.get_siblings()] siblings_perms = permissions.get('groups_siblings', []) for django_group in siblings_groups: for permission in list(set(siblings_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj)
def assign_object_to_member(group_member, obj, **kwargs): """Assign an object to a GroupMember instance object. :Parameters: - `group_member`: groups_manager.model.GroupMember instance - `obj`: object to set permissions :Kwargs: - `custom_permissions`: updates settings.GROUPS_MANAGER['PERMISSIONS'] """ from groups_manager.settings import GROUPS_MANAGER if GROUPS_MANAGER['AUTH_MODELS_SYNC'] and \ group_member.group.django_group and group_member.member.django_user: roles_attr = kwargs.get('roles_attr', 'roles') permissions = copy.deepcopy(GROUPS_MANAGER['PERMISSIONS']) permissions.update(kwargs.get('custom_permissions', {})) # owner if isinstance(permissions['owner'], dict): roles = getattr(group_member, roles_attr).values_list('codename', flat=True) owner_perms = [] for role in list( set(roles).intersection(set( permissions['owner'].keys()))) + ['default']: owner_perms += permissions['owner'].get(role, []) else: owner_perms = permissions['owner'] for permission in list(set(owner_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, group_member.member.django_user, obj) # group group_perms = permissions.get('group', []) for permission in list(set(group_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, group_member.group.django_group, obj) # groups_upstream upstream_groups = group_member.group.get_ancestors() upstream_perms = permissions.get('groups_upstream', []) assign_related(upstream_groups, upstream_perms, obj) # groups_downstream downstream_groups = group_member.group.get_descendants() downstream_perms = permissions.get('groups_downstream', []) assign_related(downstream_groups, downstream_perms, obj) # groups_siblings siblings_groups = group_member.group.get_siblings() siblings_perms = permissions.get('groups_siblings', []) assign_related(siblings_groups, siblings_perms, obj)
def assign_object_to_group(group, obj, **kwargs): """Assign an object to a Group instance object. :Parameters: - `group`: groups_manager.model.Group instance - `obj`: object to set permissions :Kwargs: - `custom_permissions`: updates settings.GROUPS_MANAGER['PERMISSIONS'] """ from groups_manager.settings import GROUPS_MANAGER if GROUPS_MANAGER['AUTH_MODELS_SYNC'] and group.django_group: permissions = copy.deepcopy(GROUPS_MANAGER['PERMISSIONS']) permissions.update(kwargs.get('custom_permissions', {})) # owner is ignored from permissions # group group_perms = permissions.get('group', []) for permission in list(set(group_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, group.django_group, obj) # groups_upstream upstream_groups = [ ancestor_group.django_group for ancestor_group in group.get_ancestors() ] upstream_perms = permissions.get('groups_upstream', []) for django_group in upstream_groups: for permission in list(set(upstream_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj) # groups_downstream downstream_groups = \ [downstream_group.django_group for downstream_group in group.get_descendants()] downstream_perms = permissions.get('groups_downstream', []) for django_group in downstream_groups: for permission in list(set(downstream_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj) # groups_siblings siblings_groups = [ sibling_group.django_group for sibling_group in group.get_siblings() ] siblings_perms = permissions.get('groups_siblings', []) for django_group in siblings_groups: for permission in list(set(siblings_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj)
def test_get_objects_for_user_with_user_permissions(self): user_perm = Permission.objects.create(codename='user_perm', content_type=self.ctype) perm = get_permission_name(user_perm, self.uppsala_ip) assign_perm(perm, self.user_uppsala, self.uppsala_ip) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['foo'])), []) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['user_perm'])), [self.uppsala_ip])
def test_get_objects_for_user_with_group_permissions(self): group_perm = Permission.objects.create(codename='group_perm', content_type=self.ctype) perms = {'group': [get_permission_name(group_perm, self.uppsala_ip)]} self.uppsala.assign_object(self.uppsala_ip, custom_permissions=perms) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['foo'])), []) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['group_perm'])), [self.uppsala_ip])
def assign_object_to_group(group, obj, **kwargs): """Assign an object to a Group instance object. :Parameters: - `group`: groups_manager.model.Group instance - `obj`: object to set permissions :Kwargs: - `custom_permissions`: updates settings.GROUPS_MANAGER['PERMISSIONS'] """ from groups_manager.settings import GROUPS_MANAGER if GROUPS_MANAGER['AUTH_MODELS_SYNC'] and group.django_group: permissions = copy.deepcopy(GROUPS_MANAGER['PERMISSIONS']) permissions.update(kwargs.get('custom_permissions', {})) # owner is ignored from permissions # group group_perms = permissions.get('group', []) for permission in list(set(group_perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, group.django_group, obj) # groups_upstream upstream_groups = group.get_ancestors() upstream_perms = permissions.get('groups_upstream', []) assign_related(upstream_groups, upstream_perms, obj) # groups_downstream downstream_groups = group.get_descendants() downstream_perms = permissions.get('groups_downstream', []) assign_related(downstream_groups, downstream_perms, obj) # groups_siblings siblings_groups = group.get_siblings() siblings_perms = permissions.get('groups_siblings', []) assign_related(siblings_groups, siblings_perms, obj)
def test_get_permissions_for_user_with_user_permissions(self): user_perm = Permission.objects.create(codename='user_perm', content_type=self.ctype) perm = get_permission_name(user_perm, self.uppsala_ip) assign_perm(perm, self.user_uppsala, self.uppsala_ip) self.expected_user_perms.append('user_perm') six.assertCountEqual(self, self.user_uppsala.get_all_permissions(self.uppsala_ip), self.expected_user_perms) six.assertCountEqual(self, self.user_uppsala.get_all_permissions(self.sthlm_ip), [])
def test_get_permissions_for_user_with_group_permissions(self): group_perm = Permission.objects.create(codename='group_perm', content_type=self.ctype) perms = {'group': [get_permission_name(group_perm, self.uppsala_ip)]} self.uppsala.assign_object(self.uppsala_ip, custom_permissions=perms) self.expected_user_perms.append('group_perm') six.assertCountEqual(self, self.user_uppsala.get_all_permissions(self.uppsala_ip), self.expected_user_perms) six.assertCountEqual(self, self.user_uppsala.get_all_permissions(self.sthlm_ip), [])
def test_objects_added_to_user(self): ip = InformationPackage.objects.create() perm_name = get_permission_name('view_informationpackage', ip) assign_perm(perm_name, self.user, ip) qs = InformationPackage.objects.all() self.assertFalse(get_objects_for_user(self.user, qs, []).exists()) self.assertEqual(get_objects_for_user(self.user, qs, ['view_informationpackage']).get(), ip)
def test_objects_added_to_child_group(self): ip = InformationPackage.objects.create() parent = Group.objects.create(name='parent') parent.add_member(self.member) group = Group.objects.create(parent=parent) perm_name = get_permission_name('view_informationpackage', ip) assign_perm(perm_name, parent.django_group, ip) qs = InformationPackage.objects.all() self.assertEqual(get_objects_for_user(self.user, qs, ['view_informationpackage']).get(), ip)
def assign_related(related_groups, perms, obj): if isinstance(perms, dict): default = set(perms.pop('default', [])) for group in related_groups: django_group = group.django_group for permission in default: perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj) if group.group_type is not None: for permission in set(perms.get(group.group_type.codename, [])): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj) else: for group in related_groups: django_group = group.django_group for permission in list(set(perms)): perm_name = get_permission_name(permission, obj) assign_perm(perm_name, django_group, obj)
def create_new_generation(self, state, responsible, object_identifier_value): perms = deepcopy(getattr(settings, 'IP_CREATION_PERMS_MAP', {})) new_aip = deepcopy(self) new_aip.pk = None new_aip.active = True new_aip.object_identifier_value = None new_aip.state = state new_aip.cached = False new_aip.archived = False new_aip.object_path = '' new_aip.responsible = responsible with transaction.atomic(): max_generation = InformationPackage.objects.select_for_update( ).filter(aic=self.aic).aggregate( Max('generation'))['generation__max'] new_aip.generation = max_generation + 1 new_aip.save() new_aip.object_identifier_value = object_identifier_value if object_identifier_value is not None else str( new_aip.pk) new_aip.save(update_fields=['object_identifier_value']) for profile_ip in self.profileip_set.all(): new_profile_ip = deepcopy(profile_ip) new_profile_ip.pk = None new_profile_ip.ip = new_aip new_profile_ip.save() member = Member.objects.get(django_user=responsible) user_perms = perms.pop('owner', []) organization = responsible.user_profile.current_organization organization.assign_object(new_aip, custom_permissions=perms) organization.add_object(new_aip) for perm in user_perms: perm_name = get_permission_name(perm, new_aip) assign_perm(perm_name, member.django_user, new_aip) return new_aip
def run(self, sip_path): sip_path, = self.parse_params(sip_path) sip_path = pathlib.Path(sip_path) user = User.objects.get(pk=self.responsible) perms = copy.deepcopy(getattr(settings, 'IP_CREATION_PERMS_MAP', {})) organization = user.user_profile.current_organization object_identifier_value = sip_path.stem existing_sip = InformationPackage.objects.filter( Q( Q(object_path=sip_path) | Q(object_identifier_value=object_identifier_value), ), package_type=InformationPackage.SIP).first() xmlfile = sip_path.with_suffix('.xml') if existing_sip is None: parsed = parse_submit_description(xmlfile.as_posix(), srcdir=sip_path.parent) parsed_sa = parsed.get('altrecordids', {}).get('SUBMISSIONAGREEMENT', [None])[0] if parsed_sa is not None: raise ValueError('No submission agreement found in xml') sa = SubmissionAgreement.objects.get(pk=parsed_sa) with transaction.atomic(): ip = InformationPackage.objects.create( object_identifier_value=object_identifier_value, sip_objid=object_identifier_value, sip_path=sip_path.as_posix(), package_type=InformationPackage.AIP, state='Prepared', responsible=user, submission_agreement=sa, submission_agreement_locked=True, object_path=sip_path.as_posix(), package_mets_path=xmlfile.as_posix(), ) member = Member.objects.get(django_user=user) user_perms = perms.pop('owner', []) organization.assign_object(ip, custom_permissions=perms) organization.add_object(ip) for perm in user_perms: perm_name = get_permission_name(perm, ip) assign_perm(perm_name, member.django_user, ip) # refresh date fields to convert them to datetime instances instead of # strings to allow further datetime manipulation ip.refresh_from_db( fields=['entry_date', 'start_date', 'end_date']) ip.create_profile_rels( [x.lower().replace(' ', '_') for x in profile_types], user) else: with transaction.atomic(): ip = existing_sip ip.sip_objid = object_identifier_value ip.sip_path = sip_path.as_posix() ip.package_type = InformationPackage.AIP ip.responsible = user ip.state = 'Prepared' ip.object_path = sip_path.as_posix() ip.package_mets_path = xmlfile.as_posix() ip.save() return str(ip.pk)
def create(self, request, *args, **kwargs): """ Prepares a new information package (IP) using the following tasks: 1. Creates a new IP in the database. 2. Creates a directory in the prepare directory with the name set to the id of the new IP. 3. Creates an event in the database connected to the IP and with the detail "Prepare IP". Args: Returns: None """ self.check_permissions(request) try: label = request.data['label'] except KeyError: raise exceptions.ParseError('Missing parameter label') object_identifier_value = request.data.get('object_identifier_value') responsible = self.request.user if responsible.user_profile.current_organization is None: raise exceptions.ParseError( 'You must be part of an organization to prepare an IP') prepare_path = Path.objects.get(entity="path_preingest_prepare").value if object_identifier_value: ip_exists = InformationPackage.objects.filter( object_identifier_value=object_identifier_value).exists() if ip_exists: raise Conflict( 'IP with object identifer value "%s" already exists' % object_identifier_value) if os.path.exists( os.path.join(prepare_path, object_identifier_value)): raise Conflict( 'IP with identifier "%s" already exists on disk' % object_identifier_value) perms = copy.deepcopy(getattr(settings, 'IP_CREATION_PERMS_MAP', {})) try: with transaction.atomic(): ip = InformationPackage.objects.create( object_identifier_value=object_identifier_value, label=label, responsible=responsible, state="Preparing", package_type=InformationPackage.SIP) ip.entry_date = ip.create_date extra = { 'event_type': 10100, 'object': str(ip.pk), 'agent': request.user.username, 'outcome': EventIP.SUCCESS } self.logger.info( "Prepared {obj}".format(obj=ip.object_identifier_value), extra=extra) member = Member.objects.get(django_user=responsible) user_perms = perms.pop('owner', []) organization = member.django_user.user_profile.current_organization organization.assign_object(ip, custom_permissions=perms) organization.add_object(ip) for perm in user_perms: perm_name = get_permission_name(perm, ip) assign_perm(perm_name, member.django_user, ip) obj_path = normalize_path( os.path.join(prepare_path, ip.object_identifier_value)) os.mkdir(obj_path) ip.object_path = obj_path ip.save() extra = { 'event_type': 10200, 'object': str(ip.pk), 'agent': request.user.username, 'outcome': EventIP.SUCCESS } self.logger.info("Created IP root directory", extra=extra) except IntegrityError: try: shutil.rmtree(obj_path) except OSError as e: pass raise return Response({"detail": "Prepared IP"}, status=status.HTTP_201_CREATED)