Skip to content

Commit

Permalink
create new user
Browse files Browse the repository at this point in the history
  • Loading branch information
wbaccinelli committed Feb 26, 2024
1 parent 27fa0db commit a489cf6
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 180 deletions.
Expand Up @@ -48,7 +48,6 @@
from vantage6.algorithm.store import db

# TODO move server imports to common / refactor
from vantage6.algorithm.store.resource.schema.output_schema import HATEOASModelSchema
from vantage6.algorithm.store.permission import PermissionManager
from vantage6.algorithm.store.globals import (
RESOURCES,
Expand Down Expand Up @@ -250,8 +249,8 @@ def load_resources(self) -> None:
# make use of 'em.
services = {
"api": self.api,
# "permissions": self.permissions,
"config": self.ctx.config,
"permissions": self.permissions,
}

for res in RESOURCES:
Expand Down
17 changes: 17 additions & 0 deletions vantage6-algorithm-store/vantage6/algorithm/store/model/user.py
Expand Up @@ -131,3 +131,20 @@ def get_by_username(cls, username: str) -> User:
result = session.query(cls).filter_by(username=username).one()
session.commit()
return result

@classmethod
def username_exists(cls, username) -> bool:
"""
Check if a user with the given username exists
Parameters
----------
username: str
Username to check
Returns
-------
bool
Whether or not a user with the given username exists
"""
return cls.exists(field="username", value=username)
64 changes: 41 additions & 23 deletions vantage6-algorithm-store/vantage6/algorithm/store/permission.py
Expand Up @@ -77,7 +77,6 @@ def add(self, operation: Operation) -> None:
permission = Permission(RuleNeed(self.name, operation))
self.__setattr__(f'{operation}', permission)


def _id_in_list(self, id_: int, resource_list: list[Base]) -> bool:
"""
Check if resource list contains a resource with a certain ID
Expand All @@ -96,6 +95,27 @@ def _id_in_list(self, id_: int, resource_list: list[Base]) -> bool:
"""
return any(r.id == id_ for r in resource_list)

def has_permission(self, operation: Operation) -> bool:
"""
Check if the user has the permission fo a certain operation
Parameters
----------
operation: Operation
Operation to check
Returns
-------
bool
True if the entity has at least the scope, False otherwise
"""
perm = getattr(self, f"{operation}", None)

if perm and perm.can():
return True

return False


class PermissionManager:
"""
Expand Down Expand Up @@ -294,25 +314,23 @@ def rule_exists_in_db(name: str,
session.commit()
return result

# def check_user_rules(self, rules: list[Rule]) -> dict | None:
# """
# Check if a user, node or container has all the `rules` in a list
#
# Parameters
# ----------
# rules: list[:class:`~vantage6.server.model.rule.Rule`]
# List of rules that user is checked to have
#
# Returns
# -------
# dict | None
# Dict with a message which rule is missing, else None
# """
# for rule in rules:
# if not self.collections[rule.name].has_at_least_scope(
# rule.scope, rule.operation
# ):
# return {"msg": f"You don't have the rule ({rule.name}, "
# f"{print_scope(rule.scope)}, "
# f"{print_operation(rule.operation)})"}
# return None
def check_user_rules(self, rules: list[Rule]) -> dict | None:
"""
Check if a user has all the `rules` in a list
Parameters
----------
rules: list[:class:`~vantage6.algorithm.store.model.rule.Rule`]
List of rules that user is checked to have
Returns
-------
dict | None
Dict with a message which rule is missing, else None
"""
for rule in rules:

if not self.collections[rule.name].has_permission(rule.operation):
return {"msg": f"You don't have the rule ({rule.name}, "
f"{print_operation(rule.operation)})"}
return None
Expand Up @@ -3,12 +3,16 @@
import requests
from functools import wraps
from http import HTTPStatus
from flask import request
from flask import request, current_app
from flask_principal import Identity, identity_changed
from flask_restful import Api

from vantage6.algorithm.store import PermissionManager
from vantage6.algorithm.store.model.rule import Operation
from vantage6.common import logger_name
from vantage6.algorithm.store.model.vantage6_server import Vantage6Server
from vantage6.algorithm.store.model.user import User
from vantage6.algorithm.store.permission import RuleNeed
from vantage6.backend.common.services_resources import BaseServicesResources

log = logging.getLogger(logger_name(__name__))
Expand All @@ -26,6 +30,15 @@ class AlgorithmStoreResources(BaseServicesResources):
Configuration dictionary
"""

def __init__(
self,
api: Api,
config: dict,
permissions: PermissionManager,
):
super().__init__(api, config)
self.permissions = permissions

# TODO implement this class when necessary
# TODO move this class elsewhere?

Expand Down Expand Up @@ -122,7 +135,7 @@ def decorator(*args, **kwargs):

def with_permission(resource: str, operation: Operation) -> callable:
"""
Decorator to verify that the user has view permission on a resource.
Decorator to verify that the user has as a permission on a resource.
Parameters
----------
resource : str
Expand Down Expand Up @@ -165,9 +178,23 @@ def decorator(*args, **kwargs):
log.warning(msg)
return {"msg": msg}, HTTPStatus.UNAUTHORIZED

flag = user.can(resource, operation)
# if the user is registered, load the rules
auth_identity = Identity(user_id)

for role in user.roles:
for rule in role.rules:
auth_identity.provides.add(
RuleNeed(
name=rule.name,
operation=rule.operation,
)
)

identity_changed.send(
current_app._get_current_object(), identity=auth_identity
)

if not flag:
if not user.can(resource, operation):
msg = f"This user is not allowed to perform this operation"

log.warning(msg)
Expand Down
Expand Up @@ -95,7 +95,7 @@ class UserInputSchema(Schema):

id_server = fields.Integer(validate=Range(min=1))
roles = fields.List(fields.Integer(validate=Range(min=1)))
rules = fields.List(fields.Integer(validate=Range(min=1)))
username = fields.String()


class Vantage6ServerInputSchema(Schema):
Expand Down

0 comments on commit a489cf6

Please sign in to comment.