Example #1
0
File: user.py Project: cryos/girder
    def generateTemporaryPassword(self, params):
        self.requireParams('email', params)
        email = params['email'].lower().strip()

        users = self.model('user').find({'email': email})

        if not users.count():
            raise RestException('That email is not registered.')
        for user in users:
            token = self.model('token').createToken(
                None,
                days=1,
                scope=(TokenScope.USER_AUTH, TokenScope.TEMPORARY_USER_AUTH))
            token['userId'] = user['_id']
            self.model('token').save(token)
            base = cherrypy.request.base.rstrip('/')
            altbase = cherrypy.request.headers.get('X-Forwarded-Host', '')
            if altbase:
                base = '%s://%s' % (cherrypy.request.scheme, altbase)
            url = '%s/#useraccount/%s/token/%s' % (base, str(
                user['_id']), str(token['_id']))

            html = mail_utils.renderTemplate('temporaryAccess.mako', {
                'url': url,
                'token': str(token['_id'])
            })
            mail_utils.sendEmail(to=email,
                                 subject='Girder: Temporary Access',
                                 text=html)
        return {'message': 'Sent temporary access email.'}
Example #2
0
 def testBcc(self):
     bcc = ('*****@*****.**', '*****@*****.**')
     mail_utils.sendEmail(to='*****@*****.**', bcc=bcc, subject='hi', text='hi')
     self.assertTrue(base.mockSmtp.waitForMail())
     message = base.mockSmtp.getMail(parse=True)
     self.assertEqual(message['To'], '*****@*****.**')
     self.assertEqual(message['Bcc'], ', '.join(bcc))
Example #3
0
    def inviteToGroup(self, group, params):
        """Invite the user to join the group."""
        self.requireParams('userId', params)
        user = self.getCurrentUser()
        level = int(params.get('level', AccessType.READ))

        userToInvite = self.model('user').load(id=params['userId'],
                                               user=user,
                                               level=AccessType.READ,
                                               exc=True)

        # Can only invite into access levels that you yourself have
        self.model('group').requireAccess(group, user, level)
        self.model('group').inviteUser(group, userToInvite, level)

        if params.get('quiet', '').lower() != 'true':
            html = mail_utils.renderTemplate('groupInvite.mako', {
                'userToInvite': userToInvite,
                'user': user,
                'group': group
            })
            mail_utils.sendEmail(
                to=userToInvite['email'],
                text=html,
                subject="Girder: You've been invited to a group")

        return self.model('group').filter(group,
                                          user,
                                          accessList=True,
                                          requests=True)
Example #4
0
    def postScore(self, submission, params):
        # Ensure admin access on the containing challenge phase
        phase = self.model('phase',
                           'challenge').load(submission['phaseId'],
                                             user=self.getCurrentUser(),
                                             exc=True,
                                             level=AccessType.ADMIN)

        submission['score'] = json.loads(cherrypy.request.body.read())
        submission = self.model('submission', 'covalic').save(submission)

        # Delete the scirubg user's job token since the job is now complete.
        token = self.getCurrentToken()
        self.model('token').remove(token)

        user = self.model('user').load(submission['creatorId'], force=True)
        challenge = self.model('challenge',
                               'challenge').load(phase['challengeId'],
                                                 force=True)
        covalicHost = posixpath.dirname(mail_utils.getEmailUrlPrefix())
        html = mail_utils.renderTemplate(
            'covalic.submissionComplete.mako', {
                'phase': phase,
                'challenge': challenge,
                'submission': submission,
                'host': covalicHost
            })
        mail_utils.sendEmail(to=user['email'],
                             subject='Your submission has been scored',
                             text=html)

        return submission
Example #5
0
def testBcc(smtp):
    bcc = ('*****@*****.**', '*****@*****.**')
    mail_utils.sendEmail(to='*****@*****.**', bcc=bcc, subject='hi', text='hi')
    assert smtp.waitForMail()
    message = smtp.getMail(parse=True)
    assert message['To'] == '*****@*****.**'
    assert message['Bcc'] == ', '.join(bcc)
Example #6
0
    def postScore(self, submission, params):
        # Ensure admin access on the containing challenge phase
        phase = self.model('phase', 'challenge').load(
            submission['phaseId'], user=self.getCurrentUser(), exc=True,
            level=AccessType.ADMIN)

        submission['score'] = json.loads(cherrypy.request.body.read())
        submission = self.model('submission', 'covalic').save(submission)

        # Delete the scirubg user's job token since the job is now complete.
        token = self.getCurrentToken()
        self.model('token').remove(token)

        user = self.model('user').load(submission['creatorId'], force=True)
        challenge = self.model('challenge', 'challenge').load(
            phase['challengeId'], force=True)
        covalicHost = posixpath.dirname(mail_utils.getEmailUrlPrefix())
        html = mail_utils.renderTemplate('covalic.submissionComplete.mako', {
            'phase': phase,
            'challenge': challenge,
            'submission': submission,
            'host': covalicHost
        })
        mail_utils.sendEmail(
            to=user['email'], subject='Your submission has been scored',
            text=html)

        return submission
Example #7
0
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.sendEmail(to=user['email'],
                             subject='Authorized upload complete',
                             text=text)
        Token().remove(token)
Example #8
0
def testBcc(smtp):
    bcc = ('*****@*****.**', '*****@*****.**')
    mail_utils.sendEmail(to='*****@*****.**', bcc=bcc, subject='hi', text='hi')
    assert smtp.waitForMail()
    message = smtp.getMail(parse=True)
    assert message['To'] == '*****@*****.**'
    assert message['Bcc'] == ', '.join(bcc)
