Example #1
0
def test_it_should_be_impossible_to_create_restriction_with_end_time_happening_before_start_time(tables):
    start_time = datetime.utcnow() + timedelta(hours=5)
    end_time = datetime.utcnow() + timedelta(minutes=1)
    restriction = Restriction(name='Test', starts_at=start_time, ends_at=end_time, is_global=False)

    with pytest.raises(AssertionError):
        restriction.save()
Example #2
0
    def _check_restrictions(cls):
        # If there are already users in the DB, don't bother
        if User.query.count() > 0:
            return

        if Restriction.query.count() == 0:
            if click.confirm(
                    orange('There are no permissions specified') +
                    ' - that means, that by default '
                    'users will not have access to any resources. Would you like to create '
                    'a default permission together with a default group now? (All users '
                    'would have access to every resource)',
                    default=True):
                default_group = Group(name='users')
                default_group._is_default = True
                default_group.save()

                default_restriction = Restriction(
                    name='can always use everything',
                    starts_at=datetime.utcnow(),
                    is_global=True)
                default_restriction.apply_to_group(default_group)

                click.echo(
                    green(
                        'Created a default group: {} and a permission "{}" '.
                        format(default_group.name, default_restriction.name) +
                        'allowing access to every resource '
                        'at any time.'))
            else:
                click.echo(
                    orange(
                        '[•] OK - not creating any permissions. Remember that you need to define permissions'
                        ' in order for users to be able to access the resources.'
                    ))
Example #3
0
def create(restriction: Dict[str, Any]) -> Tuple[Content, HttpStatusCode]:
    try:
        new_restriction = Restriction(name=restriction.get('name'),
                                      starts_at=restriction['startsAt'],
                                      is_global=restriction['isGlobal'],
                                      ends_at=DateUtils.try_parse_string(
                                          restriction.get('endsAt')))
        new_restriction.save()
    except AssertionError as e:
        content = {
            'msg': RESTRICTION['create']['failure']['invalid'].format(reason=e)
        }
        status = HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        content = {'msg': GENERAL['internal_error'] + str(e)}
        status = HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content = {
            'msg':
            RESTRICTION['create']['success'],
            'restriction':
            new_restriction.as_dict(include_groups=True,
                                    include_users=True,
                                    include_resources=True)
        }
        status = HTTPStatus.CREATED.value
    finally:
        return content, status
Example #4
0
def test_it_should_be_impossible_to_create_or_edit_restriction_that_already_expired(tables):
    start_time = datetime.utcnow() - timedelta(hours=5)
    end_time = start_time + timedelta(hours=1)
    restriction = Restriction(name='Test', starts_at=start_time, ends_at=end_time, is_global=False)

    with pytest.raises(AssertionError):
        restriction.save()
Example #5
0
def test_restriction_creation(tables):
    starts_at = datetime.utcnow() + timedelta(minutes=5)
    duration = timedelta(hours=12)
    new_restriction = Restriction(name='TestRestriction', starts_at=starts_at,
                                  ends_at=starts_at + duration, is_global=False)
    new_restriction.save()

    assert new_restriction.id is not None
Example #6
0
def test_get_global_restrictions_returns_them(tables):
    starts_at = datetime.utcnow() + timedelta(minutes=5)
    duration = timedelta(hours=12)
    new_restriction = Restriction(name='TestRestriction', starts_at=starts_at,
                                  ends_at=starts_at + duration, is_global=True)
    new_restriction.save()

    assert new_restriction in Restriction.get_global_restrictions()
Example #7
0
def restriction():
    start_time = datetime.datetime.utcnow() + timedelta(minutes=5)
    end_time = start_time + timedelta(hours=8)
    restriction = Restriction(name='TestRestriction',
                              starts_at=start_time,
                              ends_at=end_time,
                              is_global=False)
    restriction.save()
    return restriction
