Exemple #1
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 #2
0
    def confirm_email(self, token, merge=False):
        """Confirm the email address associated with the token"""
        email = self.get_unconfirmed_email_for_token(token)

        # If this email is confirmed on another account, abort
        try:
            user_to_merge = OSFUser.find_one(Q('emails', 'contains', [email]))
        except NoResultsFound:
            user_to_merge = None

        # TODO: Implement merging
        if user_to_merge and merge:
            self.merge_user(user_to_merge)
        elif user_to_merge:
            raise MergeConfirmedRequiredError(
                'Merge requires confirmation',
                user=self,
                user_to_merge=user_to_merge,
            )

        # If another user has this email as its username, get it
        try:
            unregistered_user = OSFUser.find_one(
                Q('username', 'eq', email) & Q('_id', 'ne', self._id))
        except NoResultsFound:
            unregistered_user = None

        if unregistered_user:
            self.merge_user(unregistered_user)
            self.save()
            unregistered_user.username = None

        if email not in self.emails:
            self.emails.append(email)

        # Complete registration if primary email
        if email.lower() == self.username.lower():
            self.register(self.username)
            self.date_confirmed = timezone.now()
        # Revoke token
        del self.email_verifications[token]

        # TODO: We can't assume that all unclaimed records are now claimed.
        # Clear unclaimed records, so user's name shows up correctly on
        # all projects
        self.unclaimed_records = {}
        self.save()

        self.update_search_nodes()

        return True
Exemple #3
0
    def _on_complete(self, user):
        Registration = apps.get_model('osf_models.Registration')
        NodeLog = apps.get_model('osf_models.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 #4
0
    def unconfirmed_email_info(self):
        """Return a list of dictionaries containing information about each of this
        user's unconfirmed emails.
        """
        unconfirmed_emails = []
        email_verifications = self.email_verifications or []
        for token in email_verifications:
            if self.email_verifications[token].get('confirmed', False):
                try:
                    user_merge = OSFUser.find_one(
                        Q('emails', 'contains',
                          [self.email_verifications[token]['email'].lower()]))
                except NoResultsFound:
                    user_merge = False

                unconfirmed_emails.append({
                    'address':
                    self.email_verifications[token]['email'],
                    'token':
                    token,
                    'confirmed':
                    self.email_verifications[token]['confirmed'],
                    'user_merge':
                    user_merge.email if user_merge else False
                })
        return unconfirmed_emails
Exemple #5
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_models.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 #6
0
    def _on_reject(self, user, *args, **kwargs):
        from website.project.model import 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 #7
0
 def find(cls, query, *args, **kwargs):
     # Make referent queryable
     # NOTE: This won't work with compound queries
     if hasattr(query, 'attribute') and query.attribute == 'referent':
         # We rely on the fact that the related_name for BaseIDMixin.guid
         # is 'referent_<lowercased class name>'
         class_name = query.argument.__class__.__name__.lower()
         return super(Guid, cls).find(
             Q('referent_{}'.format(class_name), query.op, query.argument))
     else:
         return super(Guid, cls).find(query, *args, **kwargs)
Exemple #8
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 KeyExistsException:
            # ... 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')

        # 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 self.account not in user.external_accounts:
            user.external_accounts.append(self.account)
            user.save()

        return True
Exemple #9
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_models.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 #10
0
 def update_affiliated_institutions_by_email_domain(self):
     """
     Append affiliated_institutions by email domain.
     :return:
     """
     try:
         email_domains = [
             email.split('@')[1].lower() for email in self.emails
         ]
         insts = Institution.find(
             Q('email_domains', 'overlap', email_domains))
         affiliated = self.affiliated_institutions.all()
         self.affiliated_institutions.add(
             *[each for each in insts if each not in affiliated])
     except (IndexError, NoResultsFound):
         pass
Exemple #11
0
    def _on_reject(self, user):
        Registration = apps.get_model('osf_models.Registration')
        NodeLog = apps.get_model('osf_models.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 #12
0
    def _on_complete(self, user):
        from website.project.model import 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':
            sanction = functools.partial(
                registration.embargo_registration, draft.initiator,
                parse_date(self.meta.get('embargo_end_date'), ignoretz=True))
        else:
            raise ValueError(
                "'registration_choice' must be either 'embargo' or 'immediate'"
            )
        sanction(notify_initiator_on_complete=True)
Exemple #13
0
    def get_or_create_cookie(self, secret=None):
        """Find the cookie for the given user
        Create a new session if no cookie is found

        :param str secret: The key to sign the cookie with
        :returns: The signed cookie
        """
        secret = secret or settings.SECRET_KEY
        sessions = Session.find(Q('data.auth_user_id', 'eq',
                                  self._id)).sort('-date_modified').limit(1)

        if sessions.exists():
            user_session = sessions[0]
        else:
            user_session = Session(
                data={
                    'auth_user_id': self._id,
                    'auth_user_username': self.username,
                    'auth_user_fullname': self.fullname,
                })
            user_session.save()

        signer = itsdangerous.Signer(secret)
        return signer.sign(user_session._id)