Example #9
0
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 'authorizedUploadId' in token:
        user = ModelImporter.model('user').load(token['userId'], force=True)
        item = ModelImporter.model('item').load(event.info['file']['itemId'], force=True)

        # Save the metadata on the item
        item['description'] = token['authorizedUploadDescription']
        item['authorizedUploadEmail'] = token['authorizedUploadEmail']
        ModelImporter.model('item').save(item)

        text = mail_utils.renderTemplate('authorized_upload.uploadFinished.mako', {
            'itemId': item['_id'],
            'itemName': item['name'],
            'itemDescription': item.get('description', '')
        })
        mail_utils.sendEmail(to=user['email'], subject='Authorized upload complete', text=text)
        ModelImporter.model('token').remove(token)
Example #10
0
    def inviteToGroup(self, group, params):
        """Invite the user to join the group."""
        self.requireParams(('userId',), params)
        user = self.getCurrentUser()
        level = int(params.get('level', AccessType.READ))

        userToInvite = self.model('user').load(
            id=params['userId'], user=user, level=AccessType.READ, exc=True)

        # Can only invite into access levels that you yourself have
        self.model('group').requireAccess(group, user, level)
        self.model('group').inviteUser(group, userToInvite, level)

        if params.get('quiet', '').lower() != 'true':
            html = mail_utils.renderTemplate('groupInvite.mako', {
                'userToInvite': userToInvite,
                'user': user,
                'group': group
            })
            mail_utils.sendEmail(
                to=userToInvite['email'], text=html,
                subject="Girder: You've been invited to a group")

        return self.model('group').filter(group, user, accessList=True,
                                          requests=True)
Example #11
0
    def generateTemporaryPassword(self, params):
        self.requireParams('email', params)
        email = params['email'].lower().strip()

        users = self.model('user').find({'email': email})

        if not users.count():
            raise RestException('That email is not registered.')
        for user in users:
            token = self.model('token').createToken(None, days=1, scope=(
                TokenScope.USER_AUTH, TokenScope.TEMPORARY_USER_AUTH))
            token['userId'] = user['_id']
            self.model('token').save(token)
            base = cherrypy.request.base.rstrip('/')
            altbase = cherrypy.request.headers.get('X-Forwarded-Host', '')
            if altbase:
                base = '%s://%s' % (cherrypy.request.scheme, altbase)
            url = '%s/#useraccount/%s/token/%s' % (
                base, str(user['_id']), str(token['_id']))

            html = mail_utils.renderTemplate('temporaryAccess.mako', {
                'url': url,
                'token': str(token['_id'])
            })
            mail_utils.sendEmail(to=email, subject='Girder: Temporary Access',
                                 text=html)
        return {'message': 'Sent temporary access email.'}
Example #12
0
 def _sendApprovedEmail(self, user):
     text = mail_utils.renderTemplate('accountApproved.mako', {
         'user': user,
         'url': mail_utils.getEmailUrlPrefix()
     })
     mail_utils.sendEmail(to=user.get('email'),
                          subject='Girder: Account approved',
                          text=text)
Example #13
0
 def _sendApprovedEmail(self, user):
     text = mail_utils.renderTemplate('accountApproved.mako', {
         'user': user,
         'url': mail_utils.getEmailUrlPrefix()
     })
     mail_utils.sendEmail(
         to=user.get('email'),
         subject='Girder: Account approved',
         text=text)
Example #14
0
 def _sendApprovalEmail(self, user):
     url = '%s#user/%s' % (mail_utils.getEmailUrlPrefix(), str(user['_id']))
     text = mail_utils.renderTemplate('accountApproval.mako', {
         'user': user,
         'url': url
     })
     mail_utils.sendEmail(toAdmins=True,
                          subject='Girder: Account pending approval',
                          text=text)
Example #15
0
 def testBcc(self):
     bcc = ('*****@*****.**', '*****@*****.**')
     mail_utils.sendEmail(to='*****@*****.**',
                          bcc=bcc,
                          subject='hi',
                          text='hi')
     self.assertTrue(base.mockSmtp.waitForMail())
     message = base.mockSmtp.getMail(parse=True)
     self.assertEqual(message['To'], '*****@*****.**')
     self.assertEqual(message['Bcc'], ', '.join(bcc))
Example #16
0
 def _sendApprovalEmail(self, user):
     url = '%s/#user/%s' % (
         mail_utils.getEmailUrlPrefix(), str(user['_id']))
     text = mail_utils.renderTemplate('accountApproval.mako', {
         'user': user,
         'url': url
     })
     mail_utils.sendEmail(
         toAdmins=True,
         subject='Girder: Account pending approval',
         text=text)
Example #17
0
 def _sendVerificationEmail(self, user):
     token = self.model('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.sendEmail(to=user.get('email'),
                          subject='Girder: Email verification',
                          text=text)
Example #18
0
 def _sendVerificationEmail(self, user):
     token = self.model('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.sendEmail(
         to=user.get('email'),
         subject='Girder: Email verification',
         text=text)
