def test_approval_after_initiator_is_merged_into_another_user(
            self, mock_enqueue):
        approver = factories.UserFactory()
        approver.add_system_tag(settings.PREREG_ADMIN_TAG)

        mergee = factories.UserFactory(fullname='Manny Mergee')
        merger = factories.UserFactory(fullname='Merve Merger')
        project = factories.ProjectFactory(creator=mergee)
        registration_schema = MetaSchema.find_one(
            Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2))
        draft = factories.DraftRegistrationFactory(
            branched_from=project,
            registration_schema=registration_schema,
        )
        merger.merge_user(mergee)
        approval = DraftRegistrationApproval(
            meta={'registration_choice': 'immediate'})
        approval.save()
        draft.approval = approval
        draft.save()
        approval.approve(approver)

        draft.reload()
        registered_node = draft.registered_node
        assert registered_node.registered_user == merger
Exemple #2
0
    def get_file_guids(cls, materialized_path, provider, node):
        guids = []
        materialized_path = '/' + materialized_path.lstrip('/')
        if materialized_path.endswith('/'):
            # it's a folder
            folder_children = cls.find(
                Q('provider', 'eq', provider) & Q('node', 'eq', node)
                & Q('_materialized_path', 'startswith', materialized_path))
            for item in folder_children:
                if item.kind == 'file':
                    guid = item.get_guid()
                    if guid:
                        guids.append(guid._id)
        else:
            # it's a file
            try:
                file_obj = cls.find_one(
                    Q('node', 'eq', node)
                    & Q('_materialized_path', 'eq', materialized_path))
            except NoResultsFound:
                return guids
            guid = file_obj.get_guid()
            if guid:
                guids.append(guid._id)

        return guids
    def test_on_complete_embargo_creates_registration_for_draft_initiator(
            self, mock_enquque):
        user = factories.UserFactory()
        end_date = timezone.now() + datetime.timedelta(
            days=366)  # <- leap year
        approval = DraftRegistrationApproval(
            meta={
                'registration_choice': 'embargo',
                'embargo_end_date': end_date.isoformat()
            })
        approval.save()
        project = factories.ProjectFactory(creator=user)
        registration_schema = MetaSchema.find_one(
            Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2))
        draft = factories.DraftRegistrationFactory(
            branched_from=project,
            registration_schema=registration_schema,
        )
        draft.approval = approval
        draft.save()

        approval._on_complete(user)
        draft.reload()
        registered_node = draft.registered_node
        assert registered_node is not None
        assert registered_node.is_pending_embargo
        assert registered_node.registered_user == draft.initiator
Exemple #4
0
    def test_on_complete_immediate_creates_registration_for_draft_initiator(self, mock_enquque):
        ensure_schemas()
        user = factories.UserFactory()
        project = factories.ProjectFactory(creator=user)
        registration_schema = MetaSchema.find_one(
            Q('name', 'eq', 'Prereg Challenge') &
            Q('schema_version', 'eq', 2)
        )
        draft = factories.DraftRegistrationFactory(
            branched_from=project,
            registration_schema=registration_schema,
        )
        approval = DraftRegistrationApproval(
            meta={
                'registration_choice': 'immediate'
            }
        )
        approval.save()
        draft.approval = approval
        draft.save()
        approval._on_complete(user)
        draft.reload()
        registered_node = draft.registered_node

        assert registered_node is not None
        assert registered_node.is_pending_registration
        assert registered_node.registered_user == draft.initiator
Exemple #5
0
def get_configured_projects(user):
    """Filter all user subscriptions for ones that are on parent projects
     and return the node objects.

    :param user: modular odm User object
    :return: list of node objects for projects with no parent
    """
    configured_projects = set()
    user_subscriptions = get_all_user_subscriptions(
        user,
        extra=(Q('node__type', 'ne', 'osf.collection')
               & Q('node__is_deleted', 'eq', False)))

    for subscription in user_subscriptions:
        if subscription is None:
            continue
        # If the user has opted out of emails skip
        node = subscription.owner

        if ((subscription.none.filter(id=user.id).exists()
             and not node.parent_id)
                or node._id not in user.notifications_configured):
            continue

        root = node.root

        if not root.is_deleted:
            configured_projects.add(root)

    return sorted(configured_projects, key=lambda n: n.title.lower())
