Skip to content

Commit

Permalink
Files refactor to include repositories logic (#1560)
Browse files Browse the repository at this point in the history
* remove unneeded provider methods

* create access policies file

* refactor get_functions repository method

* refactor groups and repositories

* repository refactor from files

* fix some linter problems

* fixed a bug when the user retrieves a function

* fix lint

* refactor of get_function method

* remove artifact test file

* remove programs access policies

* refactor programs references to functions

* group repository refactor

* rename groups repository into user repository

* simplified get_function methods

* fix query

* adapt get_functions methods

* updated comments

* create path if doesn't exist

* remove some unused code

* fix files client

* fix typos

* fixed the creation of the directory

* added a test for the provider end-points

* fix some typos from the provider end-points

* fix black on tests
  • Loading branch information
Tansito authored Dec 26, 2024
1 parent f3b8de9 commit f50a7f9
Show file tree
Hide file tree
Showing 13 changed files with 497 additions and 420 deletions.
24 changes: 10 additions & 14 deletions client/qiskit_serverless/core/clients/serverless_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,25 +426,21 @@ def provider_file_download(
file, download_location, function, target_name
)

def file_delete(
self, file: str, function: QiskitFunction, provider: Optional[str] = None
):
"""Deletes file uploaded or produced by the programs,"""
return self._files_client.delete(file, function, provider)
def file_delete(self, file: str, function: QiskitFunction):
"""Deletes file uploaded or produced by the Qiskit function"""
return self._files_client.delete(file, function)

def provider_file_delete(self, file: str, function: QiskitFunction, provider: str):
"""Deletes file uploaded or produced by the programs,"""
return self._files_client.provider_delete(file, function, provider)
def provider_file_delete(self, file: str, function: QiskitFunction):
"""Deletes file uploaded or produced by the Qiskit Function"""
return self._files_client.provider_delete(file, function)

def file_upload(
self, file: str, function: QiskitFunction, provider: Optional[str] = None
):
def file_upload(self, file: str, function: QiskitFunction):
"""Upload file."""
return self._files_client.upload(file, function, provider)
return self._files_client.upload(file, function)

def provider_file_upload(self, file: str, function: QiskitFunction, provider: str):
def provider_file_upload(self, file: str, function: QiskitFunction):
"""Upload file."""
return self._files_client.provider_upload(file, function, provider)
return self._files_client.provider_upload(file, function)


class IBMServerlessClient(ServerlessClient):
Expand Down
38 changes: 18 additions & 20 deletions client/qiskit_serverless/core/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,13 @@ def provider_download(
)

@_trace
def upload(
self, file: str, function: QiskitFunction, provider: Optional[str] = None
) -> Optional[str]:
def upload(self, file: str, function: QiskitFunction) -> Optional[str]:
"""Uploads file."""
with open(file, "rb") as f:
with requests.post(
os.path.join(self._files_url, "upload/"),
files={"file": f},
params={"provider": provider, "function": function.title},
params={"provider": function.provider, "function": function.title},
stream=True,
headers={"Authorization": f"Bearer {self._token}"},
timeout=REQUESTS_STREAMING_TIMEOUT,
Expand All @@ -151,15 +149,16 @@ def upload(
return "Can not open file"

@_trace
def provider_upload(
self, file: str, function: QiskitFunction, provider: str
) -> Optional[str]:
def provider_upload(self, file: str, function: QiskitFunction) -> Optional[str]:
"""Uploads file to provider/function file storage."""
if not function.provider:
raise QiskitServerlessException("`function` doesn't have a provider.")

with open(file, "rb") as f:
with requests.post(
os.path.join(self._files_url, "upload/"),
os.path.join(self._files_url, "provider", "upload/"),
files={"file": f},
params={"provider": provider, "function": function.title},
params={"provider": function.provider, "function": function.title},
stream=True,
headers={"Authorization": f"Bearer {self._token}"},
timeout=REQUESTS_STREAMING_TIMEOUT,
Expand All @@ -175,7 +174,7 @@ def list(self, function: QiskitFunction) -> List[str]:
response_data = safe_json_request_as_dict(
request=lambda: requests.get(
self._files_url,
params={"function": function.title},
params={"function": function.title, "provider": function.provider},
headers={"Authorization": f"Bearer {self._token}"},
timeout=REQUESTS_TIMEOUT,
)
Expand All @@ -191,25 +190,23 @@ def provider_list(self, function: QiskitFunction) -> List[str]:
response_data = safe_json_request_as_dict(
request=lambda: requests.get(
os.path.join(self._files_url, "provider"),
params={"provider": function.provider, "function": function.title},
params={"function": function.title, "provider": function.provider},
headers={"Authorization": f"Bearer {self._token}"},
timeout=REQUESTS_TIMEOUT,
)
)
return response_data.get("results", [])

@_trace
def delete(
self, file: str, function: QiskitFunction, provider: Optional[str] = None
) -> Optional[str]:
def delete(self, file: str, function: QiskitFunction) -> Optional[str]:
"""Deletes file uploaded or produced by the programs,"""
response_data = safe_json_request_as_dict(
request=lambda: requests.delete(
os.path.join(self._files_url, "delete"),
params={
"file": file,
"function": function.title,
"provider": provider,
"provider": function.provider,
},
headers={
"Authorization": f"Bearer {self._token}",
Expand All @@ -221,17 +218,18 @@ def delete(
return response_data.get("message", "")

@_trace
def provider_delete(
self, file: str, function: QiskitFunction, provider: str
) -> Optional[str]:
"""Deletes file uploaded or produced by the programs,"""
def provider_delete(self, file: str, function: QiskitFunction) -> Optional[str]:
"""Deletes a file uploaded or produced by the Qiskit Functions"""
if not function.provider:
raise QiskitServerlessException("`function` doesn't have a provider.")

response_data = safe_json_request_as_dict(
request=lambda: requests.delete(
os.path.join(self._files_url, "provider", "delete"),
params={
"file": file,
"function": function.title,
"provider": provider,
"provider": function.provider,
},
headers={
"Authorization": f"Bearer {self._token}",
Expand Down
Empty file.
38 changes: 38 additions & 0 deletions gateway/api/access_policies/providers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""
Access policies implementation for Provider access
"""
import logging

from api.models import Provider


logger = logging.getLogger("gateway")


class ProviderAccessPolicy: # pylint: disable=too-few-public-methods
"""
The main objective of this class is to manage the access for the user
to the Provider entities.
"""

@staticmethod
def can_access(user, provider: Provider) -> bool:
"""
Checks if the user has access to a Provider:
Args:
user: Django user from the request
provider: Provider instance against to check the access
Returns:
bool: True or False in case the user has access
"""

user_groups = user.groups.all()
admin_groups = provider.admin_groups.all()
has_access = any(group in admin_groups for group in user_groups)
if not has_access:
logger.warning(
"User [%s] has no access to provider [%s].", user.id, provider.name
)
return has_access
Loading

0 comments on commit f50a7f9

Please sign in to comment.