def post(self): """Create a new account""" self.reqparse.add_argument('accountName', type=str, required=True) self.reqparse.add_argument('accountNumber', type=str, required=True) self.reqparse.add_argument('contacts', type=str, required=True, action='append') self.reqparse.add_argument('enabled', type=int, required=True, choices=(0, 1)) self.reqparse.add_argument('requiredGroups', type=str, action='append', default=()) self.reqparse.add_argument('adGroupBase', type=str, default=None) args = self.reqparse.parse_args() AuditLog.log('account.create', session['user'].username, args) for contact in args['contacts']: if not contact.startswith('#') and (contact.find('@') >= 0 and not validate_email(contact)): raise Exception( 'Invalid email address or slack channel name supplied: {}'. format(contact)) for key in ('accountName', 'accountNumber', 'contacts', 'enabled'): value = args[key] if type(value) == str: value = value.strip() if type(value) in (int, tuple, list, str): if not value: raise Exception('{} cannot be empty'.format( key.replace('_', ' ').title())) else: raise ValueError( 'Invalid type: {} for value {} for argument {}'.format( type(value), value, key)) if Account.query.filter_by( account_name=args['accountName']).count() > 0: raise Exception('Account already exists') acct = Account(args['accountName'], args['accountNumber'].zfill(12), args['contacts'], args['enabled'], args['adGroupBase']) acct.required_groups = json.dumps(args['requiredGroups']) db.session.add(acct) db.session.commit() # Add the newly created account to the session so we can see it right away session['accounts'].append(acct.account_id) return self.make_response( { 'message': 'Account created', 'accountId': acct.account_id }, HTTP.CREATED)
def put(self, accountId): """Update an account""" self.reqparse.add_argument('accountName', type=str, required=True) self.reqparse.add_argument('accountNumber', type=str, required=True) self.reqparse.add_argument('contacts', type=str, required=True, action='append') self.reqparse.add_argument('enabled', type=int, required=True, choices=(0, 1)) self.reqparse.add_argument('requiredRoles', type=str, action='append', default=()) self.reqparse.add_argument('adGroupBase', type=str, default=None) args = self.reqparse.parse_args() AuditLog.log('account.update', session['user'].username, args) for contact in args['contacts']: if not contact.startswith('#') and not validate_email(contact): raise Exception( 'Invalid email address or slack channel name supplied: {}'. format(contact)) if not args['accountName'].strip(): raise Exception('You must provide an account name') if not args['contacts']: raise Exception('You must provide at least one contact') acct = Account.query.filter_by(account_id=accountId).first() acct.account_name = args['accountName'] acct.account_number = args['accountNumber'].zfill(12) acct.contacts = args['contacts'] acct.enabled = args['enabled'] acct.required_roles = args['requiredRoles'] acct.ad_group_base = args['adGroupBase'] db.session.add(acct) db.session.commit() return self.make_response({ 'message': 'Object updated', 'account': acct.to_json(is_admin=True) })
def validate_tag(self, key, value): """Check whether a tag value is valid Args: key: A tag key value: A tag value Returns: `(True or False)` A boolean indicating whether or not the value is valid """ if key == 'owner': return validate_email(value, self.partial_owner_match) elif key == self.gdpr_tag: return value in self.gdpr_tag_values else: return True
def check_required_tags_compliance(self, resource): """Check whether a resource is compliance Args: resource: A single resource Returns: `(list, list)` A tuple contains missing tags (if there were any) and notes """ missing_tags = [] notes = [] resource_tags = {tag.key.lower(): tag.value for tag in resource.tags} # Do not audit this resource if it is not in the Account scope if resource.resource_type in self.alert_schedule: target_accounts = self.alert_schedule[ resource.resource_type]['scope'] else: target_accounts = self.alert_schedule['*']['scope'] if not (resource.account.account_name in target_accounts or '*' in target_accounts): return missing_tags, notes # Do not audit this resource if the ignore tag was set if self.audit_ignore_tag.lower() in resource_tags: return missing_tags, notes ''' # Do not audit this resource if it is still in grace period if (datetime.utcnow() - resource.resource_creation_date).total_seconds() // 3600 < self.grace_period: return missing_tags, notes ''' # Check if the resource is missing required tags for key in [tag.lower() for tag in self.required_tags]: if key not in resource_tags: missing_tags.append(key) elif key == 'owner' and not validate_email( resource_tags[key], self.partial_owner_match): missing_tags.append(key) notes.append('Owner tag is not a valid email address') return missing_tags, notes
def validate_tag(self, key, value): """Check whether a tag value is valid Args: key: A tag key value: A tag value Returns: `(True or False)` A boolean indicating whether or not the value is valid """ if key == 'owner': return validate_email(value, self.partial_owner_match) elif key == 'gdpr_compliance': return value in GDPR_COMPLIANCE_TAG_VALUES elif key == 'max-age' or key == 'data_retention': return value in MAX_AGE_TAG_VALUES else: return True