Exemple #6
0
    def _find_matching_archive(self, save=True):
        """Find another version with the same sha256 as this file.
        If found copy its vault name and glacier id, no need to create additional backups.
        returns True if found otherwise false
        """

        if 'sha256' not in self.metadata:
            return False  # Dont bother searching for nothing

        if 'vault' in self.metadata and 'archive' in self.metadata:
            # Shouldn't ever happen, but we already have an archive
            return True  # We've found ourself

        qs = self.__class__.find(
            Q('_id', 'ne', self._id)
            & Q('metadata.sha256', 'eq', self.metadata['sha256'])
            & Q('metadata.archive', 'ne', None)
            & Q('metadata.vault', 'ne', None)).limit(1)
        if qs.count() < 1:
            return False
        other = qs[0]
        try:
            self.metadata['vault'] = other.metadata['vault']
            self.metadata['archive'] = other.metadata['archive']
        except KeyError:
            return False
        if save:
            self.save()
        return True
Exemple #7
0
 def _create(cls, *args, **kwargs):
     try:
         models.NodeLicense.find_one(Q('name', 'eq', 'No license'))
     except NoResultsFound:
         ensure_licenses()
     kwargs['node_license'] = kwargs.get(
         'node_license',
         models.NodeLicense.find_one(Q('name', 'eq', 'No license')))
     return super(NodeLicenseRecordFactory, cls)._create(*args, **kwargs)
Exemple #8
0
def get_targets():
    logger.info('Acquiring targets...')
    targets = [
        u for u in OSFUser.find(Q('merged_by', 'eq', None)) if Collection.find(
            Q('is_bookmark_collection', 'eq', True)
            & Q('is_deleted', 'eq', False)
            & Q('creator', 'eq', u)).count() == 0
    ]
    logger.info('Found {} target users.'.format(len(targets)))
    return targets
Exemple #9
0
 def find_sent_of_same_type_and_user(self):
     """
     Queries up for all emails of the same type as self, sent to the same user as self.
     Does not look for queue-up emails.
     :return: a list of those emails
     """
     return self.__class__.find(
         Q('email_type', 'eq', self.email_type) &
         Q('user', 'eq', self.user) &
         Q('sent_at', 'ne', None)
     )
Exemple #10
0
def get_parent_notification_type(node, event, user):
    """
    Given an event on a node (e.g. comment on node 'xyz'), find the user's notification
    type on the parent project for the same event.
    :param obj node: event owner (Node or User object)
    :param str event: notification event (e.g. 'comment_replies')
    :param obj user: modular odm User object
    :return: str notification type (e.g. 'email_transactional')
    """
    AbstractNode = apps.get_model('osf.AbstractNode')
    NotificationSubscription = apps.get_model('osf.NotificationSubscription')

    if node and isinstance(
            node, AbstractNode
    ) and node.parent_node and node.parent_node.has_permission(user, 'read'):
        parent = node.parent_node
        key = to_subscription_key(parent._id, event)
        try:
            subscription = NotificationSubscription.find_one(
                Q('_id', 'eq', key))
        except NoResultsFound:
            return get_parent_notification_type(parent, event, user)

        for notification_type in constants.NOTIFICATION_TYPES:
            if getattr(subscription,
                       notification_type).filter(id=user.id).exists():
                return notification_type
        else:
            return get_parent_notification_type(parent, event, user)
    else:
        return None
Exemple #11
0
 def test_sanction_embargo_termination_first(self):
     embargo_termination_approval = factories.EmbargoTerminationApprovalFactory(
     )
     registration = Registration.find_one(
         Q('embargo_termination_approval', 'eq',
           embargo_termination_approval))
     assert registration.sanction == embargo_termination_approval
