def SetRoles(cls, email_addr, new_roles): user = User.GetOrInsert(email_addr) old_roles = set(user.roles) new_roles = set(new_roles) all_roles = constants.USER_ROLE.SET_ALL # Removing all roles would put this user into a bad state, so don't. if not new_roles: msg = 'Cannot remove remaining role(s) %s from user %s' % (sorted( list(old_roles)), user.nickname) logging.error(msg) raise NoRolesError(msg) # Verify that all the roles provided are valid. invalid_roles = new_roles - all_roles if invalid_roles: raise InvalidUserRoleError(', '.join(invalid_roles)) # If no role changes are necessary, bail. if old_roles == new_roles: logging.info('No roles changes necessary for %s', user.nickname) return # Log the roles changes. roles_removed = old_roles - new_roles for role in roles_removed: logging.info('Removing the %s role from %s', role, user.nickname) roles_added = new_roles - old_roles for role in roles_added: logging.info('Adding the %s role to %s', role, user.nickname) # Recalculate the voting weight. voting_weights = settings.VOTING_WEIGHTS new_vote_weight = max(voting_weights[role] for role in new_roles) if user.vote_weight != new_vote_weight: logging.info('Vote weight changing from %d to %d for %s', user.vote_weight, new_vote_weight, user.nickname) new_roles = sorted(list(new_roles)) user.roles = new_roles user.vote_weight = new_vote_weight user.put() # Notify the user of the change. roles_added_str = ', '.join(sorted(roles_added)) roles_removed_str = ', '.join(sorted(roles_removed)) body = template_utils.RenderEmailTemplate( 'user_role_change.html', roles_added=roles_added_str, roles_removed=roles_removed_str) subject = 'Your user roles have changed' mail_utils.Send(subject, body, to=[user.email], html=True) # Note the role change in BigQuery. tables.USER.InsertRow(email=user.email, timestamp=datetime.datetime.utcnow(), action=constants.USER_ACTION.ROLE_CHANGE, roles=new_roles)
def ChangeTransitiveWhitelisting(host_id, enable): """Changes the transitive whitelisting state for a SantaHost. Args: host_id: The ID of the SantaHost. enable: Whether to enable or disable transitive whitelisting. Raises: UnsupportedClientError: if called against anything other than a SantaHost. """ # Only Santa clients are supported. host = host_models.Host.get_by_id(host_models.Host.NormalizeId(host_id)) if host.GetClientName() != constants.CLIENT.SANTA: raise UnsupportedClientError( 'Only Santa clients support transitive whitelisting') # If this is a no-op, just bail now. if host.transitive_whitelisting_enabled == enable: logging.warning('Transitive whitelisting is already %s for %s', 'enabled' if enable else 'disabled', host.hostname) return # Make the change. host.transitive_whitelisting_enabled = enable host.put() modification = 'enabled' if enable else 'disabled' logging.info('Transitive whitelisting %s for %s', modification, host.hostname) # If enabling transitive whitelisting and the SantaHost has an APPROVED # Exemption, cancel it. exm_key = exemption_models.Exemption.CreateKey(host_id) exm = exm_key.get() if enable and exm and exm.state == constants.EXEMPTION_STATE.APPROVED: Cancel(exm_key) # Notify the user of the mode change. body = template_utils.RenderEmailTemplate( 'transitive_modified.html', modification=modification, device_hostname=host.hostname, upvote_hostname=env_utils.ENV.HOSTNAME) subject = 'Developer mode changed: %s' % host.hostname mail_utils.Send(subject, body, to=[host.primary_user], html=True) # Note the state change in BigQuery. comment = 'Transitive whitelisting %s' % modification tables.HOST.InsertRow(device_id=host_id, timestamp=datetime.datetime.utcnow(), action=constants.HOST_ACTION.COMMENT, hostname=host.hostname, platform=constants.PLATFORM.MACOS, users=[host.primary_user], mode=host.client_mode, comment=comment)
def SendExpirationEmail(exm_key): """Sends an email regarding an Exemption that is about to expire. Args: exm_key: The Key of the Exemption. Raises: UnsupportedPlatformError: if the platform of the corresponding Host is unsupported. """ # Compose the body. deactivation_dt = exm_key.get().deactivation_dt expiration_str = deactivation_dt.strftime('%B %d, %Y at %I:%M%p (UTC)') hostname = exm_key.parent().get().hostname body = template_utils.RenderEmailTemplate( 'exemption_will_expire.html', expiration_str=expiration_str, device_hostname=hostname, upvote_hostname=settings.ENV.HOSTNAME) _SendEmail(exm_key, body)
def SendUpdateEmail(exm_key, new_state, details=None): """Sends an email when an Exemption is updated. Args: exm_key: The Key of the Exemption. new_state: The new state the Exemption is transitioning to. details: Optional list of detail strings explaining the transition. Raises: UnsupportedPlatformError: if the platform of the corresponding Host is unsupported. """ # Compose the body. template_name = _EMAIL_TEMPLATE_MAP[new_state] hostname = exm_key.parent().get().hostname body = template_utils.RenderEmailTemplate( template_name, details=details, device_hostname=hostname, upvote_hostname=settings.ENV.HOSTNAME) _SendEmail(exm_key, body)
def testSuccess(self): content = template_utils.RenderEmailTemplate('exemption_expired.html', device_hostname='aaa', upvote_hostname='bbb') self.assertIsInstance(content, unicode)
def testInvalidTemplate(self): with self.assertRaises(jinja2.TemplateNotFound): template_utils.RenderEmailTemplate('no_bueno.html')