Example #19
0
    def postScore(self, submission, score, params):
        # Ensure admin access on the containing challenge phase
        phase = self.model('phase', 'covalic').load(
            submission['phaseId'], user=self.getCurrentUser(), exc=True,
            level=AccessType.ADMIN)

        # Record whether submission is being re-scored
        rescoring = 'overallScore' in submission

        # Save document to trigger computing overall score
        submission.pop('overallScore', None)
        submission['score'] = score
        submission = self.model('submission', 'covalic').save(submission)

        # Delete the scoring user's job token since the job is now complete.
        token = self.getCurrentToken()
        self.model('token').remove(token)

        user = self.model('user').load(submission['creatorId'], force=True)
        challenge = self.model('challenge', 'covalic').load(
            phase['challengeId'], force=True)
        covalicHost = posixpath.dirname(mail_utils.getEmailUrlPrefix())

        # Mail user
        if not rescoring:
            html = mail_utils.renderTemplate(
                'covalic.submissionCompleteUser.mako',
                {
                    'phase': phase,
                    'challenge': challenge,
                    'submission': submission,
                    'host': covalicHost
                })
            mail_utils.sendEmail(
                to=user['email'], subject='Your submission has been scored',
                text=html)

        # Mail admins
        emails = sorted(getPhaseUserEmails(
            phase, AccessType.WRITE, includeChallengeUsers=True))
        html = mail_utils.renderTemplate(
            'covalic.submissionCompleteAdmin.mako',
            {
                'user': user,
                'phase': phase,
                'challenge': challenge,
                'submission': submission,
                'host': covalicHost
            })
        mail_utils.sendEmail(
            to=emails, subject='A submission has been scored', text=html)

        return self._filterScore(phase, submission, user)
Example #20
0
    def inviteToGroup(self, group, params):
        """Invite the user to join the group."""
        self.requireParams('userId', params)
        user = self.getCurrentUser()
        level = int(params.get('level', AccessType.READ))
        force = self.boolParam('force', params, default=False)

        userToInvite = self.model('user').load(id=params['userId'],
                                               user=user,
                                               level=AccessType.READ,
                                               exc=True)

        if force:
            if not user.get('admin', False):
                mustBeAdmin = True
                addPolicy = self.model('setting').get(
                    SettingKey.ADD_TO_GROUP_POLICY)
                addGroup = group.get('addAllowed', 'default')
                if addGroup not in ['no', 'yesadmin', 'yesmod']:
                    addGroup = addPolicy
                if (self.model('group').hasAccess(group, user,
                                                  AccessType.ADMIN)
                        and ('mod' in addPolicy or 'admin' in addPolicy)
                        and addGroup.startswith('yes')):
                    mustBeAdmin = False
                elif (self.model('group').hasAccess(
                        group, user, AccessType.WRITE) and 'mod' in addPolicy
                      and addGroup == 'yesmod'):
                    mustBeAdmin = False
                if mustBeAdmin:
                    self.requireAdmin(user)
            self.model('group').addUser(group, userToInvite, level=level)
        else:
            # Can only invite into access levels that you yourself have
            self.model('group').requireAccess(group, user, level)
            self.model('group').inviteUser(group, userToInvite, level)

            if not self.boolParam('quiet', params, default=False):
                html = mail_utils.renderTemplate('groupInvite.mako', {
                    'userToInvite': userToInvite,
                    'user': user,
                    'group': group
                })
                mail_utils.sendEmail(
                    to=userToInvite['email'],
                    text=html,
                    subject="Girder: You've been invited to a group")

        return self.model('group').filter(group,
                                          user,
                                          accessList=True,
                                          requests=True)
Example #21
0
def send_created(event):
    dataset = event.info['dataset']
    print(dataset)
    user = event.info['user']

    html = mail_utils.renderTemplate('mdb.dataset_created.mako', {
        'dataset': dataset,
        'user': user
    })

    email_address = Setting().get(constants.NOTIFICATION_EMAIL)

    mail_utils.sendEmail(to=email_address, subject='Materials Data Bank: Dataset submitted.', text=html)
Example #22
0
    def resetPassword(self, email, params):
        user = self.model('user').findOne({'email': email.lower()})
        if user is None:
            raise RestException('That email is not registered.')

        randomPass = genToken(length=12)

        html = mail_utils.renderTemplate('resetPassword.mako', {
            'password': randomPass
        })
        mail_utils.sendEmail(to=email, subject='Girder: Password reset', text=html)
        self.model('user').setPassword(user, randomPass)
        return {'message': 'Sent password reset email.'}
Example #23
0
    def resetPassword(self, email):
        user = self.model('user').findOne({'email': email.lower()})
        if user is None:
            raise RestException('That email is not registered.')

        randomPass = genToken(length=12)

        html = mail_utils.renderTemplate('resetPassword.mako', {
            'password': randomPass
        })
        mail_utils.sendEmail(to=email, subject='Girder: Password reset', text=html)
        self.model('user').setPassword(user, randomPass)
        return {'message': 'Sent password reset email.'}
Example #24
0
def send_approved(event):
    dataset = event.info['dataset']
    approver = event.info['approver']
    user = User().load(dataset['userId'], force=True)
    html = mail_utils.renderTemplate('mdb.dataset_approved.mako', {
        'dataset': dataset,
        'user': user,
        'approver': approver
    })

    email_address = user['email']

    mail_utils.sendEmail(to=email_address, subject='Materials Data Bank: Dataset approved.', text=html)