Example #8
0
def test_delete_restriction(tables, client, restriction, new_user):
    new_user.save()
    restriction.apply_to_user(new_user)

    resp = client.delete(ENDPOINT + '/' + str(restriction.id), headers=HEADERS)

    assert resp.status_code == HTTPStatus.OK
    assert restriction not in new_user.get_restrictions()
    with pytest.raises(NoResultFound):
        Restriction.get(restriction.id)
Example #9
0
def test_get_all_restrictions_with_data(tables, client):
    # Create new restriction and save it to the DB
    start_time = datetime.datetime.utcnow() + datetime.timedelta(minutes=5)
    end_time = start_time + datetime.timedelta(hours=8)
    restriction = Restriction(name='TestRestriction', starts_at=start_time, ends_at=end_time, is_global=False)
    restriction.save()

    resp = client.get(ENDPOINT, headers=HEADERS)
    resp_json = json.loads(resp.data.decode('utf-8'))

    assert resp.status_code == HTTPStatus.OK
    assert len(resp_json) == 1
Example #10
0
def delete(id: RestrictionId) -> Tuple[Content, HttpStatusCode]:
    try:
        restriction_to_destroy = Restriction.get(id)
        users = restriction_to_destroy.get_all_affected_users()
        restriction_to_destroy.destroy()
        for user in users:
            ReservationVerifier.update_user_reservations_statuses(
                user, have_users_permissions_increased=False)
    except AssertionError as error_message:
        content, status = {
            'msg': str(error_message)
        }, HTTPStatus.FORBIDDEN.value
    except NoResultFound:
        content, status = {
            'msg': RESTRICTION['not_found']
        }, HTTPStatus.NOT_FOUND.value
    except Exception as e:
        content, status = {
            'msg': GENERAL['internal_error'] + str(e)
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {
            'msg': RESTRICTION['delete']['success']
        }, HTTPStatus.OK.value
    finally:
        return content, status
Example #11
0
def get_all() -> Tuple[List[Any], HttpStatusCode]:
    return [
        restriction.as_dict(include_groups=True,
                            include_users=True,
                            include_resources=True)
        for restriction in Restriction.all()
    ], HTTPStatus.OK.value
Example #12
0
def test_restriction_without_schedules_is_active_only_when_between_start_and_end_dates(tables):
    start_time = datetime.utcnow() - timedelta(hours=5)
    end_time = datetime.utcnow() + timedelta(hours=5)
    active_restriction = Restriction(name='ActiveRestriction', starts_at=start_time, ends_at=end_time, is_global=False)
    active_restriction.save()

    start_time = datetime.utcnow() + timedelta(hours=1)
    inactive_restriction = Restriction(name='InactiveRestriction', starts_at=start_time, ends_at=end_time,
                                       is_global=False)
    inactive_restriction.save()

    assert active_restriction.is_active is True
    assert inactive_restriction.is_active is False
Example #13
0
def test_restriction_with_schedules_is_active_only_when_at_least_one_of_its_schedules_is_active(tables,
                                                                                                active_schedule,
                                                                                                inactive_schedule):
    start_time = datetime.utcnow() - timedelta(hours=5)
    end_time = datetime.utcnow() + timedelta(hours=5)
    restriction = Restriction(name='ActiveRestriction', starts_at=start_time, ends_at=end_time, is_global=False)
    restriction.save()

    restriction.add_schedule(inactive_schedule)
    assert restriction.is_active is False

    restriction.add_schedule(active_schedule)
    assert restriction.is_active is True
Example #14
0
def test_create_indefinte_retriction(tables, client):
    data = {
        'name': 'Test restriction',
        'startsAt': '2100-01-01T10:00:00.000Z',
        'isGlobal': False
    }
    resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data))
    resp_json = json.loads(resp.data.decode('utf-8'))

    assert resp.status_code == HTTPStatus.CREATED
    assert Restriction.get(resp_json['restriction']['id']) is not None