Exemple #12
0
    def _email_template_context(self,
                                user,
                                node,
                                is_authorizer=False,
                                urls=None):
        urls = urls or self.stashed_urls.get(user._id, {})
        registration_link = urls.get('view', self._view_url(user._id, node))
        if is_authorizer:
            Registration = apps.get_model('osf.Registration')

            approval_link = urls.get('approve', '')
            disapproval_link = urls.get('reject', '')
            approval_time_span = osf_settings.RETRACTION_PENDING_TIME.days * 24

            registration = Registration.find_one(Q('retraction', 'eq', self))

            return {
                'is_initiator': self.initiated_by == user,
                'initiated_by': self.initiated_by.fullname,
                'project_name': registration.title,
                'registration_link': registration_link,
                'approval_link': approval_link,
                'disapproval_link': disapproval_link,
                'approval_time_span': approval_time_span,
            }
        else:
            return {
                'initiated_by': self.initiated_by.fullname,
                'registration_link': registration_link,
            }
Exemple #13
0
    def _on_complete(self, user):
        Registration = apps.get_model('osf.Registration')
        NodeLog = apps.get_model('osf.NodeLog')

        parent_registration = Registration.find_one(Q('retraction', 'eq',
                                                      self))
        parent_registration.registered_from.add_log(
            action=NodeLog.RETRACTION_APPROVED,
            params={
                'node': parent_registration.registered_from._id,
                'retraction_id': self._id,
                'registration': parent_registration._id
            },
            auth=Auth(self.initiated_by),
        )
        # Remove any embargoes associated with the registration
        if parent_registration.embargo_end_date or parent_registration.is_pending_embargo:
            parent_registration.embargo.state = self.REJECTED
            parent_registration.registered_from.add_log(
                action=NodeLog.EMBARGO_CANCELLED,
                params={
                    'node': parent_registration.registered_from._id,
                    'registration': parent_registration._id,
                    'embargo_id': parent_registration.embargo._id,
                },
                auth=Auth(self.initiated_by),
            )
            parent_registration.embargo.save()
        # Ensure retracted registration is public
        # Pass auth=None because the registration initiator may not be
        # an admin on components (component admins had the opportunity
        # to disapprove the retraction by this point)
        for node in parent_registration.node_and_primary_descendants():
            node.set_privacy('public', auth=None, save=True, log=False)
            node.update_search()
Exemple #14
0
    def merge(self, user_settings):
        """Merge `user_settings` into this instance"""
        if user_settings.__class__ is not self.__class__:
            raise TypeError('Cannot merge different addons')

        for node_id, data in user_settings.oauth_grants.iteritems():
            if node_id not in self.oauth_grants:
                self.oauth_grants[node_id] = data
            else:
                node_grants = user_settings.oauth_grants[node_id].iteritems()
                for ext_acct, meta in node_grants:
                    if ext_acct not in self.oauth_grants[node_id]:
                        self.oauth_grants[node_id][ext_acct] = meta
                    else:
                        for k, v in meta:
                            if k not in self.oauth_grants[node_id][ext_acct]:
                                self.oauth_grants[node_id][ext_acct][k] = v

        user_settings.oauth_grants = {}
        user_settings.save()

        try:
            config = settings.ADDONS_AVAILABLE_DICT[
                self.oauth_provider.short_name]
            Model = config.models['nodesettings']
        except KeyError:
            pass
        else:
            connected = Model.find(Q('user_settings', 'eq', user_settings))
            for node_settings in connected:
                node_settings.user_settings = self
                node_settings.save()

        self.save()
Exemple #15
0
    def _on_complete(self, user):
        DraftRegistration = apps.get_model('osf.DraftRegistration')

        draft = DraftRegistration.find_one(
            Q('approval', 'eq', self)
        )
        auth = Auth(draft.initiator)
        registration = draft.register(
            auth=auth,
            save=True
        )
        registration_choice = self.meta['registration_choice']

        if registration_choice == 'immediate':
            sanction = functools.partial(registration.require_approval, draft.initiator)
        elif registration_choice == 'embargo':
            embargo_end_date = parse_date(self.meta.get('embargo_end_date'))
            if not embargo_end_date.tzinfo:
                embargo_end_date = embargo_end_date.replace(tzinfo=pytz.UTC)
            sanction = functools.partial(
                registration.embargo_registration,
                draft.initiator,
                embargo_end_date
            )
        else:
            raise ValueError("'registration_choice' must be either 'embargo' or 'immediate'")
        sanction(notify_initiator_on_complete=True)