Example #25
0
    def inviteToGroup(self, group, params):
        self.requireParams('userId', params)
        user = self.getCurrentUser()
        level = int(params.get('level', AccessType.READ))
        force = self.boolParam('force', params, default=False)
        groupModel = self.model('group')

        userToInvite = self.model('user').load(
            id=params['userId'], user=user, level=AccessType.READ, exc=True)

        if force:
            if not user.get('admin', False):
                mustBeAdmin = True
                addPolicy = self.model('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 self.boolParam('quiet', params, default=False):
                html = mail_utils.renderTemplate('groupInvite.mako', {
                    'userToInvite': userToInvite,
                    'user': user,
                    'group': group
                })
                mail_utils.sendEmail(
                    to=userToInvite['email'], text=html,
                    subject="Girder: You've been invited to a group")

        group['access'] = groupModel.getFullAccessList(group)
        group['requests'] = list(groupModel.getFullRequestList(group))
        return group
Example #26
0
    def _sendMail(self, folder, userId, subject, template):
        """
        Sends the specified email template to a single user.

        :param folder: the curated folder
        :param userId: the id of the user to email
        :param subject: the email subject
        :param template: the name of the mako template to use
        """
        if not userId:
            return
        data = dict(folder=folder, curation=folder[CURATION])
        text = mail_utils.renderTemplate(template, data)
        emails = [self._getEmail(userId)]
        mail_utils.sendEmail(emails, subject, text)
Example #27
0
def onJobUpdate(event):
    """
    Hook into job update event so we can look for job failure events and email
    administrators accordingly.
    """
    if (event.info['job']['type'] == 'covalic_score' and
            'status' in event.info['params'] and
            int(event.info['params']['status']) == JobStatus.ERROR):
        covalicHost = posixpath.dirname(mail_utils.getEmailUrlPrefix())
        html = mail_utils.renderTemplate('covalic.submissionError.mako', {
            'submissionId': event.info['job']['covalicSubmissionId'],
            'host': covalicHost
        })
        mail_utils.sendEmail(
            toAdmins=True, subject='Submission processing error', text=html)
Example #28
0
def inviteUser(self, params):
    Token = self.model('token')
    User = self.model('user', 'isic_archive')

    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 = '%s/#user/%s/rsvp/%s' % (
        mail_utils.getEmailUrlPrefix(), newUser['_id'], token['_id'])

    html = mail_utils.renderTemplate(
        'inviteUser.mako',
        {
            'newUser': newUser,
            'inviteUrl': inviteUrl,
        })
    mail_utils.sendEmail(
        to=newUser['email'],
        subject='ISIC Archive: Invitation',
        text=html)

    return {
        'newUser': User.filterSummary(newUser, currentUser),
        'inviteUrl': inviteUrl
    }
Example #29
0
def onJobUpdate(event):
    """
    Hook into job update event so we can look for job failure events and email
    administrators accordingly.
    """
    if (event.info['job']['type'] == 'covalic_score'
            and 'status' in event.info['params']
            and int(event.info['params']['status']) == JobStatus.ERROR):
        covalicHost = posixpath.dirname(mail_utils.getEmailUrlPrefix())
        html = mail_utils.renderTemplate(
            'covalic.submissionError.mako', {
                'submissionId': event.info['job']['covalicSubmissionId'],
                'host': covalicHost
            })
        mail_utils.sendEmail(toAdmins=True,
                             subject='Submission processing error',
                             text=html)
Example #30
0
def requestCreateDatasetPermission(self, params):
    User = self.model('user', 'isic_archive')
    Group = self.model('group')
    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('Could not load group: %s' % groupName)
        resp['message'] = 'Dataset Contributor access requested. An administrator may contact ' \
                          'you via email (at %s) to process your request.' % currentUser['email']

        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
            ]
            host = mail_utils.getEmailUrlPrefix()
            html = mail_utils.renderTemplate(
                'datasetContributorRequest.mako',
                {
                    'user': currentUser,
                    'group': group,
                    'host': host,
                })
            mail_utils.sendEmail(
                to=groupModeratorEmails,
                subject='ISIC Archive: Dataset Contributor Request',
                text=html)

    return resp
Example #31
0
    def _sendMail(self, folder, userId, subject, template):
        """
        Sends the specified email template to a single user.

        :param folder: the curated folder
        :param userId: the id of the user to email
        :param subject: the email subject
        :param template: the name of the mako template to use
        """
        if not userId:
            return
        data = dict(
            folder=folder,
            curation=folder[CURATION])
        text = mail_utils.renderTemplate(template, data)
        emails = [self._getEmail(userId)]
        mail_utils.sendEmail(emails, subject, text)
