def get(self, id=None): data = [] if not detector.check_availability('neo4j'): log.warning("This endpoint is implemented only for neo4j") return self.force_response(data) self.graph = self.get_service_instance('neo4j') is_admin = self.auth.verify_admin() is_group_admin = self.auth.verify_group_admin() if not is_admin and not is_group_admin: raise RestApiException( "You are not authorized: missing privileges", status_code=hcodes.HTTP_BAD_UNAUTHORIZED) current_user = self.get_current_user() nodeset = self.graph.User.nodes for n in nodeset.all(): is_authorized = self.check_permissions( current_user, n, is_admin, is_group_admin ) if not is_authorized: continue user = self.getJsonResponse(n, max_relationship_depth=1) data.append(user) return self.force_response(data)
def get(self, service): log.critical(detector.available_services) if not detector.check_availability(service): raise RestApiException( "Unknown service: {}".format(service), status_code=hcodes.HTTP_BAD_UNAUTHORIZED, ) service_instance = self.get_service_instance(service, global_instance=False) log.critical(service_instance) return self.force_response("Service is reachable: {}".format(service))
def test_08_admin_users(self, client): service = 'neo4j' from restapi.services.detect import detector if not detector.check_availability(service): return True else: log.debug("Testing admin users for %s", service) headers, _ = self.do_login(client, None, None) endpoint = "admin/users" get_r, _, _, _ = self._test_endpoint( client, endpoint, headers, hcodes.HTTP_OK_BASIC, hcodes.HTTP_BAD_REQUEST, hcodes.HTTP_BAD_METHOD_NOT_ALLOWED, hcodes.HTTP_BAD_METHOD_NOT_ALLOWED) self.checkResponse(get_r, [], []) # users_def = self.get("def.users") # user_def = self.get("def.user") # user, user_pwd = self.create_user('*****@*****.**') # user_headers, user_token = self.do_login(user, user_pwd) # data = {} # data['name'] = "A new name" # data['password'] = self.randomString() # self._test_update( # user_def, 'admin/users/' + user, # headers, data, hcodes.HTTP_OK_NORESPONSE) # self._test_delete( # user_def, 'admin/users/' + user, # headers, hcodes.HTTP_OK_NORESPONSE) endpoint = AUTH_URI + '/logout' r = client.get(endpoint, headers=headers) assert r.status_code == hcodes.HTTP_OK_NORESPONSE
def delete(self, user_id=None): if user_id is None: raise RestApiException( "Please specify a user id", status_code=hcodes.HTTP_BAD_REQUEST) if not detector.check_availability('neo4j'): log.warning("This endpoint is implemented only for neo4j") return self.empty_response() self.graph = self.get_service_instance('neo4j') is_admin = self.auth.verify_admin() is_group_admin = self.auth.verify_group_admin() if not is_admin and not is_group_admin: raise RestApiException( "You are not authorized: missing privileges", status_code=hcodes.HTTP_BAD_UNAUTHORIZED) user = self.graph.User.nodes.get_or_none(uuid=user_id) # user = self.getNode(self.graph.User, user_id, field='uuid') if user is None: raise RestApiException( "This user cannot be found or you are not authorized") current_user = self.get_current_user() is_authorized = self.check_permissions( current_user, user, is_admin, is_group_admin ) if not is_authorized: raise RestApiException( "This user cannot be found or you are not authorized") user.delete() return self.empty_response()
from restapi.confs import get_api_url from flask import request api_url = get_api_url(request, PRODUCTION) scheme, host = api_url.rstrip('/').split('://') swagjson['host'] = host swagjson['schemes'] = [scheme] # Jsonify, so we skip custom response building return jsonify(swagjson) ########################### # In case you have celery queue, # you get a queue endpoint for free if detector.check_availability('celery'): class Queue(EndpointResource): depends_on = ["CELERY_ENABLE"] labels = ["tasks"] GET = { "/queue": { "summary": "List tasks in the queue", "description": "Base implementation of a CELERY queue.", "responses": {"200": {"description": "A list of tasks"}}, }, "/queue/<task_id>": { "summary": "Information about a single task", "responses": {"200": {"description": "task information"}}, },
Remove tokens: MATCH (a:Token) WHERE NOT (a)<-[]-() DELETE a """ import pytz from datetime import datetime, timedelta from utilities.uuid import getUUID from restapi.services.authentication import BaseAuthentication from restapi.services.detect import detector from utilities.logs import get_logger log = get_logger(__name__) if not detector.check_availability(__name__): log.critical_exit("No neo4j GraphDB service found for auth") class Authentication(BaseAuthentication): def get_user_object(self, username=None, payload=None): from neomodel.exceptions import DeflateError user = None try: if username is not None: user = self.db.User.nodes.get(email=username) if payload is not None and 'user_id' in payload: user = self.db.User.nodes.get(uuid=payload['user_id']) except DeflateError: log.warning("Invalid username '%s'", username)
def put(self, user_id=None): if user_id is None: raise RestApiException( "Please specify a user id", status_code=hcodes.HTTP_BAD_REQUEST) if not detector.check_availability('neo4j'): log.warning("This endpoint is implemented only for neo4j") return self.empty_response() schema = self.get_endpoint_custom_definition() self.graph = self.get_service_instance('neo4j') is_admin = self.auth.verify_admin() is_group_admin = self.auth.verify_group_admin() if not is_admin and not is_group_admin: raise RestApiException( "You are not authorized: missing privileges", status_code=hcodes.HTTP_BAD_UNAUTHORIZED) v = self.get_input() user = self.graph.User.nodes.get_or_none(uuid=user_id) # user = self.getNode(self.graph.User, user_id, field='uuid') if user is None: raise RestApiException( "This user cannot be found or you are not authorized") current_user = self.get_current_user() is_authorized = self.check_permissions( current_user, user, is_admin, is_group_admin ) if not is_authorized: raise RestApiException( "This user cannot be found or you are not authorized") unhashed_password = None if "password" in v and v["password"] == "": del v["password"] else: v["password"] = BaseAuthentication.hash_password(v["password"]) if "email" in v: v["email"] = v["email"].lower() self.update_properties(user, schema, v) user.save() if 'group' in v: group = self.parse_group(v) if not is_admin: if not group.coordinator.is_connected(current_user): raise RestApiException( "You are allowed to assign users to this group") p = None for p in user.belongs_to.all(): if p == group: continue if p is not None: user.belongs_to.reconnect(p, group) else: user.belongs_to.connect(group) roles = self.parse_roles(v) if not is_admin: allowed_roles = mem.customizer._configurations \ .get('variables', {}) \ .get('backend', {}) \ .get('allowed_roles', []) for r in roles: if r not in allowed_roles: raise RestApiException( "You are allowed to assign users to this role") self.auth.link_roles(user, roles) email_notification = v.get('email_notification', False) if email_notification and unhashed_password is not None: self.send_notification(user, unhashed_password, is_update=True) return self.empty_response()
def post(self): v = self.get_input() if len(v) == 0: raise RestApiException( 'Empty input', status_code=hcodes.HTTP_BAD_REQUEST) if not detector.check_availability('neo4j'): log.warning("This endpoint is implemented only for neo4j") return self.force_response('0') self.graph = self.get_service_instance('neo4j') is_admin = self.auth.verify_admin() is_group_admin = self.auth.verify_group_admin() if not is_admin and not is_group_admin: raise RestApiException( "You are not authorized: missing privileges", status_code=hcodes.HTTP_BAD_UNAUTHORIZED) schema = self.get_endpoint_custom_definition() if 'get_schema' in v: new_schema = schema[:] if send_mail_is_active(): new_schema.append( { "name": "email_notification", "description": "Notify password by email", "type": "boolean", "default": False, "custom": { "htmltype": "checkbox", "label": "Notify password by email" } } ) if is_admin: return self.force_response(new_schema) # institutes = self.graph.Institute.nodes # users = self.graph.User.nodes current_user = self.get_current_user() for idx, val in enumerate(new_schema): if val["name"] == "group": new_schema[idx]["default"] = None new_schema[idx]["custom"] = { "htmltype": "select", "label": "Group" } new_schema[idx]["enum"] = [] for g in current_user.coordinator.all(): new_schema[idx]["enum"].append( {g.uuid: g.shortname} ) if new_schema[idx]["default"] is None: new_schema[idx]["default"] = g.uuid return self.force_response(new_schema) # INIT # properties = self.read_properties(schema, v) roles = self.parse_roles(v) if not is_admin: allowed_roles = mem.customizer._configurations \ .get('variables', {}) \ .get('backend', {}) \ .get('allowed_roles', []) for r in roles: if r not in allowed_roles: raise RestApiException( "You are allowed to assign users to this role") if "password" in properties and properties["password"] == "": del properties["password"] if "password" in properties: unhashed_password = properties["password"] else: unhashed_password = None user = self.auth.create_user(properties, roles) group = None if 'group' in v: group = self.parse_group(v) if group is not None: if not is_admin: current_user = self.get_current_user() if not group.coordinator.is_connected(current_user): raise RestApiException( "You are allowed to assign users to this group") user.belongs_to.connect(group) email_notification = v.get('email_notification', False) if email_notification and unhashed_password is not None: self.send_notification(user, unhashed_password, is_update=False) return self.force_response(user.uuid)
def post(self): v = self.get_input() if len(v) == 0: raise RestApiException('Empty input', status_code=hcodes.HTTP_BAD_REQUEST) if not detector.check_availability('neo4j'): log.warning("This endpoint is implemented only for neo4j") return self.force_response('0') self.graph = self.get_service_instance('neo4j') is_admin = self.auth.verify_admin() is_local_admin = self.auth.verify_local_admin() if not is_admin and not is_local_admin: raise RestApiException( "You are not authorized: missing privileges", status_code=hcodes.HTTP_BAD_UNAUTHORIZED) schema = self.get_endpoint_custom_definition() if 'get_schema' in v: new_schema = schema[:] if send_mail_is_active(): new_schema.append({ "name": "email_notification", "description": "Notify password by email", "type": "boolean", "default": False, "custom": { "htmltype": "checkbox", "label": "Notify password by email" } }) if 'autocomplete' in v and not v['autocomplete']: for idx, val in enumerate(new_schema): if val["name"] == "group": new_schema[idx]["default"] = None if "custom" not in new_schema[idx]: new_schema[idx]["custom"] = {} new_schema[idx]["custom"]["htmltype"]: "select" new_schema[idx]["custom"]["label"]: "Group" new_schema[idx]["enum"] = [] for g in self.graph.Group.nodes.all(): new_schema[idx]["enum"].append( {g.uuid: g.fullname}) if new_schema[idx]["default"] is None: new_schema[idx]["default"] = g.uuid # Roles as multi checkbox if val["name"] == "roles": cypher = "MATCH (r:Role)" if not self.auth.verify_admin(): allowed_roles = mem.customizer._configurations \ .get('variables', {}) \ .get('backend', {}) \ .get('allowed_roles', []) cypher += " WHERE r.name in %s" % allowed_roles # Admin only else: cypher += " WHERE r.description <> 'automatic'" cypher += " RETURN r ORDER BY r.name ASC" result = self.graph.cypher(cypher) del new_schema[idx] for row in result: r = self.graph.Role.inflate(row[0]) role = { "type": "checkbox", # "name": "roles[%s]" % r.name, "name": "roles_%s" % r.name, # "name": r.name, "custom": { "label": r.description } } new_schema.insert(idx, role) if is_admin: return self.force_response(new_schema) # institutes = self.graph.Institute.nodes # users = self.graph.User.nodes current_user = self.get_current_user() for idx, val in enumerate(new_schema): if val["name"] == "group": new_schema[idx]["default"] = None new_schema[idx]["custom"] = { "htmltype": "select", "label": "Group" } new_schema[idx]["enum"] = [] default_group = self.graph.Group.nodes.get_or_none( shortname="default") if default_group is not None: new_schema[idx]["enum"].append( {default_group.uuid: default_group.shortname}) new_schema[idx]["default"] = default_group.uuid for g in current_user.coordinator.all(): if g == default_group: continue new_schema[idx]["enum"].append({g.uuid: g.shortname}) if new_schema[idx]["default"] is None: new_schema[idx]["default"] = g.uuid return self.force_response(new_schema) # INIT # properties = self.read_properties(schema, v) roles = self.parse_roles(v) if not is_admin: allowed_roles = mem.customizer._configurations \ .get('variables', {}) \ .get('backend', {}) \ .get('allowed_roles', []) for r in roles: if r not in allowed_roles: raise RestApiException( "You are allowed to assign users to this role") if "password" in properties and properties["password"] == "": del properties["password"] if "password" in properties: unhashed_password = properties["password"] else: unhashed_password = None user = self.auth.create_user(properties, roles) group = None if 'group' in v: group = self.parse_group(v) if group is not None: if not is_admin: current_user = self.get_current_user() if not group.coordinator.is_connected(current_user): raise RestApiException( "You are allowed to assign users to this group") user.belongs_to.connect(group) email_notification = v.get('email_notification', False) if email_notification and unhashed_password is not None: self.send_notification(user, unhashed_password, is_update=False) return self.force_response(user.uuid)