def collection_post(self): obj = self.request.validated if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, obj) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) if not self.integrity_validation(obj): if len(self.request.errors) < 1: self.request.errors.add('body', 'object', 'Integrity error') return # Remove '_id' for security reasons if self.key in obj: del obj[self.key] obj = self.pre_save(obj) if obj is None: return try: obj_id = self.collection.insert(obj) except DuplicateKeyError, e: raise HTTPBadRequest('The Object already exists: ' '{0}'.format(e.message))
def refresh_policies(self): obj = self.request.validated oid = self.request.matchdict['oid'] if oid != str(obj[self.key]): raise HTTPBadRequest('The object id is not the same that the id in' ' the url') if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, oid) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) obj_filter = self.get_oid_filter(oid) obj_filter.update(self.mongo_filter) real_obj = self.collection.find_one(obj_filter) if not real_obj: raise HTTPNotFound() self.notify_refresh_policies(real_obj) obj = self.parse_item(real_obj) return obj
def collection_post(self): obj = self.request.validated if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, obj) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) if not self.integrity_validation(obj): if len(self.request.errors) < 1: self.request.errors.add('body', 'object', 'Integrity error') return # Remove '_id' for security reasons if self.key in obj: del obj[self.key] obj = self.pre_save(obj) if obj is None: return try: obj_id = self.collection.insert_one(obj).inserted_id except DuplicateKeyError as e: raise HTTPBadRequest('The Object already exists: ' '{0}'.format(e.message)) obj = self.post_save(obj) obj.update({self.key: obj_id}) self.notify_created(obj) return self.parse_item(obj)
def refresh_policies(self): obj = self.request.validated oid = self.request.matchdict['oid'] if oid != str(obj[self.key]): raise HTTPBadRequest('The object id is not the same that the id in' ' the url') if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, obj) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) obj_filter = self.get_oid_filter(oid) obj_filter.update(self.mongo_filter) real_obj = self.collection.find_one(obj_filter) if not real_obj: raise HTTPNotFound() self.notify_refresh_policies(real_obj) obj = self.parse_item(real_obj) return obj
def put(self): obj = self.request.validated oid = self.request.matchdict['oid'] if oid != str(obj[self.key]): raise HTTPBadRequest('The object id is not the same that the id in' ' the url') if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, oid) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) obj_filter = self.get_oid_filter(oid) obj_filter.update(self.mongo_filter) real_obj = self.collection.find_one(obj_filter) if not real_obj: raise HTTPNotFound() old_obj = deepcopy(real_obj) if not self.integrity_validation(obj, real_obj=real_obj): if len(self.request.errors) < 1: self.request.errors.add('body', 'object', 'Integrity error') logger.error("Integrity error in object: {0}".format(obj)) else: logger.error("Integrity error {0} in object: {1}".format( self.request.errors, obj)) return obj = self.pre_save(obj, old_obj=old_obj) if obj is None: return inheritance_backup = None if 'inheritance' in obj: # Do not save the inheritance field inheritance_backup = obj['inheritance'] del obj['inheritance'] real_obj.update(obj) try: self.collection.replace_one(obj_filter, real_obj) except DuplicateKeyError as e: raise HTTPBadRequest('Duplicated object {0}'.format(e.message)) obj = self.post_save(obj, old_obj=old_obj) self.notify_changed(obj, old_obj) obj = self.parse_item(obj) if inheritance_backup is not None: obj['inheritance'] = inheritance_backup return obj
def _get_domain(self, ouSchema, xmlDomain, is_ad_master, report): # Get already exists root domain domain_id = self.request.POST.get('domainId', None) system_type = self.request.POST.get('systemType', 'ad') if not domain_id: raise HTTPBadRequest('GECOSCC needs a domainId param') filter_domain = { '_id': ObjectId(domain_id), 'type': ouSchema['mongoType'] } domain = self.collection.find_one(filter_domain) if not domain: raise HTTPBadRequest('domain does not exists') can_access_to_this_path(self.request, self.collection, domain, ou_type='ou_availables') if not is_domain(domain): raise HTTPBadRequest('domain param is not a domain id') update_domain = { 'extra': xmlDomain.attributes['DistinguishedName'].value, 'source': u'{0}:{1}:{2}'.format( system_type, xmlDomain.attributes['DistinguishedName'].value, xmlDomain.attributes['ObjectGUID'].value), 'adObjectGUID': xmlDomain.attributes['ObjectGUID'].value, 'adDistinguishedName': xmlDomain.attributes['DistinguishedName'].value, 'master_policies': {} } has_updated = False report['total'] += 1 if is_ad_master: update_domain['master'] = u'{0}:{1}:{2}'.format( system_type, xmlDomain.attributes['DistinguishedName'].value, xmlDomain.attributes['ObjectGUID'].value) has_updated = True elif not is_ad_master: if 'adObjectGUID' not in domain: update_domain['master'] = MASTER_DEFAULT has_updated = True elif domain['master'] != MASTER_DEFAULT: update_domain['master'] = MASTER_DEFAULT has_updated = True if has_updated: self.collection.update(filter_domain, {'$set': update_domain}) report['updated'] += 1 domain = self.collection.find_one(filter_domain) return domain
def _get_domain(self, ouSchema, xmlDomain, is_ad_master, report): # Get already exists root domain domain_id = self.request.POST.get('domainId', None) system_type = self.request.POST.get('systemType', 'ad') if not domain_id: raise HTTPBadRequest('GECOSCC needs a domainId param') filter_domain = { '_id': ObjectId(domain_id), 'type': ouSchema['mongoType'] } domain = self.collection.find_one(filter_domain) if not domain: raise HTTPBadRequest('domain does not exists') can_access_to_this_path(self.request, self.collection, domain, ou_type='ou_availables') if not is_domain(domain): raise HTTPBadRequest('domain param is not a domain id') update_domain = { 'extra': xmlDomain.attributes['DistinguishedName'].value, 'source': u'{0}:{1}:{2}'.format(system_type, xmlDomain.attributes['DistinguishedName'].value, xmlDomain.attributes['ObjectGUID'].value), 'adObjectGUID': xmlDomain.attributes['ObjectGUID'].value, 'adDistinguishedName': xmlDomain.attributes['DistinguishedName'].value, 'master_policies': {} } has_updated = False report['total'] += 1 if is_ad_master: update_domain['master'] = u'{0}:{1}:{2}'.format(system_type, xmlDomain.attributes['DistinguishedName'].value, xmlDomain.attributes['ObjectGUID'].value) has_updated = True elif not is_ad_master: if 'adObjectGUID' not in domain: update_domain['master'] = MASTER_DEFAULT has_updated = True elif domain['master'] != MASTER_DEFAULT: update_domain['master'] = MASTER_DEFAULT has_updated = True if has_updated: self.collection.update(filter_domain, {'$set': update_domain}) report['updated'] += 1 domain = self.collection.find_one(filter_domain) return domain
def put(self): obj = self.request.validated oid = self.request.matchdict['oid'] if oid != str(obj[self.key]): raise HTTPBadRequest('The object id is not the same that the id in' ' the url') if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, obj) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) obj_filter = self.get_oid_filter(oid) obj_filter.update(self.mongo_filter) real_obj = self.collection.find_one(obj_filter) if not real_obj: raise HTTPNotFound() old_obj = deepcopy(real_obj) if not self.integrity_validation(obj, real_obj=real_obj): if len(self.request.errors) < 1: self.request.errors.add('body', 'object', 'Integrity error') return obj = self.pre_save(obj, old_obj=old_obj) if obj is None: return inheritance_backup = None if 'inheritance' in obj: # Do not save the inheritance field inheritance_backup = obj['inheritance'] del obj['inheritance'] real_obj.update(obj) try: self.collection.update(obj_filter, real_obj, new=True) except DuplicateKeyError, e: raise HTTPBadRequest('Duplicated object {0}'.format( e.message))
def get(self): oid = self.request.matchdict['oid'] if issubclass(self.schema_detail, Node): try: can_access_to_this_path(self.request, self.collection, oid, ou_type='ou_readonly') except HTTPForbidden: can_access_to_this_path(self.request, self.collection, oid) collection_filter = self.get_oid_filter(oid) collection_filter.update(self.get_object_filter()) collection_filter.update(self.mongo_filter) node = self.collection.find_one(collection_filter) if not node: raise HTTPNotFound() node = self.parse_item(node) if node.get('type', None) in RESOURCES_EMITTERS_TYPES: node['is_assigned'] = self.is_assigned(node) return node return node
def get(self): oid = self.request.matchdict['oid'] if issubclass(self.schema_detail, Node): try: can_access_to_this_path(self.request, self.collection, oid, ou_type='ou_readonly') except HTTPForbidden: can_access_to_this_path(self.request, self.collection, oid) collection_filter = self.get_oid_filter(oid) collection_filter.update(self.get_object_filter()) collection_filter.update(self.mongo_filter) node = self.collection.find_one(collection_filter) if not node: raise HTTPNotFound() node = self.parse_item(node) if node.get('type', None) in RESOURCES_EMITTERS_TYPES: node['is_assigned'] = self.is_assigned(node) return node return node
def delete(self): oid = self.request.matchdict['oid'] if issubclass(self.schema_detail, Node): obj = self.collection.find_one({'_id': ObjectId(oid)}) can_access_to_this_path(self.request, self.collection, obj) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) filters = self.get_oid_filter(oid) filters.update(self.mongo_filter) obj = self.collection.find_one(filters) if not obj: raise HTTPNotFound() old_obj = deepcopy(obj) obj = self.pre_save(obj) if obj is None: return obj = self.pre_delete(obj) status = self.collection.remove(filters) if status['ok']: obj = self.post_save(obj, old_obj) obj = self.post_delete(obj) self.notify_deleted(obj) return { 'status': 'The object was deleted successfully', 'ok': 1 } else: self.request.errors.add(unicode(obj[self.key]), 'db status', status) return
def put(self): obj = self.request.validated oid = self.request.matchdict['oid'] if oid != str(obj[self.key]): raise HTTPBadRequest('The object id is not the same that the id in' ' the url') if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, obj) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) obj_filter = self.get_oid_filter(oid) obj_filter.update(self.mongo_filter) real_obj = self.collection.find_one(obj_filter) if not real_obj: raise HTTPNotFound() old_obj = deepcopy(real_obj) if not self.integrity_validation(obj, real_obj=real_obj): if len(self.request.errors) < 1: self.request.errors.add('body', 'object', 'Integrity error') return obj = self.pre_save(obj, old_obj=old_obj) if obj is None: return real_obj.update(obj) try: self.collection.update(obj_filter, real_obj, new=True) except DuplicateKeyError, e: raise HTTPBadRequest('Duplicated object {0}'.format(e.message))
def delete(self): oid = self.request.matchdict['oid'] if issubclass(self.schema_detail, Node): obj = self.collection.find_one({'_id': ObjectId(oid)}) can_access_to_this_path(self.request, self.collection, oid) is_gecos_master_or_403(self.request, self.collection, obj, self.schema_detail) master_policy_no_updated_or_403(self.request, self.collection, obj) filters = self.get_oid_filter(oid) filters.update(self.mongo_filter) obj = self.collection.find_one(filters) if not obj: raise HTTPNotFound() old_obj = deepcopy(obj) obj = self.pre_save(obj) if obj is None: return obj = self.pre_delete(obj) status = self.collection.delete_one(filters).raw_result if status['ok']: obj = self.post_save(obj, old_obj) obj = self.post_delete(obj) self.notify_deleted(obj) return {'status': 'The object was deleted successfully', 'ok': 1} else: self.request.errors.add('body', '%s: db status' % (obj[self.key]), status) return
def post(self): """ Imports and converts XML GPOs into GECOSCC from self.request """ try: counter = 0 status = '' ok = True # Read SID-GUID data postedfile = self.request.POST['media0'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() xmlsid_guid = xmltodict.parse(xmldata) GPOConversor.xml_sid_guid = xmlsid_guid # Update domain with master_policies domain_id = self.request.POST.get('domainId', None) if not domain_id: raise HTTPBadRequest('GECOSCC needs a domainId param') filter_domain = {'_id': ObjectId(domain_id), 'type': 'ou'} domain = self.collection.find_one(filter_domain) if not domain: raise HTTPBadRequest('domain does not exists') can_access_to_this_path(self.request, self.collection, domain, ou_type='ou_availables') if not is_domain(domain): raise HTTPBadRequest('domain param is not a domain id') policies_slugs = self.request.POST.getall('masterPolicy[]') for policy_slug in policies_slugs: policy = self.collection_policies.find_one( {'slug': policy_slug}) if 'master_policies' not in domain: domain['master_policies'] = {} if policy is not None and policy['_id'] not in domain[ 'master_policies']: domain['master_policies'][str(policy['_id'])] = True self.collection.update(filter_domain, domain) # Read GPOs data postedfile = self.request.POST['media1'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() xmlgpos = xmltodict.parse(xmldata) # Apply each xmlgpo for xmlgpo in xmlgpos['report']['GPO']: for gpoconversorclass in GPOConversor.__subclasses__(): if not gpoconversorclass(self.request).apply( self._cleanPrefixNamespaces(xmlgpo)): # TODO Report error to somewhere ok = False else: counter += 1 status = 'Policies applied correctly: {0}'.format(counter) except Exception as e: logger.exception(e) status = u'{0}'.format(e) ok = False return {'status': status, 'ok': ok}
def post(self): """ Imports and converts XML GPOs into GECOSCC from self.request """ try: counter = 0 status = '' ok = True # Read SID-GUID data postedfile = self.request.POST['media0'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() xmlsid_guid = xmltodict.parse(xmldata) GPOConversor.xml_sid_guid = xmlsid_guid # Update domain with master_policies domain_id = self.request.POST.get('domainId', None) if not domain_id: raise HTTPBadRequest('GECOSCC needs a domainId param') filter_domain = { '_id': ObjectId(domain_id), 'type': 'ou' } domain = self.collection.find_one(filter_domain) if not domain: raise HTTPBadRequest('domain does not exists') can_access_to_this_path(self.request, self.collection, domain, ou_type='ou_availables') if not is_domain(domain): raise HTTPBadRequest('domain param is not a domain id') policies_slugs = self.request.POST.getall('masterPolicy[]') for policy_slug in policies_slugs: policy = self.collection_policies.find_one({'slug': policy_slug}) if 'master_policies' not in domain: domain['master_policies'] = {} if policy is not None and policy['_id'] not in domain['master_policies']: domain['master_policies'][str(policy['_id'])] = True self.collection.update(filter_domain, domain) # Read GPOs data postedfile = self.request.POST['media1'].file xmldata = GzipFile('', 'r', 9, StringIO(postedfile.read())).read() xmlgpos = xmltodict.parse(xmldata) # Apply each xmlgpo for xmlgpo in xmlgpos['report']['GPO']: for gpoconversorclass in GPOConversor.__subclasses__(): if not gpoconversorclass(self.request).apply(self._cleanPrefixNamespaces(xmlgpo)): # TODO Report error to somewhere ok = False else: counter += 1 status = 'Policies applied correctly: {0}'.format(counter) except Exception as e: logger.exception(e) status = u'{0}'.format(e) ok = False return { 'status': status, 'ok': ok }
def get_oid_filter(self, oid): if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, oid) return {self.key: ObjectId(oid)}
def get_oid_filter(self, oid): if issubclass(self.schema_detail, Node): can_access_to_this_path(self.request, self.collection, oid) return {self.key: ObjectId(oid)}
def post(self): logger.debug('/help-channel-client/login START') # Default known message known_message = 'En un lugar de la Mancha, de cuyo nombre no quiero'\ ' acordarme, no ha mucho tiempo que vivía un hidalgo de los de'\ ' lanza en astillero, adarga antigua, rocín flaco y galgo corredor.' # Check the parameters node_id = self.request.POST.get('node_id') if not node_id: logger.error('/help-channel-client/login - No node ID') return {'ok': False, 'message': 'Please set a node id'} username = self.request.POST.get('username') if not username: logger.error('/help-channel-client/login - No username') return {'ok': False, 'message': 'Please set a username'} secret = self.request.POST.get('secret') if not secret: logger.error('/help-channel-client/login - No secret') return {'ok': False, 'message': 'Please set a secret'} hc_server = self.request.POST.get('hc_server') if not hc_server: logger.error('/help-channel-client/login - No server') return {'ok': False, 'message': 'Please set a Help Channel Server'} gcc_username = self.request.POST.get('gcc_username') if not gcc_username: logger.error('/help-channel-client/login - No admin username') return { 'ok': False, 'message': 'Please set a GCC administrator username' } self.request.user = self.request.db.adminusers.find_one( {'username': gcc_username}) if not self.request.user: return { 'ok': False, 'message': 'The admin user %s does not exists' % gcc_username } logger.debug('/help-channel-client/login node_id=%s' % (node_id)) logger.debug('/help-channel-client/login username=%s' % (username)) logger.debug('/help-channel-client/login secret=%s' % (secret)) logger.debug('/help-channel-client/login hc_server=%s' % (hc_server)) logger.debug('/help-channel-client/login gccusername=%s' % (gcc_username)) gcc_node = self.request.db.nodes.find_one({'node_chef_id': node_id}) if not gcc_node: logger.error('/help-channel-client/login - Node not found') return {'ok': False, 'message': 'Node not found in database'} can_access_to_this_path(self.request, self.request.db.nodes, gcc_node, ou_type='ou_remote') # Remote OUs gcc_user = self.request.db.nodes.find_one({ 'type': 'user', 'name': username }) if not gcc_user: logger.error('/help-channel-client/login - User not found') return {'ok': False, 'message': 'User not found in database'} try: # Check the secret message api = get_chef_api(self.request.registry.settings, self.request.user) chef_client = ChefClient(node_id, api) if not chef_client.exists: logger.error('/help-channel-client/login - Client not found') return {'ok': False, 'message': 'This client does not exists'} chef_node = ChefNode(node_id, api) if not chef_node.exists: logger.error( '/help-channel-client/login - Chef node not found') return { 'ok': False, 'message': 'This chef node does not exists' } client_certificate = chef_client.certificate public_key = RSA.importKey(client_certificate) decrypted = public_key.encrypt(bytes.fromhex(secret), 0)[0] decrypted = decrypted.decode("utf-8") known_message_setting = self.request.registry.settings.get( 'helpchannel.known_message') if known_message_setting is not None: known_message = known_message_setting if decrypted != known_message: logger.error('/help-channel-client/login - Bad secret') return {'ok': False, 'message': 'Bad secret'} # Login successful, generate the token! server_address = self.request.registry.settings.get( 'server_address', 'UNKNOWN') if server_address == 'UNKNOWN': server_address = os.getenv('HOSTNAME', 'UNKNOWN') # - Token generation min_char = 8 max_char = 12 allchar = string.ascii_letters + string.digits token = ''.join( choice(allchar) for _ in range(randint(min_char, max_char))) self.request.db.helpchannel.insert_one({ 'last_modified': datetime.datetime.utcnow(), 'action': 'request', 'computer_node_id': node_id, 'computer_node_path': gcc_node['path'], 'user_node_id': str(gcc_user['_id']), 'user_node_path': gcc_user['path'], 'adminuser_id': False, 'adminuser_ou_managed': False, 'adminuser_is_superuser': False, 'gecos_cc_server': server_address, 'helpchannel_server': hc_server, 'token': token }) logger.info('/help-channel-client/login - token: %s' % (token)) return {'ok': True, 'token': token} except (urllib.error.URLError, ChefError, ChefServerError): pass logger.error('/help-channel-client/login - UNKNOWN') return {'ok': False, 'message': 'Unknown error'}