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))
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
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()
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
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, }
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)
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)
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
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, }
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
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, )
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)
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)