def is_inbox(self): """Based on currently logged in user decide if message should marked as incomming message""" user = get_current_user() return (self.user_to == user and self.message_type not in [ MessageType.COLLECTION_REQUEST, ])
def __init__(self, *args, **kwargs): """Get currently logged in user that will be used to determine where to look for previously uploaded files, and then generate list of files that are available for selection (by default only .zip files are allowed)""" super(CollectionUploadDataForm, self).__init__(*args, **kwargs) user = get_current_user() self.username = user.username path = get_external_collections_path(username=self.username) files = [] # If upload user directory doesn't exists, create it if not os.path.exists(path): os.makedirs(path) for filename in os.listdir(path): ext = os.path.splitext(filename)[1] if ext in CollectionSettings.MEDIA_EXTENSIONS: files.append(filename) files.sort() self.fields['uploaded_media'] = forms.ChoiceField( label="Uploaded archive", choices=[('', '---------')] + zip(files, files), required=False, help_text= 'Optionally choose already uploaded data package (e.g. through FTP)' )
def __init__(self, *args, **kwargs): """Preselect research project and check if user has access to given ResearchProject """ super(ProjectForm, self).__init__(*args, **kwargs) user = get_current_user() projects_queryset = ResearchProject.objects.get_accessible( user=user, role_levels=ResearchProjectRoleType.EDIT) self.fields['research_project'].queryset = projects_queryset selected_value = self.initial.get('selected', None) if not self.instance.pk and selected_value: try: rproject = ResearchProject.objects.get(pk=selected_value) except ResearchProject.DoesNotExist: pass else: if rproject.can_update(user): self.fields['research_project'].initial = rproject.pk classificator_field = self.fields.get('classificator', None) if classificator_field: classificator_field.queryset = classificator_field.queryset.filter( disabled_at__isnull=True) if not self.instance.pk: self.fields['status'].widget = forms.HiddenInput()
def get_accessible(self, user=None, base_queryset=None, role_levels=None): """ Return all :class:`ResearchProject` instances that given user has access to. :param user: if not none then that user will be used to filter accessible research projects. :param base_queryset: queryset used to limit checked research projects. by default it's all projects. :return: research projects queryset """ user = user or get_current_user() if not user.is_authenticated(): return ResearchProject.objects.none() if base_queryset is None: queryset = super(ResearchProjectManager, self).get_queryset() else: queryset = base_queryset if user is not None and user.pk and role_levels: queryset = queryset.filter( Q(owner=user) | (Q(project_roles__user=user) & Q(project_roles__name__in=role_levels))).distinct() return queryset.filter(status=True)
def get_available(self, user=None, base_queryset=None, public=True, editable_only=False): user = user or get_current_user() resource_model = apps.get_model('storage', 'Resource') if base_queryset is None: queryset = self.get_queryset() else: queryset = base_queryset params = {} if public is not None: params['is_public'] = bool(public) if user.is_authenticated(): params['owner'] = user params['managers'] = user # if user has access to a resource (e.g. through a project role) # it should also have acccess to a resource's location if not editable_only: resources = resource_model.objects.get_accessible(user=user, basic=True) res_loc = queryset.filter(deployments__resources__in=resources ).order_by('id').distinct('id') params['pk__in'] = res_loc filter_params = reduce(operator.or_, map(models.Q, params.items())) return queryset.filter(filter_params)
def get_removable(self, user=None, base_queryset=None): """Get queryset with collections that can be removed by given user :param user: if not none then that user will be used to filter accessible collections. If passed user not logged in, then queryset is empty. If user is None then currently logged in user is used. :param base_queryset: queryset used to limit checked collections. by default it's all collections. """ user = user or get_current_user() if not user.is_authenticated(): return Collection.objects.none() if base_queryset is None: queryset = self.get_queryset() else: queryset = base_queryset level = CollectionMemberLevels.DELETE return queryset.filter( models.Q(owner=user) | models.Q(managers=user) | (models.Q(members=user) & models.Q(members__collectionmember__level=level))).distinct()
def get_accessible(self, user=None, base_queryset=None, role_levels=None): """Return all :class:`ResearchProjectCollection` instances that given user has access to. :param user: if not none then that user will be used to filter accessible research project collections. :param base_queryset: queryset used to limit checked research projects collections. By default it's all collections. :return: research projects collections queryset """ user = user or get_current_user() public = CollectionStatus.PUBLIC if role_levels is None: role_levels = [CollectionMemberLevels.ACCESS] if base_queryset is None: queryset = self.get_queryset() else: queryset = base_queryset if not user.is_authenticated(): return queryset.filter(collection__status=public) return queryset.filter( Q(collection__owner=user) | Q(collection__managers=user) | Q(collection__status=public) | (Q(collection__members=user) & Q( collection__members__collectionmember__level__in=role_levels)) ).distinct()
def can_view(self, user=None): """ ResearchProjectCollection can be accessed when user has permissions to change ResearchProject """ user = user or get_current_user() return self.project.can_update(user=user)
def delete_collection_notification(instance): """ Messages sent when collection is deleted to: * owner * all managers * owners of collections * all users that have access to resource """ user = get_current_user() recipients = set() # Owner recipients.add(instance.owner) # managers recipients.update(instance.managers.all()) # people with access recipients.update( CollectionMember.objects.filter(collection=instance, level=CollectionMemberLevels.ACCESS)) for recipient in recipients: if user and recipient: Message.objects.create( subject=u"Collection: {name} has been deleted".format( name=instance.name), text=u"Collection: {name} has been deleted".format( name=instance.name), user_from=user, user_to=recipient, date_sent=now(), message_type=MessageType.RESOURCE_DELETED)
def __init__(self, *args, **kwargs): """""" super(DeploymentImportForm, self).__init__(*args, **kwargs) user = get_current_user() self.fields[ 'research_project'].queryset = ResearchProject.objects.get_accessible( user=user, role_levels=ResearchProjectRoleType.EDIT)
def get_accessible(cls, user=None): user = user or get_current_user() if user.is_authenticated(): queryset = Map.objects.filter( models.Q(owner=user) | models.Q(editors=user)) else: queryset = Map.objects.filter(share_status=Map.PUBLIC) return queryset
def __init__(self, *args, **kwargs): super(LocationImportForm, self).__init__(*args, **kwargs) user = get_current_user() self.fields['research_project'].help_text = None self.fields[ 'research_project'].queryset = ResearchProject.objects.get_accessible( user=user, role_levels=ResearchProjectRoleType.EDIT)
def get_all_choices(cls, base_choices=None): if base_choices: user = get_current_user() if user and user.is_authenticated(): base_choices = base_choices.exclude(pk=user.pk) choices = tuple(base_choices.values_list('pk', 'username')) else: choices = super(CollectionManagers, cls).get_all_choices() return (cls.ALL_CHOICE,) + choices
def __init__(self, *args, **kwargs): """""" super(ClassificationImportForm, self).__init__(*args, **kwargs) user = get_current_user() projects = ClassificationProject.objects.filter( classification_project_roles__user=user, classification_project_roles__name=1).distinct().order_by('name') self.fields['project'].queryset = projects
def __init__(self, **kwargs): """Limit available research projects only to those that are accessible to a user""" super(CollectionRequestForm, self).__init__(**kwargs) user = get_current_user() self.fields['project'].queryset = ResearchProject.objects.filter( status=True).filter( Q(owner=user) | (Q(project_roles__name__in=self.REQUIRED_PROJECT_ROLES) & Q(project_roles__user=user))).distinct()
def get_user_roles(self, user=None): """Returns a tuple of project roles for given user. :param: user :class:`auth.User` instance for which the roles are determined :return: list of role names of given user withing the project """ user = user or get_current_user() roles = self.project_roles.filter(user=user) return [role.get_name_display() for role in roles]
def can_view(self, user=None, member_levels=None): """ Checks if given user has access to details. :param user: if passed, permissions will be checked against given user will be used. If user is None then current request will be checked for currently logged in user and this user will be used. Otherwise only PUBLIC resources are available to view details :param member_levels: roles required to view details. By default ACCESS level is required to view details :return: boolean access status """ user = user or get_current_user() member_levels = member_levels or [ self.member_levels.ACCESS, self.member_levels.ACCESS_REQUEST, ] if self.status == self.status_choices.PUBLIC: return True else: user = user or get_current_user() access_status = ( # Legacy code begin self.owner == user or user in self.managers.all() # Legacy code end ) if user.is_authenticated(): params = { 'user': user, 'level__in': member_levels, self._meta.model_name: self } access_status = ( access_status or self.members.through.objects.filter(**params).exists() ) return access_status
def can_view(self, user=None): """Determines whether user can view the location. :param user: user for which the test is made :type user: :py:class:`django.contrib.auth.User` :return: True if user can see the location, False otherwise :rtype: bool """ user = user or get_current_user() return (self.is_public or user == self.owner or user in self.managers.all())
def can_delete(self, user=None): """Determines whether given user can delete the project. :param: user :class:`auth.User` instance for which test is made :return: True if user can delete the project, False otherwise """ user = user or get_current_user() return self.status is True and user.is_authenticated() and ( self.owner == user or self.project_roles.filter( user=user, name__in=ResearchProjectRoleType.DELETE).exists())
def can_view(self, user=None): """Determines whether given user can see the details of a project. :param: user :class:`auth.User` instance for which test is made :return: True if user can see the details of the project, False otherwise """ user = user or get_current_user() return self.status is True and user.is_authenticated() and ( self.owner == user or self.project_roles.filter(user=user).exists())
def get_orphaned_resources(self, user=None): """ """ user = user or get_current_user() if self.can_update(user=user): all_res = self.resources.values_list('pk', flat=True) accessible = self.resources.get_accessible(user=user).values_list( 'pk', flat=True) diff_pks = list(set(all_res).difference(set(accessible))) return diff_pks else: return None
def can_view(self, user=None): """Determines whether user can view the deployment. :param user: user for which the test is made :type user: :py:class:`django.contrib.auth.User` :return: True if user can see the deployment, False otherwise :rtype: bool """ user = user or get_current_user() if user == self.owner or user in self.managers.all(): return True if self.resources.get_accessible(user=user, basic=True).count(): return True return False
def clean_definition_file(self): """Validate config file to be valid yaml file and match schema used for uploading collections""" user = get_current_user() definition_file = self.cleaned_data['definition_file'].file.read() processor = CollectionProcessor(definition_file=definition_file, owner=user) errors = processor.validate_definition() if errors: errors = mark_safe( errors.replace(CollectionProcessor.SEPARATOR, '<br/>')) raise forms.ValidationError(errors) return definition_file
def save(self, *args, **kwargs): """Before saving comment user that posted comment has to be determined. This is done by using threadlocals that can store request or user connected to request. Also if submit date is not specified, it's set to current datetime """ user = get_current_user() if not self.pk and self.user is None and user.is_authenticated(): self.user = user if self.submit_date is None: self.submit_date = timezone.now() super(UserComment, self).save(*args, **kwargs)
def get_accessible(self, user=None, base_queryset=None, editable_only=False): """Return all :class:`Deployment` instances that given user has access to. If user is not defined, then currently logged in user is used. :param user: if not none then that user will be used to filter accessible deployments. If user is None then currently logged in user is used. :param base_queryset: queryset used to limit checked deployments. by default it's all deployments. :return: deployments queryset """ resource_model = apps.get_model('storage', 'Resource') user = user or get_current_user() if base_queryset is None: queryset = self.get_queryset() else: queryset = base_queryset if not user.is_authenticated(): return queryset.none() params = {} if user.is_authenticated(): params['owner'] = user params['managers'] = user # # if user has access to a resource (e.g. through a project role) # # it should also have acccess to data on related deployment if not editable_only: resources = resource_model.objects.get_accessible(user=user, basic=True) res_dep = queryset.filter( resources__in=resources).order_by('id').distinct('id') params['pk__in'] = res_dep filter_params = reduce(operator.or_, map(models.Q, params.items())) return queryset.filter(filter_params)
def get_ondemand(self, user, base_queryset=None): """ """ user = user or get_current_user() if not user.is_authenticated(): return Collection.objects.none() ondemand = CollectionStatus.ON_DEMAND if base_queryset is None: queryset = self.get_queryset() else: queryset = base_queryset return queryset.filter(status=ondemand).exclude( models.Q(owner=user) | models.Q(managers=user) | (models.Q(collectionmember__user=user) & models.Q(collectionmember__level=1))).distinct()
def __init__(self, *args, **kwargs): self.helper = FormHelper() self.helper.form_tag = True self.helper.form_id = 'filter-locations-form' self.helper.error_text_inline = True self.helper.form_show_errors = False self.helper.help_text_inline = False self.helper.form_show_labels = True self.helper.layout = Layout( Fieldset('Basic filters', 'locations_map', 'search', 'research_project'), Fieldset('Spatial filters', 'in_bbox', 'radius'), ) super(LocationFilterForm, self).__init__(*args, **kwargs) user = get_current_user() self.fields[ 'research_project'].queryset = ResearchProject.objects.get_accessible( user=user, role_levels=ResearchProjectRoleType.EDIT)
def get_accessible(self, user=None, base_queryset=None, role_levels=None): """Return all :class:`Collection` instances that given user has access to. If user is not defined, then currently logged in user is used. If there is no authenticated user then only :class:`apps.storage.taxonomy.CollectionStatus.PUBLIC` collections are returned :param user: if not none then that user will be used to filter accessible collections. If passed user not logged in, then collections are limited to PUBLIC only. If user is None then currently logged in user is used. :param base_queryset: queryset used to limit checked collections. by default it's all collections. :param role_levels: list of :class:`CollectionMemberLevels` levels that user is required to have to access collections :return: collections queryset """ user = user or get_current_user() public = CollectionStatus.PUBLIC if not role_levels: role_levels = (CollectionMemberLevels.ACCESS, CollectionMemberLevels.ACCESS_REQUEST) if base_queryset is None: queryset = self.get_queryset() else: queryset = base_queryset if not user.is_authenticated(): return queryset.filter(status=public) colmem = CollectionMember.objects.filter( user=user, level__in=role_levels).values_list('pk', flat=True) colmem_col = queryset.filter(collectionmember__in=colmem).order_by( 'id').distinct('id').values_list('pk', flat=True) return queryset.filter( models.Q(owner=user) | models.Q(managers=user) | models.Q(status=public) | models.Q(pk__in=colmem_col))
def can_delete(self, user=None, member_levels=None): """ Check if given user has access to delete a record. :param user: if passed, permissions will be checked against given user will be used. If user is None then current request will be checked for currently logged in user and this user will be used. Otherwise access is forbidden :return: boolean access status """ user = user or get_current_user() if not user.is_authenticated(): return False result = ( self.owner_id == user.pk or user in self.managers.all() ) return result
def clean(self): """ When collection and its resources are saved and the status of this collection is set to "Public" or "OnDemand" check if this collection can be published or shared. This should be only possible when a user has editing rights to all resources that are part of this collection. """ cleaned_data = super(CollectionForm, self).clean() status = cleaned_data.get('status') resources_pks = cleaned_data.pop('resources_pks', None) app = cleaned_data.pop('app', None) if resources_pks: pks_list = parse_pks(resources_pks) if app == 'media_classification': resources = Resource.objects.get_accessible().filter( classifications__pk__in=pks_list) else: resources = Resource.objects.get_accessible().filter( pk__in=pks_list) if resources: cleaned_data['resources'] = resources if status != 'Private': if self.instance.pk: resources = self.instance.resources.all() else: resources = cleaned_data.get('resources', None) if not resources: return cleaned_data user = get_current_user() n = resources.exclude(Q(owner=user) | Q(managers=user)).count() if n != 0: errors = mark_safe( 'You are not allowed to set the status of this collection ' 'to <strong>{status}</strong> as you are not the owner of all resources ' 'that are part of this collection.'.format(status=status)) raise forms.ValidationError(errors) return cleaned_data