Example #32
0
    def generateTemporaryPassword(self, email):
        user = self.model('user').findOne({'email': email.lower()})

        if not user:
            raise RestException('That email is not registered.')

        token = self.model('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.sendEmail(to=email, subject='Girder: Temporary access', text=html)
        return {'message': 'Sent temporary access email.'}
Example #33
0
    def resetPassword(self, params):
        self.requireParams('email', params)
        email = params['email'].lower().strip()

        cursor = self.model('user').find({'email': email}, limit=1)
        if cursor.count() == 0:
            raise RestException('That email is not registered.')

        user = cursor.next()
        randomPass = genToken(length=12)

        html = mail_utils.renderTemplate('resetPassword.mako',
                                         {'password': randomPass})
        mail_utils.sendEmail(to=email,
                             subject='Girder: Password reset',
                             text=html)
        self.model('user').setPassword(user, randomPass)
        return {'message': 'Sent password reset email.'}
Example #34
0
    def resetPassword(self, params):
        self.requireParams(('email',), params)
        email = params['email'].lower().strip()

        cursor = self.model('user').find({'email': email}, limit=1)
        if cursor.count() == 0:
            raise RestException('That email is not registered.')

        user = cursor.next()
        randomPass = genToken(length=12)

        html = mail_utils.renderTemplate('resetPassword.mako', {
            'password': randomPass
        })
        mail_utils.sendEmail(to=email, subject='Girder: Password reset',
                             text=html)
        self.model('user').setPassword(user, randomPass)
        return {'message': 'Sent password reset email.'}
Example #35
0
    def generateTemporaryPassword(self, email, params):
        user = self.model('user').findOne({'email': email.lower()})

        if not user:
            raise RestException('That email is not registered.')

        token = self.model('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.sendEmail(to=email, subject='Girder: Temporary access', text=html)
        return {'message': 'Sent temporary access email.'}
Example #36
0
def sendEmailToGroup(groupName, templateFilename, templateParams, subject=None):
    """
    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.
    """
    Group = ModelImporter.model('group')

    group = Group.findOne({'name': groupName})
    if not group:
        raise Exception('Could not load group: %s.' % groupName)
    emails = [member['email'] for member in Group.listMembers(group)]
    if emails:
        html = mail_utils.renderTemplate(templateFilename, templateParams)
        mail_utils.sendEmail(to=emails, subject=subject, text=html)
Example #37
0
    def _ingestZip(self, dataset, zipFile, batch, user, sendMail):
        """
        Ingest images from a ZIP file into a dataset.

        The images are extracted to a "Pre-review" folder within the dataset folder.
        """
        prereviewFolder = Folder().createFolder(
            parent=self.imagesFolder(dataset),
            name='Pre-review',
            parentType='folder',
            creator=user,
            public=False,
            reuseExisting=True)

        # Process zip file
        # TODO: gracefully clean up after exceptions in handleZip
        self._handleZip(dataset, batch, prereviewFolder, user, zipFile)

        # Send email confirmations
        if sendMail:
            host = mail_utils.getEmailUrlPrefix()
            params = {
                'group': False,
                'host': host,
                'dataset': dataset,
                # We intentionally leak full user details here, even though all
                # email recipients may not have access permissions to the user
                'user': user,
                'batch': batch,
            }
            subject = 'ISIC Archive: Dataset Upload Confirmation'
            templateFilename = 'ingestDatasetConfirmation.mako'

            # Mail user
            html = mail_utils.renderTemplate(templateFilename, params)
            mail_utils.sendEmail(to=user['email'], subject=subject, text=html)

            # Mail 'Dataset QC Reviewers' group
            params['group'] = True
            isic_mail_utils.sendEmailToGroup(
                groupName='Dataset QC Reviewers',
                templateFilename=templateFilename,
                templateParams=params,
                subject=subject)
Example #38
0
    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.sendEmail(
                    to=userToInvite['email'], text=html,
                    subject="%s: You've been invited to a group"
                    % Setting().get(SettingKey.BRAND_NAME)
                )

        group['access'] = groupModel.getFullAccessList(group)
        group['requests'] = list(groupModel.getFullRequestList(group))
        return group
Example #39
0
    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.sendEmail(
                    to=userToInvite['email'], text=html,
                    subject="%s: You've been invited to a group"
                    % Setting().get(SettingKey.BRAND_NAME)
                )

        group['access'] = groupModel.getFullAccessList(group)
        group['requests'] = list(groupModel.getFullRequestList(group))
        return group
Example #40
0
def sendEmailToGroup(groupName,
                     templateFilename,
                     templateParams,
                     subject=None):
    """
    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.
    """
    group = Group().findOne({'name': groupName})
    if not group:
        raise Exception('Could not load group: %s.' % groupName)
    emails = [member['email'] for member in Group().listMembers(group)]
    if emails:
        html = mail_utils.renderTemplate(templateFilename, templateParams)
        mail_utils.sendEmail(to=emails, subject=subject, text=html)
Example #41
0
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('Could not load group: %s' % groupName)
        resp['message'] = 'Dataset Contributor access requested. An administrator may contact ' \
                          'you via email (at %s) to process your request.' % currentUser['email']

        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.sendEmail(
                    to=groupModeratorEmails,
                    subject='ISIC Archive: Dataset Contributor Request',
                    text=html)

    return resp
Example #42
0
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 = '%s/#user/%s/rsvp/%s' % (mail_utils.getEmailUrlPrefix(),
                                         newUser['_id'], token['_id'])

    html = mail_utils.renderTemplate('inviteUser.mako', {
        'newUser': newUser,
        'inviteUrl': inviteUrl,
    })
    mail_utils.sendEmail(to=newUser['email'],
                         subject='ISIC Archive: Invitation',
                         text=html)

    return {
        'newUser': User().filterSummary(newUser, currentUser),
        'inviteUrl': inviteUrl
    }
Example #43
0
    def testEmailAdmins(self):
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())

        admin1, admin2 = [
            self.model('user').createUser(firstName='Admin%d' % i,
                                          lastName='Admin',
                                          login='******' % i,
                                          password='******',
                                          admin=True,
                                          email='*****@*****.**' % i)
            for i in range(2)
        ]

        # Set the email from address
        self.model('setting').set(SettingKey.EMAIL_FROM_ADDRESS, '*****@*****.**')

        # Test sending email to admin users
        mail_utils.sendEmail(text='hello', toAdmins=True)
        self.assertTrue(base.mockSmtp.waitForMail())

        message = base.mockSmtp.getMail(parse=True)
        self.assertEqual(message['subject'], '[no subject]')
        self.assertEqual(message['content-type'], 'text/html; charset="utf-8"')
        self.assertEqual(message['to'], '[email protected], [email protected]')
        self.assertEqual(message['from'], '*****@*****.**')
        self.assertEqual(message.get_payload(decode=True), b'hello')

        # Test sending email to multiple recipients
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())
        mail_utils.sendEmail(to=('*****@*****.**', '*****@*****.**'),
                             text='world',
                             subject='Email alert')
        self.assertTrue(base.mockSmtp.waitForMail())

        message = base.mockSmtp.getMail(parse=True)
        self.assertEqual(message['subject'], 'Email alert')
        self.assertEqual(message['to'], '[email protected], [email protected]')
        self.assertEqual(message['from'], '*****@*****.**')
        self.assertEqual(message.get_payload(decode=True), b'world')

        # Pass nonsense in the "to" field, check exception
        x = 0
        try:
            mail_utils.sendEmail(text='hello', to=None)
        except Exception as e:
            x = 1
            self.assertEqual(
                e.args[0], 'You must specify email recipients via "to" or '
                '"bcc", or use toAdmins=True.')

        self.assertEqual(x, 1)
