def _sendApprovedEmail(self, user): text = mail_utils.renderTemplate('accountApproved.mako', { 'user': user, 'url': mail_utils.getEmailUrlPrefix() }) mail_utils.sendMail('Girder: Account approved', text, [user.get('email')])
def testBcc(smtp): bcc = ['*****@*****.**', '*****@*****.**'] mail_utils.sendMail('hi', 'hi', ['*****@*****.**'], bcc=bcc) assert smtp.waitForMail() message = smtp.getMail(parse=True) assert message['To'] == '*****@*****.**' assert message['Bcc'] == ', '.join(bcc)
def _uploadComplete(event): """ Called after an upload finishes. We check if our current token is a special authorized upload token, and if so, delete it. TODO we could alternatively keep a reference count inside each token that authorized more than a single upload at a time, and just decrement it here. """ token = getCurrentToken() if token and 'authorizedUploadId' in token: user = User().load(token['userId'], force=True) item = Item().load(event.info['file']['itemId'], force=True) # Save the metadata on the item item['description'] = token['authorizedUploadDescription'] item['authorizedUploadEmail'] = token['authorizedUploadEmail'] Item().save(item) text = mail_utils.renderTemplate( 'authorized_upload.uploadFinished.mako', { 'itemId': item['_id'], 'itemName': item['name'], 'itemDescription': item.get('description', '') }) mail_utils.sendMail('Authorized upload complete', text, [user['email']]) Token().remove(token)
def send_new_user_email(event): try: info = event.info email = info.get('email') brandName = Setting().get(SettingKey.BRAND_NAME) rendered = renderTemplate('welcome.mako') sendMail(f'Welcome to {brandName}', rendered, [email]) except Exception: logger.exception("Failed to send new user email")
def _sendVerificationEmail(self, user): from .token import Token token = Token().createToken(user, days=1, scope=TokenScope.EMAIL_VERIFICATION) url = '%s#useraccount/%s/verification/%s' % ( mail_utils.getEmailUrlPrefix(), str(user['_id']), str( token['_id'])) text = mail_utils.renderTemplate('emailVerification.mako', {'url': url}) mail_utils.sendMail('Girder: Email verification', text, [user.get('email')])
def requestCreateDatasetPermission(self, params): currentUser = self.getCurrentUser() resp = {} if User().canCreateDataset(currentUser): resp['message'] = 'Dataset Contributor access granted.', resp['extra'] = 'hasPermission' else: # Request that user join group groupName = 'Dataset Contributors' group = Group().findOne({'name': groupName}) if not group: raise RestException(f'Could not load group: {groupName}') resp['message'] = 'Dataset Contributor access requested. An administrator may contact ' \ f'you via email (at {currentUser["email"]}) to process your request.' for request in Group().getFullRequestList(group): if request['id'] == currentUser['_id']: # Request for this user is already pending break else: # No request for this user yet Group().joinGroup(group, currentUser) # Send email to group moderators and administrators groupAcl = Group().getFullAccessList(group) groupModeratorEmails = [ getUserEmail(user) for user in groupAcl['users'] if user['level'] >= AccessType.WRITE ] if groupModeratorEmails: host = mail_utils.getEmailUrlPrefix() html = mail_utils.renderTemplate( 'datasetContributorRequest.mako', { 'user': currentUser, 'group': group, 'host': host, }) mail_utils.sendMail( 'ISIC Archive: Dataset Contributor Request', html, groupModeratorEmails) return resp
def testEmailAdmins(smtp): assert smtp.isMailQueueEmpty() for i in range(2): # Create 2 admin users to test sending mail to admins User().createUser(firstName='Admin%d' % i, lastName='Admin', login='******' % i, password='******', admin=True, email='*****@*****.**' % i) # Set the email from address Setting().set(SettingKey.EMAIL_FROM_ADDRESS, '*****@*****.**') # Test sending email to admin users mail_utils.sendMailToAdmins('Notification', 'hello') assert smtp.waitForMail() message = smtp.getMail(parse=True) assert message['subject'] == 'Notification' assert message['content-type'] == 'text/html; charset="utf-8"' assert message['to'] == '[email protected], [email protected]' assert message['from'] == '*****@*****.**' assert message.get_payload(decode=True) == b'hello' # Test sending email to multiple recipients assert smtp.isMailQueueEmpty() mail_utils.sendMail('Email alert', 'world', to=['*****@*****.**', '*****@*****.**']) assert smtp.waitForMail() message = smtp.getMail(parse=True) assert message['subject'] == 'Email alert' assert message['to'] == '[email protected], [email protected]' assert message['from'] == '*****@*****.**' assert message.get_payload(decode=True) == b'world' # Pass empty list in the "to" field, check exception msg = 'You must specify email recipients via "to" or "bcc".$' with pytest.raises(Exception, match=msg): mail_utils.sendMail('alert', 'hello', to=[])
def generateTemporaryPassword(self, email): user = self._model.findOne({'email': email.lower()}) if not user: raise RestException('That email is not registered.') token = Token().createToken(user, days=1, scope=TokenScope.TEMPORARY_USER_AUTH) url = '%s#useraccount/%s/token/%s' % ( mail_utils.getEmailUrlPrefix(), str(user['_id']), str(token['_id'])) html = mail_utils.renderTemplate('temporaryAccess.mako', { 'url': url, 'token': str(token['_id']) }) mail_utils.sendMail( '%s: Temporary access' % Setting().get(SettingKey.BRAND_NAME), html, [email] ) return {'message': 'Sent temporary access email.'}
def sendEmailToGroup(groupName, templateFilename, templateParams, subject=None, asynchronous=True): """ Send a single email with all members of a group as the recipients. :param groupName: The name of the group. :param templateFilename: The name of the Make template file used to format the email. :param templateParams: The parameters with which to render the template. :param subject: The subject line of the email. :param asynchronous: If False, bypass Girder's event system. """ group = Group().findOne({'name': groupName}) if not group: raise Exception(f'Could not load group: {groupName}.') emails = [member['email'] for member in Group().listMembers(group)] if emails: html = mail_utils.renderTemplate(templateFilename, templateParams) if asynchronous: mail_utils.sendMail(subject, html, emails) else: mail_utils.sendMailSync(subject, html, emails)
def inviteToGroup(self, group, userToInvite, level, quiet, force): groupModel = self._model user = self.getCurrentUser() if force: if not user['admin']: mustBeAdmin = True addPolicy = Setting().get(SettingKey.ADD_TO_GROUP_POLICY) addGroup = group.get('addAllowed', 'default') if addGroup not in ['no', 'yesadmin', 'yesmod']: addGroup = addPolicy if (groupModel.hasAccess(group, user, AccessType.ADMIN) and ('mod' in addPolicy or 'admin' in addPolicy) and addGroup.startswith('yes')): mustBeAdmin = False elif (groupModel.hasAccess(group, user, AccessType.WRITE) and 'mod' in addPolicy and addGroup == 'yesmod'): mustBeAdmin = False if mustBeAdmin: self.requireAdmin(user) groupModel.addUser(group, userToInvite, level=level) else: # Can only invite into access levels that you yourself have groupModel.requireAccess(group, user, level) groupModel.inviteUser(group, userToInvite, level) if not quiet: html = mail_utils.renderTemplate('groupInvite.mako', { 'userToInvite': userToInvite, 'user': user, 'group': group }) mail_utils.sendMail( "%s: You've been invited to a group" % Setting().get(SettingKey.BRAND_NAME), html, [userToInvite['email']]) group['access'] = groupModel.getFullAccessList(group) group['requests'] = list(groupModel.getFullRequestList(group)) return group
def deleteExpired(self): cursor = Folder().find({'isPhotomorph': True}) now = datetime.datetime.utcnow() emailExp = datetime.timedelta(days=DAYS_UNTIL_EMAIL) dataExp = datetime.timedelta(days=DAYS_UNTIL_DELETION) for folder in cursor: setResponseTimeLimit() if folder['created'] + dataExp < now: logger.info('Delete timelapse %s (uid=%s)' % (folder['name'], folder['creatorId'])) Folder().remove(folder) elif not folder.get('timelapseEmailSent' ) and folder['created'] + emailExp < now: try: user = User().load(folder['creatorId'], force=True, exc=True) text = renderTemplate( 'timelapse.deletePending.mako', params={ 'folder': folder, 'days': DAYS_UNTIL_DELETION, 'url': getEmailUrlPrefix() + '#timelapse', 'deletionDate': (folder['created'] + dataExp).strftime(DATE_FMT) }) sendMail(DELETE_SUBJECT, text, [user['email']]) Folder().update({'_id': folder['_id']}, {'$set': { 'timelapseEmailSent': True }}, multi=False) except Exception: logger.exception('Error sending email for folder: %s' % folder['_id'])
def inviteUser(self, params): params = self._decodeParams(params) self.requireParams(['login', 'email', 'firstName', 'lastName'], params) if 'validityPeriod' in params: try: validityPeriod = float(params['validityPeriod']) except ValueError: raise ValidationException('Validity period must be a number.', 'validityPeriod') else: validityPeriod = 60.0 currentUser = self.getCurrentUser() User().requireAdminStudy(currentUser) newUser = User().createUser(login=params['login'], password=None, email=params['email'], firstName=params['firstName'], lastName=params['lastName']) token = Token().createToken(newUser, days=validityPeriod, scope=[TokenScope.TEMPORARY_USER_AUTH]) inviteUrl = f'{mail_utils.getEmailUrlPrefix()}/#user/{newUser["_id"]}/rsvp/{token["_id"]}' html = mail_utils.renderTemplate('inviteUser.mako', { 'newUser': newUser, 'inviteUrl': inviteUrl, }) mail_utils.sendMail('ISIC Archive: Invitation', html, [newUser['email']]) return { 'newUser': User().filterSummary(newUser, currentUser), 'inviteUrl': inviteUrl }
def testUnicodeEmail(smtp): text = u'Contains unic\xf8de \u0420\u043e\u0441\u0441\u0438\u044f' mail_utils.sendMail(text, text, ['*****@*****.**']) assert smtp.waitForMail() message = smtp.getMail(parse=True) assert message.get_payload(decode=True) == text.encode('utf8')