def acs(): logger.info("Processing SAML 'acs' Response") db = DivvyCloudGatewayORM() saml_req = prepare_flask_request(request) auth = init_saml_auth(saml_req) errors = [] not_auth_warn = False configured = True auth.process_response() errors = auth.get_errors() not_auth_warn = not auth.is_authenticated() if errors: logger.error("SAML Response Errors: %s", errors) return render_template( 'index.html', errors=errors, configured=configured, domain=request.url_root, not_auth_warn=not_auth_warn ) else: username = auth.get_nameid() logger.debug( "Attempting Authentication for NameID: %s", auth.get_nameid ) try: session_data = db.LoginUser(username) logger.info("SAML: Found user with NameID") user_resource_id = ResourceIds.DivvyUser(user_id=session_data['user'].user_id) session_permissions = SessionPermissions.load_for_user(user_resource_id=user_resource_id) divvysession = create_session(session_permissions=session_permissions, **session_data) # After Success redirect to Console App response = redirect( auth.redirect_to( redirect_url( request_protocol(request), request.host ) ) ) response.set_cookie('session_id', divvysession.session_id) return response except NoResultFound: logger.error("SAML: No User found with NameID. Create new user with SSO id as username.") errors.append("SAML: No User found with NameID. Create new user with SSO id as username.") return render_template( 'index.html', errors=errors, configured=configured, domain=request.url_root, not_auth_warn=not_auth_warn )
def publish_to_sqs_queue(bot, settings, matches, _non_matches): # Get a mapping of topic ARNs to organization service IDs db = DivvyCloudGatewayORM() org_svc_mapping = dict( db.session.query(DivvyDbObjects.MessageQueue.arn, DivvyDbObjects.MessageQueue.organization_service_id)) queue = db.session.query( DivvyDbObjects.MessageQueue.url, DivvyDbObjects.MessageQueue.organization_service_id).filter( DivvyDbObjects.MessageQueue.arn == settings['message_queue_arn']).first() if not queue: raise ValueError( 'Unable to identify this message queue within DivvyCloud') message_queue_arn = settings['message_queue_arn'] region = message_queue_arn.split(':')[3] org_svc_id = org_svc_mapping.get(message_queue_arn) if not org_svc_id: raise ValueError('Unable to identify organization service ID') frontend = get_cloud_type_by_organization_service_id(org_svc_id) backend = frontend.get_cloud_gw(region_name=region) client = backend.client('sqs') with ScheduledEventTracker() as context: for resource in matches: event = BotEvent('hookpoint', resource, bot.bot_id, bot.name) message = jinja2.Template(settings.get('message', '')) client.send_message(QueueUrl=queue.url, MessageBody=message.render(event=event, resource=resource))
def xray_encryption_configuration_type(query, db_cls, settings_config): db = DivvyCloudGatewayORM() return query.filter(db_cls.resource_id.in_( db.session.query( DivvyDbObjects.ResourceProperty.resource_id ).filter( DivvyDbObjects.ResourceProperty.name == 'custom.xray_encryption_config_type' ).filter( DivvyDbObjects.ResourceProperty.value == settings_config['type'] )))
def run(self): """ Job implementations must implement this method to perform their work """ with NewSession(DivvyCloudGatewayORM): db = DivvyCloudGatewayORM() org_services = db.session.query( DivvyDbObjects.OrganizationService.organization_service_id, DivvyDbObjects.OrganizationService.name ).filter( DivvyDbObjects.OrganizationService.cloud_type_id == 'AWS' ).filter( DivvyDbObjects.OrganizationService.status.notin_([ DivvyDbObjects.OrganizationService.Status.DELETE, DivvyDbObjects.OrganizationService.Status.PAUSED, DivvyDbObjects.OrganizationService.Status.INVALID_CREDS, DivvyDbObjects.OrganizationService.Status.ASSUME_ROLE_FAIL ])) for org_service in org_services: logger.info('Harvesting X-Ray encryption configuration for %s', org_service.name) frontend = get_cloud_type_by_organization_service_id( org_service.organization_service_id) for region in frontend.get_compute_regions(): backend = frontend.get_cloud_gw(region_name=region) client = boto3.client( 'xray', aws_access_key_id=backend.auth_api_key, aws_secret_access_key=backend.auth_secret, aws_session_token=backend.session_token, region_name=region) encryption_type = client.get_encryption_config( )['EncryptionConfig']['Type'] resource_id = ResourceIds.ServiceRegion( organization_service_id=org_service. organization_service_id, region=region) db.session.merge( DivvyDbObjects.ResourceProperty( resource_id=resource_id, name='custom.xray_encryption_config_type', value=encryption_type, type_hint='string')) db.session.commit()
def do_harvest(self): with NewSession(DivvyCloudGatewayORM): db = DivvyCloudGatewayORM() if ORGANIZATION_SERVICE_ID and S3_BUCKET_NAME and FILE_KEY: for region_name, image_ids in self.image_getter_auth().items(): for image_id in image_ids: db.session.merge( dbobjects.ValidImage(region_name=region_name, image_id=image_id)) else: for region_name, image_ids in self.image_getter_unauth().items( ): for image_id in image_ids: db.session.merge( dbobjects.ValidImage(region_name=region_name, image_id=image_id))
def run(self): start_time = datetime.utcnow() # Get a mapping of topic ARNs to organization service IDs db = DivvyCloudGatewayORM() org_svc_mapping = dict( db.session.query( DivvyDbObjects.NotificationTopic.arn, DivvyDbObjects.NotificationTopic.organization_service_id ) ) org_svc_id = org_svc_mapping.get(self.cloud_topic) if not org_svc_id: raise ValueError('Unable to identify organization service ID') region = self.cloud_topic.split(':')[3] frontend = get_cloud_type_by_organization_service_id(org_svc_id) backend = frontend.get_cloud_gw(region_name=region) client = backend.client('sns') try: params = { 'TopicArn': self.cloud_topic, 'Message': self.message } if self.message_attributes: params['MessageAttributes'] = json.loads(str(self.message_attributes)) if self.subject: params['Subject'] = self.subject client.publish(**params) status = 'SUCCESS' result_data = None except Exception: status = 'ERROR' result_data = traceback.format_exc() self.store_event_history( start_time=start_time, finish_time=datetime.utcnow(), status=status, result_data=result_data )
def publish_to_cloudwatch_logs(bot, settings, matches, _non_matches): # Get a mapping of topic ARNs to organization service IDs db = DivvyCloudGatewayORM() org_svc_mapping = dict( db.session.query( DivvyDbObjects.ServiceLogGroup.namespace_id, DivvyDbObjects.ServiceLogGroup.organization_service_id)) log_group_arn = settings['log_group_arn'] region = log_group_arn.split(':')[3] log_group_name = log_group_arn.split(':')[-2] org_svc_id = org_svc_mapping.get(log_group_arn) if not org_svc_id: raise ValueError('Unable to identify organization service ID') frontend = get_cloud_type_by_organization_service_id(org_svc_id) backend = frontend.get_cloud_gw(region_name=region) client = backend.client('logs') # Get our last sequence token response = client.describe_log_streams( logGroupName=log_group_name, logStreamNamePrefix=settings['stream_name']) upload_sequence = None for item in response.get('logStreams', []): if item['logStreamName'] == settings['stream_name']: upload_sequence = item['uploadSequenceToken'] with ScheduledEventTracker() as context: for resource in matches: event = BotEvent('hookpoint', resource, bot.bot_id, bot.name) message = jinja2.Template(settings.get('message', '')) response = client.put_log_events( logGroupName=log_group_name, logStreamName=settings['stream_name'], logEvents=[{ 'timestamp': int(round(time.time() * 1000)), 'message': message.render(event=event, resource=resource), }], sequenceToken=upload_sequence) upload_sequence = response.get('nextSequenceToken')
def storage_container_with_bucket_policy(query, db_cls, settings_config): # Avoid circular imports from DivvyWorkers.Harvesters.base import CorePropertyNames db = DivvyCloudGatewayORM() subq = db.session.query( DivvyDbObjects.OrganizationService.organization_service_id ).filter( DivvyDbObjects.OrganizationService.resource_id.in_( db.session.query( DivvyDbObjects.ResourceProperty.resource_id ).filter( DivvyDbObjects.ResourceProperty.name == CorePropertyNames.bucket_public_policy ).filter( func.json_extract( DivvyDbObjects.ResourceProperty.value, '$."{0}"'.format(settings_config['policy_option']) ) == True ) ) ) return query.filter(db_cls.organization_service_id.notin_(subq))
def identity_resource_with_invalid_policy(query, db_cls, settings_config): # First we need to build a list of policy documents and iterate over them db = DivvyCloudGatewayORM() actions = [action.lower() for action in settings_config['actions']] resources = settings_config.get('resources', []) policy_resource_ids = [] invalid_user_resource_ids = [] for row in db.session.query( dbo.ServicePolicy.resource_id, dbo.ServicePolicyDocument.document ).filter( dbo.ServicePolicy.arn == dbo.ServicePolicyDocument.policy_arn ).filter( dbo.ServicePolicyDocument.is_default_version.is_(True) ).filter( dbo.ServicePolicy.attachment_count != 0 ): if policy_contains_permissions( row.document, actions, row.resource_id, resources ): policy_resource_ids.append(row.resource_id) for row in db.session.query( dbo.ServiceManagedPolicy.resource_id, dbo.ServiceManagedPolicyDocument.document ).filter( dbo.ServiceManagedPolicy.policy_id == dbo.ServiceManagedPolicyDocument.document_id ).filter( dbo.ServiceManagedPolicyDocument.is_default_version.is_(True) ): if policy_contains_permissions( row.document, actions, row.resource_id, resources ): policy_resource_ids.append(row.resource_id) for row in db.session.query( db_cls.resource_id, db_cls.inline_policies ).filter( db_cls.inline_policies.isnot(None) ): for policy in row.inline_policies: if isinstance(policy, dict): for _policy_name, document in policy.items(): # pylint: disable=W0612 if policy_contains_permissions( document, actions, None, resources ): invalid_user_resource_ids.append(row.resource_id) if ( db_cls.resource_type == ResourceType.SERVICE_USER and settings_config.get('walk_groups') is True ): query = query.filter(or_( db_cls.resource_id.in_( db.session.query( dbo.ResourceLink.left_resource_id ).filter( dbo.ResourceLink.right_resource_id.in_(policy_resource_ids) ) ), db_cls.resource_id.in_(invalid_user_resource_ids), db_cls.resource_id.in_( db.session.query( dbo.ResourceLink.left_resource_id ).filter( dbo.ResourceLink.right_resource_id.in_( db.session.query( dbo.ResourceLink.left_resource_id ).filter( dbo.ResourceLink.left_resource_id.like('servicegroup:%') ).filter( dbo.ResourceLink.right_resource_id.in_(policy_resource_ids) ) ) ) ) )) else: query = query.filter(or_( db_cls.resource_id.in_( db.session.query( dbo.ResourceLink.left_resource_id ).filter( dbo.ResourceLink.right_resource_id.in_(policy_resource_ids) ) ), db_cls.resource_id.in_(invalid_user_resource_ids) )) return query
def instance_not_running_approved_image(query, db_cls, settings_config): db = DivvyCloudGatewayORM() return query.filter( db_cls.image_id.notin_(db.session.query( dbobjects.ValidImage.image_id)))