Exemple #16
0
 def _create(cls, *args, **kwargs):
     kwargs['node_license'] = kwargs.get(
         'node_license',
         models.NodeLicense.find_one(
             Q('name', 'eq', 'No license')
         )
     )
     return super(NodeLicenseRecordFactory, cls)._create(*args, **kwargs)
 def test_on_reject(self, mock_send_mail):
     user = factories.UserFactory()
     approval = DraftRegistrationApproval(
         meta={'registration_choice': 'immediate'})
     approval.save()
     project = factories.ProjectFactory(creator=user)
     registration_schema = MetaSchema.find_one(
         Q('name', 'eq', 'Prereg Challenge') & Q('schema_version', 'eq', 2))
     draft = factories.DraftRegistrationFactory(
         branched_from=project,
         registration_schema=registration_schema,
     )
     draft.approval = approval
     draft.save()
     approval._on_reject(user)
     assert approval.meta == {}
     assert mock_send_mail.call_count == 1
    def test_remove(self):
        session, session2 = Session(data={'auth_user_id': '123ab'}), Session(data={'auth_user_id': 'ab123'})
        session.save()
        session2.save()

        assert Session.objects.count() == 2  # sanity check
        Session.remove(Q('data.auth_user_id', 'eq', '123ab'))
        assert Session.objects.count() == 1
Exemple #19
0
    def _on_reject(self, user, *args, **kwargs):
        DraftRegistration = apps.get_model('osf.DraftRegistration')

        # clear out previous registration options
        self.meta = {}
        self.save()

        draft = DraftRegistration.find_one(Q('approval', 'eq', self))
        self._send_rejection_email(draft.initiator, draft)
Exemple #20
0
def get_all_user_subscriptions(user, extra=None):
    """ Get all Subscription objects that the user is subscribed to"""
    NotificationSubscription = apps.get_model('osf.NotificationSubscription')
    for notification_type in constants.NOTIFICATION_TYPES:
        query = Q(notification_type, 'eq', user.pk)
        if extra:
            query &= extra
        queryset = NotificationSubscription.find(query)
        for subscription in queryset:
            yield subscription
Exemple #21
0
    def _set_external_account(self, user, info):
        try:
            # create a new ``ExternalAccount`` ...
            self.account = ExternalAccount(
                provider=self.short_name,
                provider_id=info['provider_id'],
                provider_name=self.name,
            )
            self.account.save()
        except ValidationError:
            # ... or get the old one
            self.account = ExternalAccount.find_one(
                Q('provider', 'eq', self.short_name) &
                Q('provider_id', 'eq', info['provider_id'])
            )
            assert self.account is not None

        # ensure that provider_name is correct
        self.account.provider_name = self.name
        # required
        self.account.oauth_key = info['key']

        # only for OAuth1
        self.account.oauth_secret = info.get('secret')

        # only for OAuth2
        self.account.expires_at = info.get('expires_at')
        self.account.refresh_token = info.get('refresh_token')
        self.account.date_last_refreshed = timezone.now()

        # additional information
        self.account.display_name = info.get('display_name')
        self.account.profile_url = info.get('profile_url')

        self.account.save()

        # add it to the user's list of ``ExternalAccounts``
        if not user.external_accounts.filter(id=self.account.id).exists():
            user.external_accounts.add(self.account)
            user.save()

        return True
Exemple #22
0
def remove_subscription_task(node_id):
    AbstractNode = apps.get_model('osf.AbstractNode')
    NotificationSubscription = apps.get_model('osf.NotificationSubscription')
    node = AbstractNode.load(node_id)
    NotificationSubscription.remove(Q('node', 'eq', node))
    parent = node.parent_node

    if parent and parent.child_node_subscriptions:
        for user_id in parent.child_node_subscriptions:
            if node._id in parent.child_node_subscriptions[user_id]:
                parent.child_node_subscriptions[user_id].remove(node._id)
        parent.save()