Example #15
0
    def get_active_restrictions(self, include_global=True):
        """
        :param include_global: If set to true will also include global restrictions (which apply to all resources)
        :return: Active restrictions (according to start/end times and schedules) assigned to given entity.
        """
        from tensorhive.models.Restriction import Restriction

        restrictions = super(Resource, self).get_active_restrictions()
        if include_global:
            restrictions = list(
                set(restrictions + Restriction.get_global_restrictions(
                    include_expired=False)))
        return restrictions
Example #16
0
def test_restriction_with_dates_passed_as_string_gets_added_successfully(tables):
    new_restriction = Restriction(
        name='TestRestriction',
        is_global=False
    )
    new_restriction.starts_at = '2020-09-29T18:07:44.191Z'
    new_restriction.ends_at = '2120-09-30T18:07:44.191Z'
    new_restriction.save()
Example #17
0
    def get_restrictions(self, include_expired=False, include_global=True):
        """
        :param include_expired: If set to true will also return restrictions that have already expired.
        :param include_global: If set to true will also include global restrictions (which apply to all resources)
        :return: Restrictions assigned to given resource.
        """
        from tensorhive.models.Restriction import Restriction

        restrictions = super(Resource, self).get_restrictions(include_expired)
        if include_global:
            restrictions = list(
                set(restrictions + Restriction.get_global_restrictions(
                    include_expired=include_expired)))
        return restrictions
Example #18
0
def permissive_restriction(new_user):
    start_time = datetime.datetime.utcnow() - timedelta(days=10)
    end_time = None
    restriction = Restriction(name='PermissiveRestriction',
                              starts_at=start_time,
                              ends_at=end_time,
                              is_global=True)
    restriction.apply_to_user(new_user)
    restriction.save()
    return restriction
Example #19
0
def test_update_restriction_incorrect_data(tables, client, restriction):
    old_start_date = restriction.starts_at
    old_end_date = restriction.ends_at
    data = {
        'startsAt':
        '2200-01-01T10:00:00.000Z',  # start date is after the end date, this request shouldn't be accepted
        'endsAt': '2199-02-01T10:00:00.000Z',
    }
    resp = client.put(ENDPOINT + '/' + str(restriction.id),
                      headers=HEADERS,
                      data=json.dumps(data))

    db_session.remove(
    )  # make sure we'll get the restriction from the DB, and not from memory
    restriction = Restriction.get(restriction.id)
    assert resp.status_code == HTTPStatus.UNPROCESSABLE_ENTITY
    assert restriction.starts_at == old_start_date
    assert restriction.ends_at == old_end_date