Example #44
0
    def testEmailAdmins(self):
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())

        admin1, admin2 = [
            self.model('user').createUser(firstName='Admin%d' % i,
                                          lastName='Admin',
                                          login='******' % i,
                                          password='******',
                                          admin=True,
                                          email='*****@*****.**' % i)
            for i in range(2)
        ]

        # Set the email from address
        self.model('setting').set(SettingKey.EMAIL_FROM_ADDRESS, '*****@*****.**')

        # Test sending email to admin users
        mail_utils.sendEmail(text='hello', toAdmins=True)
        self.assertTrue(base.mockSmtp.waitForMail())

        lines = base.mockSmtp.getMail().strip().splitlines()
        self.assertTrue('Subject: [no subject]' in lines)
        self.assertTrue('To: [email protected], [email protected]' in lines)
        self.assertTrue('From: [email protected]' in lines)
        self.assertEqual(lines[-1], 'hello')

        # Test sending email to multiple recipients
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())
        mail_utils.sendEmail(to=('*****@*****.**', '*****@*****.**'),
                             text='world',
                             subject='Email alert')
        self.assertTrue(base.mockSmtp.waitForMail())

        lines = base.mockSmtp.getMail().strip().splitlines()
        self.assertTrue('Subject: Email alert' in lines)
        self.assertTrue('To: [email protected], [email protected]' in lines)
        self.assertTrue('From: [email protected]' in lines)
        self.assertEqual(lines[-1], 'world')

        # Pass nonsense in the "to" field, check exception
        x = 0
        try:
            mail_utils.sendEmail(text='hello', to=None)
        except Exception as e:
            x = 1
            self.assertEqual(
                e.args[0], 'You must specify a "to" address or list of '
                'addresses or set toAdmins=True when calling sendEmail.')

        self.assertEqual(x, 1)
Example #45
0
    def testEmailAdmins(self):
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())

        admin1, admin2 = [self.model('user').createUser(
            firstName='Admin%d' % i, lastName='Admin', login='******' % i,
            password='******', admin=True, email='*****@*****.**' % i)
            for i in range(2)]

        # Set the email from address
        self.model('setting').set(SettingKey.EMAIL_FROM_ADDRESS, '*****@*****.**')

        # Test sending email to admin users
        mail_utils.sendEmail(text='hello', toAdmins=True)
        self.assertTrue(base.mockSmtp.waitForMail())

        message = base.mockSmtp.getMail(parse=True)
        self.assertEqual(message['subject'], '[no subject]')
        self.assertEqual(message['content-type'], 'text/html; charset="utf-8"')
        self.assertEqual(message['to'], '[email protected], [email protected]')
        self.assertEqual(message['from'], '*****@*****.**')
        self.assertEqual(message.get_payload(decode=True), b'hello')

        # Test sending email to multiple recipients
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())
        mail_utils.sendEmail(to=('*****@*****.**', '*****@*****.**'), text='world',
                             subject='Email alert')
        self.assertTrue(base.mockSmtp.waitForMail())

        message = base.mockSmtp.getMail(parse=True)
        self.assertEqual(message['subject'], 'Email alert')
        self.assertEqual(message['to'], '[email protected], [email protected]')
        self.assertEqual(message['from'], '*****@*****.**')
        self.assertEqual(message.get_payload(decode=True), b'world')

        # Pass nonsense in the "to" field, check exception
        x = 0
        try:
            mail_utils.sendEmail(text='hello', to=None)
        except Exception as e:
            x = 1
            self.assertEqual(
                e.args[0], 'You must specify email recipients via "to" or '
                '"bcc", or use toAdmins=True.')

        self.assertEqual(x, 1)
Example #46
0
    def testEmailAdmins(self):
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())

        admin1, admin2 = [self.model('user').createUser(
            firstName='Admin%d' % i, lastName='Admin', login='******' % i,
            password='******', admin=True, email='*****@*****.**' % i)
            for i in range(2)]

        # Set the email from address
        self.model('setting').set(SettingKey.EMAIL_FROM_ADDRESS, '*****@*****.**')

        # Test sending email to admin users
        mail_utils.sendEmail(text='hello', toAdmins=True)
        self.assertTrue(base.mockSmtp.waitForMail())

        lines = base.mockSmtp.getMail().strip().splitlines()
        self.assertTrue('Subject: [no subject]' in lines)
        self.assertTrue('To: [email protected], [email protected]' in lines)
        self.assertTrue('From: [email protected]' in lines)
        self.assertEqual(lines[-1], 'hello')

        # Test sending email to multiple recipients
        self.assertTrue(base.mockSmtp.isMailQueueEmpty())
        mail_utils.sendEmail(to=('*****@*****.**', '*****@*****.**'), text='world',
                             subject='Email alert')
        self.assertTrue(base.mockSmtp.waitForMail())

        lines = base.mockSmtp.getMail().strip().splitlines()
        self.assertTrue('Subject: Email alert' in lines)
        self.assertTrue('To: [email protected], [email protected]' in lines)
        self.assertTrue('From: [email protected]' in lines)
        self.assertEqual(lines[-1], 'world')

        # Pass nonsense in the "to" field, check exception
        x = 0
        try:
            mail_utils.sendEmail(text='hello', to=None)
        except Exception as e:
            x = 1
            self.assertEqual(
                e.message, 'You must specify a "to" address or list of '
                'addresses or set toAdmins=True when calling sendEmail.')

        self.assertEqual(x, 1)
Example #47
0
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.sendEmail(text='hello', toAdmins=True)
    assert smtp.waitForMail()

    message = smtp.getMail(parse=True)
    assert message['subject'] == '[no subject]'
    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.sendEmail(to=('*****@*****.**', '*****@*****.**'),
                         text='world',
                         subject='Email alert')
    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 nonsense in the "to" field, check exception
    msg = 'You must specify email recipients via "to" or "bcc", or use toAdmins=True.$'
    with pytest.raises(Exception, match=msg):
        mail_utils.sendEmail(text='hello', to=None)