def migrate():
    targets = get_targets()
    total = len(targets)
    for i, user in enumerate(targets):
        logger.info('({}/{}) Preparing to migrate User {}'.format(i + 1, total, user._id))
        bookmarks = Collection.find(Q('is_bookmark_collection', 'eq', True) & Q('creator', 'eq', user))
        if sum([bool(n.nodes) for n in bookmarks]) > 1:
            logger.warn('Expected no users to have more than one bookmark with .nodes, {} violated. Selecting first one'.format(user._id))
        bookmark_to_keep = None
        for n in bookmarks:
            if n.nodes:
                bookmark_to_keep = n
                break
        bookmark_to_keep = bookmark_to_keep or bookmarks[0]
        logger.info('Marking Collection {} as primary Bookmark Collection for User {}, preparing to delete others'.format(bookmark_to_keep._id, user._id))
        for n in bookmarks:
            if n._id != bookmark_to_keep._id:
                n.is_deleted = True
                n.save()
        logger.info('Successfully migrated User {}'.format(user._id))
    logger.info('Successfully migrated {} users'.format(total))
Exemple #24
0
    def _rejection_url_context(self, user_id):
        user_approval_state = self.approval_state.get(user_id, {})
        rejection_token = user_approval_state.get('rejection_token')
        if rejection_token:
            Registration = apps.get_model('osf.Registration')

            root_registration = Registration.find_one(Q('retraction', 'eq', self))
            node_id = user_approval_state.get('node_id', root_registration._id)
            registration = Registration.load(node_id)
            return {
                'node_id': registration.registered_from._id,
                'token': rejection_token,
            }
Exemple #25
0
    def _on_reject(self, user):
        Registration = apps.get_model('osf.Registration')
        NodeLog = apps.get_model('osf.NodeLog')

        parent_registration = Registration.find_one(Q('retraction', 'eq', self))
        parent_registration.registered_from.add_log(
            action=NodeLog.RETRACTION_CANCELLED,
            params={
                'node': parent_registration.registered_from._id,
                'registration': parent_registration._id,
                'retraction_id': self._id,
            },
            auth=Auth(user),
            save=True,
        )
Exemple #26
0
    def test_factory(self):
        draft = factories.DraftRegistrationFactory()
        assert draft.branched_from is not None
        assert draft.initiator is not None
        assert draft.registration_schema is not None

        user = factories.UserFactory()
        draft = factories.DraftRegistrationFactory(initiator=user)
        assert draft.initiator == user

        node = factories.ProjectFactory()
        draft = factories.DraftRegistrationFactory(branched_from=node)
        assert draft.branched_from == node
        assert draft.initiator == node.creator

        # Pick an arbitrary v2 schema
        schema = MetaSchema.find(Q('schema_version', 'eq', 2))[0]
        data = {'some': 'data'}
        draft = factories.DraftRegistrationFactory(registration_schema=schema,
                                                   registration_metadata=data)
        assert draft.registration_schema == schema
        assert draft.registration_metadata == data
Exemple #27
0
 def find_child_by_name(self, name, kind=2):
     return self.resolve_class(
         self.provider,
         kind).find_one(Q('name', 'eq', name) & Q('parent', 'eq', self))
Exemple #28
0
 def files_checked_out(cls, user):
     """
     :param user: The user with checked out files
     :return: A queryset of all FileNodes checked out by user
     """
     return cls.find(Q('checkout', 'eq', user))
Exemple #29
0
    def test_querying_on_referent(self):
        user = UserFactory()

        guids = Guid.find(Q('referent', 'eq', user))
        assert user._id in guids.values_list('_id', flat=True)
Exemple #30
0
 def test_is_embargoed(self):
     embargo = factories.EmbargoFactory()
     registration = Registration.find_one(Q('embargo', 'eq', embargo))
     registration.embargo.state = Sanction.APPROVED
     registration.embargo.save()
     assert registration.is_embargoed