Пример #1
0
    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)
Пример #2
0
    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))
Пример #3
0
    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
Пример #4
0
    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()
Пример #5
0
        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"}},
            },
Пример #6
0
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)
Пример #7
0
    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()
Пример #8
0
    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)
Пример #9
0
    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)