Example #48
0
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.sendEmail(text='hello', toAdmins=True)
    assert smtp.waitForMail()

    message = smtp.getMail(parse=True)
    assert message['subject'] == '[no subject]'
    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.sendEmail(to=('*****@*****.**', '*****@*****.**'), text='world', subject='Email alert')
    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 nonsense in the "to" field, check exception
    msg = 'You must specify email recipients via "to" or "bcc", or use toAdmins=True.$'
    with pytest.raises(Exception, match=msg):
        mail_utils.sendEmail(text='hello', to=None)
Example #49
0
    def ingestDataset(self,
                      zipFile,
                      user,
                      name,
                      owner,
                      description,
                      license,
                      signature,
                      anonymous,
                      attribution,
                      sendMail=False):
        """
        Ingest an uploaded dataset from a .zip file of images. The images are
        extracted to a "Pre-review" folder within a new dataset folder.
        """
        # Create dataset folder
        dataset = self.createDataset(name, description, user)

        # Set dataset metadata, including license info
        dataset['meta'] = {
            'owner': owner,
            'signature': signature,
            'anonymous': anonymous,
            'attribution': attribution,
            'license': license,
            'metadataFiles': []
        }
        dataset = Dataset().save(dataset)

        prereviewFolder = Folder().createFolder(parent=dataset,
                                                name='Pre-review',
                                                parentType='folder',
                                                creator=user,
                                                public=False)
        prereviewFolder = Folder().copyAccessPolicies(dataset,
                                                      prereviewFolder,
                                                      save=True)

        # Process zip file
        # TODO: gracefully clean up after exceptions in handleZip
        self._handleZip(prereviewFolder, user, zipFile)

        # Send email confirmations
        if sendMail:
            host = mail_utils.getEmailUrlPrefix()
            params = {
                'group': False,
                'host': host,
                # We intentionally leak full user details here, even though all
                # email recipients may not have access permissions to the user
                'user': user,
                'name': name,
                'owner': owner,
                'description': description,
                'license': license,
                'signature': signature,
                'attribution': 'Anonymous' if anonymous else attribution
            }
            subject = 'ISIC Archive: Dataset Upload Confirmation'
            templateFilename = 'ingestDatasetConfirmation.mako'

            # Mail user
            html = mail_utils.renderTemplate(templateFilename, params)
            mail_utils.sendEmail(to=user['email'], subject=subject, text=html)

            # Mail 'Dataset QC Reviewers' group
            params['group'] = True
            isic_mail_utils.sendEmailToGroup(groupName='Dataset QC Reviewers',
                                             templateFilename=templateFilename,
                                             templateParams=params,
                                             subject=subject)

        return dataset
Example #50
0
 def testUnicodeEmail(self):
     text = u'Contains unic\xf8de \u0420\u043e\u0441\u0441\u0438\u044f'
     mail_utils.sendEmail(to='*****@*****.**', subject=text, text=text)
     self.assertTrue(base.mockSmtp.waitForMail())
     message = base.mockSmtp.getMail(parse=True)
     self.assertEqual(message.get_payload(decode=True), text.encode('utf8'))
Example #51
0
def onJobUpdate(event):
    """
    Hook into job update event so we can look for job failure events and email
    the user and challenge/phase administrators accordingly. Here, an
    administrator is defined to be a user with WRITE access or above.
    """
    isErrorStatus = False
    try:
        isErrorStatus = int(event.info['params'].get('status')) == JobStatus.ERROR
    except (ValueError, TypeError):
        pass

    if (event.info['job']['type'] == 'covalic_score' and isErrorStatus):
        covalicHost = posixpath.dirname(mail_utils.getEmailUrlPrefix())

        # Create minimal log that contains only Covalic errors.
        # Use full log if no Covalic-specific errors are found.
        # Fetch log from model, because log in event may not be up-to-date.
        job = Job().load(
            event.info['job']['_id'], includeLog=True, force=True)
        log = job.get('log')

        minimalLog = None
        if log:
            log = ''.join(log)
            minimalLog = '\n'.join([line[len(JOB_LOG_PREFIX):].strip()
                                    for line in log.splitlines()
                                    if line.startswith(JOB_LOG_PREFIX)])
        if not minimalLog:
            minimalLog = log

        submission = Submission().load(
            event.info['job']['covalicSubmissionId'])
        phase = Phase().load(
            submission['phaseId'], force=True)
        challenge = Challenge().load(
            phase['challengeId'], force=True)
        user = User().load(
            event.info['job']['userId'], force=True)

        rescoring = job.get('rescoring', False)

        # Mail admins, include full log
        emails = sorted(getPhaseUserEmails(
            phase, AccessType.WRITE, includeChallengeUsers=True))
        html = mail_utils.renderTemplate('covalic.submissionErrorAdmin.mako', {
            'submission': submission,
            'challenge': challenge,
            'phase': phase,
            'user': user,
            'host': covalicHost,
            'log': log
        })
        mail_utils.sendEmail(
            to=emails, subject='Submission processing error', text=html)

        # Mail user, include minimal log
        if not rescoring:
            html = mail_utils.renderTemplate('covalic.submissionErrorUser.mako', {
                'submission': submission,
                'challenge': challenge,
                'phase': phase,
                'host': covalicHost,
                'log': minimalLog
            })
            mail_utils.sendEmail(
                to=user['email'], subject='Submission processing error', text=html)
