Exemplo n.º 1
0
    def get(self, video_id, segment_id):
        if segment_id is not None:
            log.debug("get manual segment [uuid:{sid}] for AVEntity "
                      "[uuid:{vid}]".format(vid=video_id, sid=segment_id))
        else:
            log.debug(
                "get all manual segments for AVEntity [uuid:{vid}]".format(
                    vid=video_id))
        if video_id is None:
            raise RestApiException("Please specify a video id",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        self.graph = self.get_service_instance('neo4j')
        data = []

        video = None
        try:
            video = self.graph.AVEntity.nodes.get(uuid=video_id)
        except self.graph.AVEntity.DoesNotExist:
            log.debug("AVEntity with uuid %s does not exist" % video_id)
            raise RestApiException("Please specify a valid video id",
                                   status_code=hcodes.HTTP_BAD_NOTFOUND)

        # user = self.get_current_user()

        item = video.item.single()
        log.debug('get manual segments for Item [{}]'.format(item.uuid))
        # api_url = get_api_url(request, PRODUCTION)

        # TODO

        return self.force_response(data)
Exemplo n.º 2
0
    def delete(self, filename):

        self.graph = self.get_service_instance('neo4j')

        group = self.getSingleLinkedNode(self.get_current_user().belongs_to)

        if group is None:
            raise RestApiException("No group defined for this user",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        upload_dir = os.path.join("/uploads", group.uuid)
        if not os.path.exists(upload_dir):
            raise RestApiException("Upload dir not found",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        input_parameters = self.get_input()

        # if 'filename' not in input_parameters:
        #     raise RestApiException(
        #         "Filename not found",
        #         status_code=hcodes.HTTP_BAD_REQUEST)

        # filename = input_parameters['filename']

        path = os.path.join(upload_dir, filename)
        if not os.path.isfile(path):
            raise RestApiException("File not found: %s" % filename,
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        os.remove(path)
        return self.empty_response()
Exemplo n.º 3
0
    def wrapper(self, *args, **kwargs):

        from neomodel.exceptions import RequiredProperty
        from neomodel.exceptions import UniqueProperty

        try:
            return func(self, *args, **kwargs)

        except (UniqueProperty) as e:

            # Duplicated in admin_users
            # Please not that neomodel changed this error
            # the correct version is in admin_users
            prefix = "Node [0-9]+ already exists with label"
            m = re.search("{} (.+) and property (.+)".format(prefix), str(e))

            if m:
                node = m.group(1)
                prop = m.group(2)
                val = m.group(3)
                error = "A {} already exists with {} = {}".format(
                    node, prop, val)
            else:
                error = str(e)

            raise RestApiException(error, status_code=hcodes.HTTP_BAD_CONFLICT)
        except (RequiredProperty) as e:
            raise RestApiException(str(e))
Exemplo n.º 4
0
    def change_password(self, user, password, new_password, password_confirm):

        if new_password != password_confirm:
            msg = "Your password doesn't match the confirmation"
            raise RestApiException(msg, status_code=hcodes.HTTP_BAD_CONFLICT)

        if self.auth.VERIFY_PASSWORD_STRENGTH:
            check = True
            if password is not None:
                check, msg = self.verify_password_strength(
                    new_password, old_pwd=password
                )
            else:
                check, msg = self.verify_password_strength(
                    new_password, old_hash=user.password
                )

            if not check:
                raise RestApiException(msg, status_code=hcodes.HTTP_BAD_CONFLICT)

        if new_password is not None and password_confirm is not None:
            now = datetime.now(pytz.utc)
            user.password = BaseAuthentication.get_password_hash(new_password)
            user.last_password_change = now
            self.auth.save_user(user)

            tokens = self.auth.get_tokens(user=user)
            for token in tokens:
                self.auth.invalidate_token(token=token["token"])
            # changes the user uuid invalidating all tokens
            self.auth.invalidate_all_tokens()

        return True
Exemplo n.º 5
0
    def delete(self, token_id=None):
        """
            For additional security, tokens are invalidated both
            by chanding the user UUID and by removing single tokens
        """

        user = self.get_user()
        if user is None:
            raise RestApiException(
                'Invalid username', status_code=hcodes.HTTP_BAD_REQUEST
            )

        if token_id is None:
            # NOTE: this is allowed only in removing tokens in unittests
            if not current_app.config['TESTING']:
                raise KeyError("TESTING IS FALSE! Specify a valid token")
            self.auth.invalidate_all_tokens(user=user)
            return self.empty_response()

        tokens = self.auth.get_tokens(user=user)

        for token in tokens:
            if token["id"] != token_id:
                continue
            if not self.auth.invalidate_token(token=token["token"], user=user):
                raise RestApiException(
                    "Failed token invalidation: '{}'".format(token),
                    status_code=hcodes.HTTP_BAD_REQUEST
                )
            return self.empty_response()

        raise RestApiException(
            "Token not emitted for your account or does not exist",
            status_code=hcodes.HTTP_BAD_UNAUTHORIZED
        )
Exemplo n.º 6
0
    def get(self, user_id=None):

        data = []

        is_admin = self.auth.verify_admin()
        is_local_admin = self.auth.verify_local_admin()
        if not is_admin and not is_local_admin:
            extra_debug = "is_admin = {};".format(is_admin)
            extra_debug += " is_local_admin = {};".format(is_local_admin)
            extra_debug += " roles = {};".format(
                self.auth.get_roles_from_user())
            raise RestApiException(
                "You are not authorized: missing privileges. {}".format(
                    extra_debug),
                status_code=hcodes.HTTP_BAD_UNAUTHORIZED,
            )

        users = self.auth.get_users(user_id)
        if users is None:
            raise RestApiException(
                "This user cannot be found or you are not authorized")
        if self.neo4j_enabled:
            self.graph = self.get_service_instance('neo4j')

        current_user = self.get_current_user()
        for u in users:

            is_authorized = self.check_permissions(current_user, u, is_admin,
                                                   is_local_admin)
            if not is_authorized:
                continue

            if self.neo4j_enabled:
                user = self.getJsonResponse(u, max_relationship_depth=1)
            elif self.sql_enabled:
                user = self.getJsonResponseFromSql(u)
                user['relationships'] = {}
                user['relationships']['roles'] = []
                for role in u.roles:
                    r = self.getJsonResponseFromSql(role)
                    user['relationships']['roles'].append(r)
            elif self.mongo_enabled:
                user = self.getJsonResponseFromMongo(u)
                user['relationships'] = {}
                user['relationships']['roles'] = self.auth.get_roles_from_user(
                    u)
            else:
                raise RestApiException(
                    "Invalid auth backend, all known db are disabled")

            data.append(user)

        return self.force_response(data)
Exemplo n.º 7
0
    def get(self, shot_id):
        logger.info("get annotations for Shot id: %s", shot_id)
        if shot_id is None:
            raise RestApiException("Please specify a shot id",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        params = self.get_input()
        logger.debug("inputs %s" % params)
        anno_type = params.get('type')
        if anno_type is not None:
            anno_type = anno_type.upper()

        self.graph = self.get_service_instance('neo4j')
        data = []

        shot = None
        try:
            shot = self.graph.Shot.nodes.get(uuid=shot_id)
        except self.graph.AVEntity.DoesNotExist:
            logger.debug("Shot with uuid %s does not exist" % shot_id)
            raise RestApiException("Please specify a valid shot id",
                                   status_code=hcodes.HTTP_BAD_NOTFOUND)

        user = self.get_current_user()

        for a in shot.annotation:
            if anno_type is not None and a.annotation_type != anno_type:
                continue
            if a.private:
                if a.creator is None:
                    logger.warn('Invalid state: missing creator for private '
                                'note [UUID:{}]'.format(a.uuid))
                    continue
                creator = a.creator.single()
                if creator.uuid != user.uuid:
                    continue
            res = self.getJsonResponse(a, max_relationship_depth=0)
            del (res['links'])
            if a.annotation_type in ('TAG', 'DSC') and a.creator is not None:
                res['creator'] = self.getJsonResponse(a.creator.single(),
                                                      max_relationship_depth=0)
            # attach bodies
            res['bodies'] = []
            for b in a.bodies.all():
                anno_body = b.downcast()
                body = self.getJsonResponse(anno_body,
                                            max_relationship_depth=0)
                if 'links' in body:
                    del (body['links'])
                res['bodies'].append(body)
            data.append(res)

        return self.force_response(data)
Exemplo n.º 8
0
    def put(self, token_id):

        token_id = token_id.replace("+", ".")
        try:
            # Unpack and verify token. If ok, self.auth will be added with
            # auth._user auth._token and auth._jti
            self.auth.verify_token(
                token_id, raiseErrors=True, token_type=self.auth.ACTIVATE_ACCOUNT
            )

        # If token is expired
        except jwt.exceptions.ExpiredSignatureError:
            raise RestApiException(
                'Invalid activation token: this request is expired',
                status_code=hcodes.HTTP_BAD_REQUEST,
            )

        # if token is not yet active
        except jwt.exceptions.ImmatureSignatureError:
            raise RestApiException(
                'Invalid activation token', status_code=hcodes.HTTP_BAD_REQUEST
            )

        # if token does not exist (or other generic errors)
        except Exception:
            raise RestApiException(
                'Invalid activation token', status_code=hcodes.HTTP_BAD_REQUEST
            )

        # Recovering token object from jti
        token = self.auth.get_tokens(token_jti=self.auth._jti)
        if len(token) == 0:
            raise RestApiException(
                'Invalid activation token: this request is no longer valid',
                status_code=hcodes.HTTP_BAD_REQUEST,
            )

        # If user logged is already active, invalidate the token
        if self.auth._user.is_active is not None and self.auth._user.is_active:
            self.auth.invalidate_token(token_id)
            raise RestApiException(
                'Invalid activation token: this request is no longer valid',
                status_code=hcodes.HTTP_BAD_REQUEST,
            )

        # The activation token is valid, do something
        self.auth._user.is_active = True
        self.auth.save_user(self.auth._user)

        # Bye bye token (reset activation are valid only once)
        self.auth.invalidate_token(token_id)

        return self.force_response("Account activated")
Exemplo n.º 9
0
    def post(self):

        self.graph = self.get_service_instance('neo4j')

        v = self.get_input()
        if len(v) == 0:
            raise RestApiException('Empty input',
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        schema = self.get_endpoint_custom_definition()

        if 'get_schema' in v:
            users = self.graph.User.nodes
            for idx, val in enumerate(schema):
                if val["name"] == "coordinator":
                    schema[idx]["enum"] = []
                    for n in users.all():
                        r = self.auth.get_roles_from_user(n)

                        can_coordinate = False
                        if self.auth.role_admin in r:
                            can_coordinate = True
                        elif 'local_admin' in r:
                            can_coordinate = True

                        if can_coordinate:

                            label = "%s %s (%s)" % (n.name, n.surname, n.email)

                            schema[idx]["enum"].append({n.uuid: label})

            return self.force_response(schema)

        # INIT #
        properties = self.read_properties(schema, v)

        if 'coordinator' not in v:
            raise RestApiException('Coordinator not found',
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        coordinator = self.graph.User.nodes.get_or_none(uuid=v['coordinator'])
        # coordinator = self.getNode(
        #     self.graph.User, v['coordinator'], field='uuid')

        if coordinator is None:
            raise RestApiException('User not found',
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        # GRAPH #
        group = self.graph.Group(**properties).save()
        # group.coordinator.connect(coordinator)

        return self.force_response(group.uuid)
Exemplo n.º 10
0
    def get(self):
        """Get all videos under revision"""
        log.debug('Getting videos under revision.')
        self.graph = self.get_service_instance('neo4j')
        data = []

        input_parameters = self.get_input()
        input_assignee = input_parameters['assignee']
        offset, limit = self.get_paging()
        offset -= 1
        log.debug("paging: offset {0}, limit {1}".format(offset, limit))
        if offset < 0:
            raise RestApiException('Page number cannot be a negative value',
                                   status_code=hcodes.HTTP_BAD_REQUEST)
        if limit < 0:
            raise RestApiException('Page size cannot be a negative value',
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        # naive solution for getting VideoInRevision
        items = self.graph.Item.nodes.has(revision=True)
        for i in items:
            creation = i.creation.single()
            video = creation.downcast()
            assignee = i.revision.single()
            if input_assignee is not None and input_assignee != assignee.uuid:
                continue
            rel = i.revision.relationship(assignee)
            shots = i.shots.all()
            number_of_shots = len(shots)
            number_of_confirmed = len(
                [s for s in shots if s.revision_confirmed])
            # log.debug('number_of_shots {}'.format(number_of_shots))
            # log.debug('number_of_confirmed {}'.format(number_of_confirmed))
            percentage = 100 * number_of_confirmed / number_of_shots
            res = {
                'video': {
                    'uuid': video.uuid,
                    'title': video.identifying_title
                },
                'assignee': {
                    'uuid': assignee.uuid,
                    'name': assignee.name + ' ' + assignee.surname
                },
                'since': rel.when.isoformat(),
                'state': rel.state,
                'progress': percentage
            }
            data.append(res)

        return self.force_response(data)
Exemplo n.º 11
0
    def parse_group(self, v):
        groups = self.parseAutocomplete(v, 'group', id_key='id')

        if groups is None:
            raise RestApiException('Group not found',
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        group_id = groups.pop()
        group = self.graph.Group.nodes.get_or_none(uuid=group_id)

        if group is None:
            raise RestApiException('Group not found',
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        return group
Exemplo n.º 12
0
    def update_password(self, user, data):

        password = data.get('password')
        new_password = data.get('new_password')
        password_confirm = data.get('password_confirm')

        totp_authentication = (
            self.auth.SECOND_FACTOR_AUTHENTICATION is not None
            and self.auth.SECOND_FACTOR_AUTHENTICATION == self.auth.TOTP
        )
        if totp_authentication:
            totp_code = data.get('totp_code')
        else:
            totp_code = None

        security = HandleSecurity(self.auth)

        if new_password is None or password_confirm is None:
            msg = "New password is missing"
            raise RestApiException(msg, status_code=hcodes.HTTP_BAD_REQUEST)

        if totp_authentication:
            security.verify_totp(user, totp_code)
        else:
            token, _ = self.auth.make_login(user.email, password)
            security.verify_token(user.email, token)

        security.change_password(user, password, new_password, password_confirm)

        # NOTE already in change_password
        # but if removed new pwd is not saved
        return self.auth.save_user(user)
Exemplo n.º 13
0
    def get(self, anno_id=None):
        """ Get an annotation if its id is passed as an argument. """
        self.graph = self.get_service_instance('neo4j')

        params = self.get_input()
        anno_type = params.get('type')
        if anno_type is not None:
            anno_type = anno_type.upper()

        if anno_id is not None:
            # check if the video exists
            try:
                anno = self.graph.Annotation.nodes.get(uuid=anno_id)
            except self.graph.Annotation.DoesNotExist:
                logger.debug("Annotation with uuid %s does not exist" %
                             anno_id)
                raise RestApiException("Please specify a valid annotation id",
                                       status_code=hcodes.HTTP_BAD_NOTFOUND)
            annotations = [anno]
        elif anno_type is not None:
            annotations = self.graph.Annotation.nodes.filter(
                annotation_type=anno_type)
        else:
            annotations = self.graph.Annotation.nodes.all()

        data = []
        for a in annotations:
            anno = self.get_annotation_response(a)
            data.append(anno)

        return self.force_response(data)
Exemplo n.º 14
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)
Exemplo n.º 15
0
    def validate_input(self, json_parameters, definitionName):

        try:
            return input_validation(json_parameters, definitionName)
        except ValidationError as e:
            raise RestApiException(e.message,
                                   status_code=hcodes.HTTP_BAD_REQUEST)
Exemplo n.º 16
0
    def post(self):

        user = self.get_current_user()
        logger.info(
            'request for data extraction coming from user UUID: {}'.format(
                user.uuid))
        criteria = self.get_input()

        self.validate_input(criteria, 'DataExtraction')
        dataset_names = criteria.get('datasets')
        # check for existing dataset(s)
        datasets = arki.load_datasets()
        for ds_name in dataset_names:
            found = next(
                (ds for ds in datasets if ds.get('id', '') == ds_name), None)
            if not found:
                raise RestApiException(
                    "Dataset '{}' not found".format(ds_name),
                    status_code=hcodes.HTTP_BAD_NOTFOUND)

        filters = criteria.get('filters')

        task = CeleryExt.data_extract.apply_async(
            args=[user.uuid, dataset_names, filters], countdown=1)
        return self.force_response(task.id, code=hcodes.HTTP_OK_ACCEPTED)
Exemplo n.º 17
0
    def make_login(self, username, password):
        """ The method which will check if credentials are good to go """

        try:
            user = self.get_user_object(username=username)
        except BaseException as e:
            log.error("Unable to connect to auth backend\n[%s] %s", type(e), e)
            # log.critical("Please reinitialize backend tables")
            from restapi.exceptions import RestApiException
            raise RestApiException("Server authentication misconfiguration",
                                   status_code=hcodes.HTTP_SERVER_ERROR)

        if user is None:
            return None, None

        try:
            # Check if Oauth2 is enabled
            if user.authmethod != 'credentials':
                return None, None
        except BaseException:
            # Missing authmethod as requested for authentication
            log.critical("Current authentication db models are broken!")
            return None, None

        if self.check_passwords(user.password, password):
            return self.create_token(self.fill_payload(user))

        return None, None
Exemplo n.º 18
0
    def api(
        path: str,
        method: str,
        base: str = "api",
        payload: Optional[Dict[str, Any]] = None,
    ) -> Any:
        host = BotApiClient.variables.get("backend_host")
        port = Env.get("FLASK_PORT", "8080")
        url = f"http://{host}:{port}/{base}/{path}"

        log.debug("Calling {} on {}", method, url)

        try:
            data: Optional[str] = None
            if payload:
                data = orjson.dumps(payload).decode("UTF8")

            response = requests.request(method, url=url, data=data, timeout=10)

            out = response.json()
        # Never raised during tests: how to test it?
        except Exception as e:  # pragma: no cover
            log.error(f"API call failed: {e}")
            raise ServerError(str(e))

        if response.status_code >= 300:
            raise RestApiException(out, status_code=response.status_code)

        return out
Exemplo n.º 19
0
    def post(self):
        """ Create new current user """
        v = self.get_input()
        if len(v) == 0:
            raise RestApiException(
                'Empty input',
                status_code=hcodes.HTTP_BAD_REQUEST)
        # INIT #
        schema = self.get_endpoint_custom_definition()
        properties = self.read_properties(schema, v)
        # GRAPH #
        # properties["authmethod"] = "credentials"
        # if "password" in properties:
        # properties["password"] = \
        #     BaseAuthentication.hash_password(properties["password"])

        # DO CUSTOM STUFFS HERE - e.g. create irods user
        properties, other_properties = \
            self.custom_pre_handle_user_input(properties, v)

        roles = self.get_roles(v)
        user = self.auth.create_user(properties, roles)

        self.custom_post_handle_user_input(user, properties, other_properties)

        # DO CUSTOM STUFFS HERE - e.g. link to group
        return self.force_response(user.uuid)
Exemplo n.º 20
0
    def get_user_object(self, username=None, payload=None):
        user = None
        try:
            if username is not None:
                user = self.db.User.query.filter_by(email=username).first()
            if payload is not None and 'user_id' in payload:
                user = self.db.User.query.filter_by(
                    uuid=payload['user_id']).first()
        except (sqlalchemy.exc.StatementError,
                sqlalchemy.exc.InvalidRequestError) as e:

            # Unable to except pymysql.err.OperationalError because:
            # ModuleNotFoundError: No module named 'pymysql.err.OperationalError';
            # 'pymysql.err' is not a package
            # Let's test exception name (OMG!)
            if type(e).__name__ == 'pymysql.err.OperationalError':
                # If you catch an error that indicates the connection was closed during
                # an operation, SQLAlchemy automatically reconnects on the next access.

                # Pessimistic approach: Add pool_pre_ping=True when creating the engine
                # The “pre ping” feature will normally emit SQL equivalent to “SELECT 1”
                # each time a connection is checked out from the pool; if an error is
                # raised that is detected as a “disconnect” situation, the connection
                # will be immediately recycled, and all other pooled connections older
                # than the current time are invalidated, so that the next time they are
                # checked out, they will also be recycled before use.
                # This add a little overhead to every connections
                # https://docs.sqlalchemy.org/en/13/core/pooling.html#pool-disconnects-pessimistic

                # Optimistic approach: try expect for connection errors.
                # When the connection attempts to use a closed connection an exception
                # is raised, then the connection calls the Pool.create() method,
                # further connections will work again by using the refreshed connection.
                # Only a single transaction will fail -> retry the operation is enough
                # https://docs.sqlalchemy.org/en/13/core/pooling.html#disconnect-handling-optimistic

                # if retry <= 0:
                #     log.error(str(e))
                #     log.warning("Errors retrieving user object, retrying...")
                #     return self.get_user_object(
                #         username=username, payload=payload, retry=1
                #     )
                raise e
            else:
                log.error(str(e))
                raise RestApiException(
                    "Backend database is unavailable",
                    status_code=hcodes.HTTP_SERVICE_UNAVAILABLE,
                )
        except (sqlalchemy.exc.DatabaseError,
                sqlalchemy.exc.OperationalError) as e:
            # if retry <= 0:
            #     log.error(str(e))
            #     log.warning("Errors retrieving user object, retrying...")
            # return self.get_user_object(
            #     username=username, payload=payload, retry=1)
            raise e

        return user
Exemplo n.º 21
0
    def delete(self, group_id=None):

        if group_id is None:

            raise RestApiException("Please specify a group id",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        self.graph = self.get_service_instance('neo4j')

        group = self.graph.Group.nodes.get_or_none(uuid=group_id)
        # group = self.getNode(self.graph.Group, group_id, field='uuid')
        if group is None:
            raise RestApiException("Group not found")

        group.delete()

        return self.empty_response()
Exemplo n.º 22
0
    def verify_token(self, username, token):
        if token is None:

            if self.auth.REGISTER_FAILED_LOGIN:
                self.auth.register_failed_login(username)
            msg = 'Invalid username or password'
            code = hcodes.HTTP_BAD_UNAUTHORIZED
            raise RestApiException(msg, status_code=code)
Exemplo n.º 23
0
    def get(self, filename):
        log.info("get stage content for filename %s" % filename)
        if filename is None:
            raise RestApiException("Please specify a stage filename",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        self.graph = self.get_service_instance('neo4j')

        group = self.getSingleLinkedNode(self.get_current_user().belongs_to)

        if group is None:
            raise RestApiException("No group defined for this user",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        if group is None:
            raise RestApiException("No group defined for this user",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        upload_dir = os.path.join("/uploads", group.uuid)
        if not os.path.exists(upload_dir):
            os.mkdir(upload_dir)
            if not os.path.exists(upload_dir):
                return self.force_response([], errors=["Upload dir not found"])
        found = False
        for f in os.listdir(upload_dir):

            staged_file = os.path.join(upload_dir, f)
            if not os.path.isfile(staged_file):
                continue
            if f[0] == '.':
                continue
            if f == filename:
                found = True
                break
        if not found:
            raise RestApiException(
                "File not found. Please specify a valid staged file",
                status_code=hcodes.HTTP_BAD_NOTFOUND)

        mime_type = mime.guess_type(f)
        log.debug('mime type: {}'.format(mime_type))

        response = make_response(send_file(staged_file))
        response.headers['Content-Type'] = mime_type[0]
        return response
Exemplo n.º 24
0
    def head(self, video_id):
        """
        Check for video content existance.
        """
        log.debug("check for video content existence with id %s" % video_id)
        if video_id is None:
            raise RestApiException("Please specify a video id",
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        input_parameters = self.get_input()
        content_type = input_parameters['type']
        if content_type is None or content_type not in self.__available_content_types__:
            raise RestApiException("Bad type parameter: expected one of %s." %
                                   (self.__available_content_types__, ),
                                   status_code=hcodes.HTTP_BAD_REQUEST)

        self.graph = self.get_service_instance('neo4j')
        video = None
        try:
            video = self.graph.AVEntity.nodes.get(uuid=video_id)
        except self.graph.AVEntity.DoesNotExist:
            log.debug("AVEntity with uuid %s does not exist" % video_id)
            raise RestApiException("Please specify a valid video id",
                                   status_code=hcodes.HTTP_BAD_NOTFOUND)

        item = video.item.single()
        headers = {}
        if content_type == 'video':
            if item.uri is None or not os.path.exists(item.uri):
                raise RestApiException("Video not found",
                                       status_code=hcodes.HTTP_BAD_NOTFOUND)
            headers['Content-Type'] = 'video/mp4'
        elif content_type == 'orf':
            orf_uri = os.path.dirname(item.uri) + '/orf.mp4'
            log.debug(orf_uri)
            if item.uri is None or not os.path.exists(orf_uri):
                raise RestApiException("Video ORF not found",
                                       status_code=hcodes.HTTP_BAD_NOTFOUND)
            headers['Content-Type'] = 'video/mp4'
        elif content_type == 'thumbnail':
            if item.thumbnail is None or not os.path.exists(item.thumbnail):
                raise RestApiException("Thumbnail not found",
                                       status_code=hcodes.HTTP_BAD_NOTFOUND)
            headers['Content-Type'] = 'image/jpeg'
        elif content_type == 'summary':
            if item.summary is None or not os.path.exists(item.summary):
                raise RestApiException("Summary not found",
                                       status_code=hcodes.HTTP_BAD_NOTFOUND)
            headers['Content-Type'] = 'image/jpeg'
        else:
            # it should never be reached
            raise RestApiException(
                "Invalid content type: {0}".format(content_type),
                status_code=hcodes.HTTP_NOT_IMPLEMENTED)
        return self.force_response([], headers=headers)
Exemplo n.º 25
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 self.neo4j_enabled:
            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,
            )

        user = self.auth.get_users(user_id)

        if user is None:
            raise RestApiException(
                "This user cannot be found or you are not authorized")

        user = user[0]

        current_user = self.get_current_user()
        is_authorized = self.check_permissions(current_user, user, is_admin,
                                               is_local_admin)
        if not is_authorized:
            raise RestApiException(
                "This user cannot be found or you are not authorized")

        if self.neo4j_enabled:
            user.delete()
        elif self.sql_enabled:
            self.auth.db.session.delete(user)
            self.auth.db.session.commit()
        elif self.mongo_enabled:
            user.delete()
        else:
            raise RestApiException(
                "Invalid auth backend, all known db are disabled")

        return self.empty_response()
Exemplo n.º 26
0
    def irodsuser_from_b2safe(self, user):

        if user.session is not None and len(user.session) > 0:
            log.debug("Validated B2SAFE user: %s" % user.uuid)
        else:
            msg = "Current credentials not registered inside B2SAFE"
            raise RestApiException(
                msg, status_code=hcodes.HTTP_BAD_UNAUTHORIZED)

        try:
            return self.get_service_instance(
                service_name='irods', user_session=user)
        except iexceptions.PAM_AUTH_PASSWORD_FAILED:
            msg = "PAM Authentication failed, invalid password or token"
            raise RestApiException(
                msg, status_code=hcodes.HTTP_BAD_UNAUTHORIZED)

        return None
Exemplo n.º 27
0
        def get(self, size: str) -> Response:

            # No type check... but it is only used from a very specific test...
            # So... who cares?? :-)
            if int(size) <= 0:
                raise RestApiException("Invalid size", status_code=416)

            # Just to prevent super giant responses
            return self.response("a" * min(int(size), 1_000_000))
Exemplo n.º 28
0
 def get(self, lang=None):
     """Get the controlled vocabulary."""
     log.debug('load the controlled vocabulary')
     try:
         f = open("../../scripts/convert-vocabulary/vocabulary.json", "r")
     except FileNotFoundError as err:
         log.warning('Vocabulary file not found')
         raise RestApiException("Warining: vocabulary not available",
                                status_code=hcodes.HTTP_BAD_NOTFOUND)
Exemplo n.º 29
0
    def verify_active_user(self, user):

        if user.is_active is None:
            log.warning("None value is_active")
        elif not user.is_active:
            # Beware, frontend leverages on this exact message,
            # do not modified it without fix also on frontend side
            raise RestApiException("Sorry, this account is not active",
                                   status_code=hcodes.HTTP_BAD_UNAUTHORIZED)
Exemplo n.º 30
0
    def delete(self, video_id):
        """
        Delete existing video description.
        """
        log.debug("deleting AVEntity id: %s", video_id)
        self.graph = self.get_service_instance('neo4j')

        if video_id is None:
            raise RestApiException("Please specify a valid video id",
                                   status_code=hcodes.HTTP_BAD_REQUEST)
        try:
            v = self.graph.AVEntity.nodes.get(uuid=video_id)
            repo = CreationRepository(self.graph)
            repo.delete_av_entity(v)
            return self.empty_response()
        except self.graph.AVEntity.DoesNotExist:
            log.debug("AVEntity with uuid %s does not exist" % video_id)
            raise RestApiException("Please specify a valid video id",
                                   status_code=hcodes.HTTP_BAD_NOTFOUND)