Example #20
0
def add_schedule(restriction_id: RestrictionId,
                 schedule_id: ScheduleId) -> Tuple[Content, HttpStatusCode]:
    restriction = None
    try:
        restriction = Restriction.get(restriction_id)
        schedule = RestrictionSchedule.get(schedule_id)
        restriction.add_schedule(schedule)
        have_users_permissions_increased = len(
            restriction.schedules) > 1  # if added another schedule
        for user in restriction.get_all_affected_users():
            ReservationVerifier.update_user_reservations_statuses(
                user, have_users_permissions_increased)
    except NoResultFound:
        if restriction is None:
            content, status = {
                'msg': RESTRICTION['not_found']
            }, HTTPStatus.NOT_FOUND.value
        else:
            content, status = {
                'msg': SCHEDULE['not_found']
            }, HTTPStatus.NOT_FOUND.value
    except InvalidRequestException:
        content, status = {
            'msg': RESTRICTION['schedules']['add']['failure']['duplicate']
        }, HTTPStatus.CONFLICT.value
    except AssertionError as e:
        content, status = {'msg': RESTRICTION['schedules']['add']['failure']['assertions'].format(reason=e)}, \
            HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        log.critical(e)
        content, status = {
            'msg': GENERAL['internal_error']
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {
            'msg':
            RESTRICTION['schedules']['add']['success'],
            'restriction':
            restriction.as_dict(include_groups=True,
                                include_users=True,
                                include_resources=True)
        }, HTTPStatus.OK.value
    finally:
        return content, status
Example #21
0
def update(id: RestrictionId,
           newValues: Dict[str, Any]) -> Tuple[Content, HttpStatusCode]:
    new_values = newValues
    allowed_fields = {'name', 'startsAt', 'endsAt', 'isGlobal'}
    try:
        assert set(new_values.keys()).issubset(
            allowed_fields), 'invalid field is present'
        restriction = Restriction.get(id)

        for field_name, new_value in new_values.items():
            field_name = snakecase(field_name)
            assert (field_name is not None) and hasattr(restriction, field_name), \
                'restriction has no {} field'.format(field_name)
            setattr(restriction, field_name, new_value)
        restriction.save()
        for user in restriction.get_all_affected_users():
            ReservationVerifier.update_user_reservations_statuses(
                user, have_users_permissions_increased=True)
            ReservationVerifier.update_user_reservations_statuses(
                user, have_users_permissions_increased=False)
    except NoResultFound:
        content, status = {
            'msg': RESTRICTION['not_found']
        }, HTTPStatus.NOT_FOUND.value
    except AssertionError as e:
        content, status = {'msg': RESTRICTION['update']['failure']['assertions'].format(reason=e)}, \
            HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        log.critical(e)
        content, status = {
            'msg': GENERAL['internal_error']
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {
            'msg':
            RESTRICTION['update']['success'],
            'restriction':
            restriction.as_dict(include_groups=True,
                                include_users=True,
                                include_resources=True)
        }, HTTPStatus.OK.value
    finally:
        return content, status
Example #22
0
def remove_from_group(restriction_id: RestrictionId,
                      group_id: GroupId) -> Tuple[Content, HttpStatusCode]:
    restriction = None
    try:
        restriction = Restriction.get(restriction_id)
        group = Group.get(group_id)
        restriction.remove_from_group(group)
        for user in group.users:
            ReservationVerifier.update_user_reservations_statuses(
                user, have_users_permissions_increased=False)
    except NoResultFound:
        if restriction is None:
            content, status = {
                'msg': RESTRICTION['not_found']
            }, HTTPStatus.NOT_FOUND.value
        else:
            content, status = {
                'msg': GENERAL['not_found']
            }, HTTPStatus.NOT_FOUND.value
    except InvalidRequestException:
        content, status = {
            'msg': RESTRICTION['groups']['remove']['failure']['not_found']
        }, HTTPStatus.NOT_FOUND.value
    except AssertionError as e:
        content, status = {'msg': RESTRICTION['groups']['remove']['failure']['assertions'].format(reason=e)}, \
            HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        log.critical(e)
        content, status = {
            'msg': GENERAL['internal_error']
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {
            'msg':
            RESTRICTION['groups']['remove']['success'],
            'restriction':
            restriction.as_dict(include_groups=True,
                                include_users=True,
                                include_resources=True)
        }, HTTPStatus.OK.value
    finally:
        return content, status
Example #23
0
def remove_from_resources_by_hostname(
        restriction_id: RestrictionId,
        hostname: str) -> Tuple[Content, HttpStatusCode]:
    restriction = None
    try:
        restriction = Restriction.get(restriction_id)
        resources = Resource.get_by_hostname(hostname)
        if resources:
            restriction.remove_from_resources(resources)
            for user in restriction.get_all_affected_users():
                ReservationVerifier.update_user_reservations_statuses(
                    user, have_users_permissions_increased=False)
        else:
            raise NoResultFound
    except NoResultFound:
        if restriction is None:
            content, status = {
                'msg': RESTRICTION['not_found']
            }, HTTPStatus.NOT_FOUND.value
        else:
            content, status = {
                'msg': NODES['hostname']['not_found']
            }, HTTPStatus.NOT_FOUND.value
    except AssertionError as e:
        content, status = {'msg': RESTRICTION['hosts']['remove']['failure']['assertions'].format(reason=e)}, \
            HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        log.critical(e)
        content, status = {
            'msg': GENERAL['internal_error']
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {
            'msg':
            RESTRICTION['hosts']['remove']['success'],
            'restriction':
            restriction.as_dict(include_groups=True,
                                include_users=True,
                                include_resources=True)
        }, HTTPStatus.OK.value
    finally:
        return content, status
Example #24
0
def apply_to_user(restriction_id: RestrictionId,
                  user_id: UserId) -> Tuple[Content, HttpStatusCode]:
    restriction = None
    try:
        restriction = Restriction.get(restriction_id)
        user = User.get(user_id)
        restriction.apply_to_user(user)
        ReservationVerifier.update_user_reservations_statuses(
            user, have_users_permissions_increased=True)
    except NoResultFound:
        if restriction is None:
            content, status = {
                'msg': RESTRICTION['not_found']
            }, HTTPStatus.NOT_FOUND.value
        else:
            content, status = {
                'msg': USER['not_found']
            }, HTTPStatus.NOT_FOUND.value
    except InvalidRequestException:
        content, status = {
            'msg': RESTRICTION['users']['apply']['failure']['duplicate']
        }, HTTPStatus.CONFLICT.value
    except AssertionError as e:
        content, status = {'msg': RESTRICTION['users']['apply']['failure']['assertions'].format(reason=e)}, \
            HTTPStatus.UNPROCESSABLE_ENTITY.value
    except Exception as e:
        log.critical(e)
        content, status = {
            'msg': GENERAL['internal_error']
        }, HTTPStatus.INTERNAL_SERVER_ERROR.value
    else:
        content, status = {
            'msg':
            RESTRICTION['users']['apply']['success'],
            'restriction':
            restriction.as_dict(include_groups=True,
                                include_users=True,
                                include_resources=True)
        }, HTTPStatus.OK.value
    finally:
        return content, status
Example #25
0
def test_indefinite_restriction_creation(tables):
    starts_at = datetime.utcnow() + timedelta(minutes=5)
    new_restriction = Restriction(name='TestRestriction', starts_at=starts_at, is_global=False)
    new_restriction.save()

    assert new_restriction.id is not None
def test_create_reservation_that_is_covered_by_two_separate_restrictions(
        tables, client, new_user):
    r1_start = '2101-01-01T00:00:00.000Z'
    r1_end = '2101-01-02T00:00:00.000Z'
    r2_start = '2101-01-02T00:00:00.000Z'
    r2_end = '2101-01-02T23:59:00.000Z'

    r1 = Restriction(name='FirstRestriction',
                     starts_at=r1_start,
                     ends_at=r1_end,
                     is_global=False)
    r2 = Restriction(name='SecondRestriction',
                     starts_at=r2_start,
                     ends_at=r2_end,
                     is_global=False)

    new_user.save()
    r1.apply_to_user(new_user)
    r2.apply_to_user(new_user)

    resource = Resource(id='0123456789012345678901234567890123456789')
    resource.save()
    r1.apply_to_resource(resource)
    r2.apply_to_resource(resource)

    data = {
        'title': 'Test reservation',
        'description': 'Test reservation',
        'resourceId': '0123456789012345678901234567890123456789',
        'userId': new_user.id,
        'start': '2101-01-01T10:00:00.000Z',
        'end': '2101-01-02T12:00:00.000Z'
    }
    resp = client.post(ENDPOINT, headers=HEADERS, data=json.dumps(data))
    resp_json = json.loads(resp.data.decode('utf-8'))

    assert resp.status_code == HTTPStatus.CREATED
    assert Reservation.get(resp_json['reservation']['id']) is not None