Example #52
0
def testUnicodeEmail(smtp):
    text = u'Contains unic\xf8de \u0420\u043e\u0441\u0441\u0438\u044f'
    mail_utils.sendEmail(to='*****@*****.**', subject=text, text=text)
    assert smtp.waitForMail()
    message = smtp.getMail(parse=True)
    assert message.get_payload(decode=True) == text.encode('utf8')
Example #53
0
def onJobUpdate(event):
    """
    Hook into job update event so we can look for job failure events and email
    the user and challenge/phase administrators accordingly. Here, an
    administrator is defined to be a user with WRITE access or above.
    """
    isErrorStatus = False
    try:
        isErrorStatus = int(
            event.info['params'].get('status')) == JobStatus.ERROR
    except (ValueError, TypeError):
        pass

    if (event.info['job']['type'] == 'covalic_score' and isErrorStatus):
        covalicHost = posixpath.dirname(mail_utils.getEmailUrlPrefix())

        # Create minimal log that contains only Covalic errors.
        # Use full log if no Covalic-specific errors are found.
        # Fetch log from model, because log in event may not be up-to-date.
        job = ModelImporter.model('job', 'jobs').load(event.info['job']['_id'],
                                                      includeLog=True,
                                                      force=True)
        log = job.get('log')

        minimalLog = None
        if log:
            log = ''.join(log)
            minimalLog = '\n'.join([
                line[len(JOB_LOG_PREFIX):].strip()
                for line in log.splitlines() if line.startswith(JOB_LOG_PREFIX)
            ])
        if not minimalLog:
            minimalLog = log

        submission = ModelImporter.model('submission', 'covalic').load(
            event.info['job']['covalicSubmissionId'])
        phase = ModelImporter.model('phase',
                                    'covalic').load(submission['phaseId'],
                                                    force=True)
        challenge = ModelImporter.model('challenge',
                                        'covalic').load(phase['challengeId'],
                                                        force=True)
        user = ModelImporter.model('user').load(event.info['job']['userId'],
                                                force=True)

        rescoring = job.get('rescoring', False)

        # Mail admins, include full log
        emails = sorted(
            getPhaseUserEmails(phase,
                               AccessType.WRITE,
                               includeChallengeUsers=True))
        html = mail_utils.renderTemplate(
            'covalic.submissionErrorAdmin.mako', {
                'submission': submission,
                'challenge': challenge,
                'phase': phase,
                'user': user,
                'host': covalicHost,
                'log': log
            })
        mail_utils.sendEmail(to=emails,
                             subject='Submission processing error',
                             text=html)

        # Mail user, include minimal log
        if not rescoring:
            html = mail_utils.renderTemplate(
                'covalic.submissionErrorUser.mako', {
                    'submission': submission,
                    'challenge': challenge,
                    'phase': phase,
                    'host': covalicHost,
                    'log': minimalLog
                })
            mail_utils.sendEmail(to=user['email'],
                                 subject='Submission processing error',
                                 text=html)
Example #54
0
 def testUnicodeEmail(self):
     text = u'Contains unic\xf8de \u0420\u043e\u0441\u0441\u0438\u044f'
     mail_utils.sendEmail(to='*****@*****.**', subject=text, text=text)
     self.assertTrue(base.mockSmtp.waitForMail())
     message = base.mockSmtp.getMail(parse=True)
     self.assertEqual(message.get_payload(decode=True), text.encode('utf8'))
Example #55
0
    def ingestDataset(self, zipFile, user, name, owner, description,
                      license, signature, anonymous, attribution,
                      sendMail=False):
        """
        Ingest an uploaded dataset from a .zip file of images. The images are
        extracted to a "Pre-review" folder within a new dataset folder.
        """
        Folder = self.model('folder')

        # Create dataset folder
        dataset = self.createDataset(name, description, user)

        # Set dataset metadata, including license info
        dataset = self.setMetadata(dataset, {
            'owner': owner,
            'signature': signature,
            'anonymous': anonymous,
            'attribution': attribution,
            'license': license,
            'metadataFiles': []
        })

        prereviewFolder = Folder.createFolder(
            parent=dataset,
            name='Pre-review',
            parentType='folder',
            creator=user,
            public=False)
        prereviewFolder = Folder.copyAccessPolicies(
            dataset, prereviewFolder, save=True)

        # Process zip file
        # TODO: gracefully clean up after exceptions in handleZip
        self._handleZip(prereviewFolder, user, zipFile)

        # Send email confirmations
        if sendMail:
            host = mail_utils.getEmailUrlPrefix()
            params = {
                'group': False,
                'host': host,
                # We intentionally leak full user details here, even though all
                # email recipients may not have access permissions to the user
                'user': user,
                'name': name,
                'owner': owner,
                'description': description,
                'license': license,
                'signature': signature,
                'attribution': 'Anonymous' if anonymous else attribution
            }
            subject = 'ISIC Archive: Dataset Upload Confirmation'
            templateFilename = 'ingestDatasetConfirmation.mako'

            # Mail user
            html = mail_utils.renderTemplate(templateFilename, params)
            mail_utils.sendEmail(to=user['email'], subject=subject, text=html)

            # Mail 'Dataset QC Reviewers' group
            params['group'] = True
            isic_mail_utils.sendEmailToGroup(
                groupName='Dataset QC Reviewers',
                templateFilename=templateFilename,
                templateParams=params,
                subject=subject)

        return dataset
Example #56
0
def testUnicodeEmail(smtp):
    text = u'Contains unic\xf8de \u0420\u043e\u0441\u0441\u0438\u044f'
    mail_utils.sendEmail(to='*****@*****.**', subject=text, text=text)
    assert smtp.waitForMail()
    message = smtp.getMail(parse=True)
    assert message.get_payload(decode=True) == text.encode('utf8')