Beispiel #1
0
    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)
Beispiel #2
0
    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)
        })
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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