Skip to content

Commit

Permalink
Merge pull request #28 from bag-cnag/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Neah-Ko authored Nov 4, 2024
2 parents c301242 + dc652eb commit 3da5611
Show file tree
Hide file tree
Showing 40 changed files with 3,307 additions and 894 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
run: |
pylint -d W0221 $(git ls-files 'src/biodm/*.py') --exit-zero
# TODO: Debug
#  TODO: Debug
# - name: Build and cache integration test images
# uses: whoan/docker-build-with-cache-action@v5
# with:
Expand Down
21 changes: 20 additions & 1 deletion docs/developer_manual/advanced_use.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ a ``ResourceController``.
.. code-block:: python
:caption: s3controller.py
from biodm.routing import Route, PublicRoute
class S3Controller(ResourceController):
"""Controller for entities involving file management leveraging an S3Service."""
def _infer_svc(self) -> Type[S3Service]:
Expand All @@ -200,7 +202,7 @@ a ``ResourceController``.
prefix = f'{self.prefix}/{self.qp_id}/'
file_routes = [
Route(f'{prefix}download', self.download, methods=[HttpMethod.GET]),
Route(f'{prefix}post_success', self.post_success, methods=[HttpMethod.GET]),
PublicRoute(f'{prefix}post_success', self.post_success, methods=[HttpMethod.GET]),
...
]
# Set an extra attribute for later.
Expand Down Expand Up @@ -420,3 +422,20 @@ A lot of that code has to do with retrieving async SQLAlchemy objects attributes
# Generate a new form.
await self.gen_upload_form(file, session=session)
return file
.. _dev-routing:

Routing and Auth
----------------

As shown in the ``S3Controller`` example above, ``BioDM`` provides two
``Routes`` class: ``PublicRoute`` and ``Route``.

In case you are defining your own routes you should use those ones instead of
starlette's ``Route``.

Ultimately, this allows to use the config parameter ``REQUIRE_AUTH`` which when set to ``True``
will require authentication on all endpoints routed
with simple ``Routes`` while leaving endpoints marked with ``PublicRoute`` public.
This distinction can be important as in the example above, s3 bucket is **not** authenticated
when sending us a successful notice of file upload.
2 changes: 1 addition & 1 deletion docs/developer_manual/demo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ we will go over the following minimal example.
# Tables
class Dataset(bd.components.Versioned, bd.components.Base):
id = Column(Integer, primary_key=True, autoincrement=not 'sqlite' in config.DATABASE_URL)
id = Column(Integer, primary_key=True, autoincrement=not 'sqlite' in str(config.DATABASE_URL))
name : sao.Mapped[str] = sa.Column(sa.String(50), nullable=False)
description : sao.Mapped[str] = sa.Column(sa.String(500), nullable=False)
username_owner: sao.Mapped[int] = sa.Column(sa.ForeignKey("USER.username"), nullable=False)
Expand Down
31 changes: 31 additions & 0 deletions docs/developer_manual/permissions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ be provided in a ``.env`` file at the same level as your ``demo.py`` script.
KC_CLIENT_ID=
KC_CLIENT_SECRET=
Server level: REQUIRE_AUTH
--------------------------

Setting ``REQUIRE_AUTH=True`` config argument, will make all routes, except the ones explicitely
marked public (such as ``/login`` and ``/[resources/|]schemas)`` require authentication.


See more at :ref:`dev-routing`


Coarse: Static rule on a Controller endpoint
---------------------------------------------

Expand Down Expand Up @@ -158,6 +169,26 @@ collections. Sharing those permissions between intermediate level and lower leve
)
Self
~~~~

The term ``self`` is also supported in this configuration, it will bind those permissions
on the same resource.

.. code-block:: python
class Project(Base):
...
__permissions__ = (
Permission("self", read=True),
)
.. warning::

It shall raise an ``ImplementationError`` if used in conjunction with ``write``
as it does not makes sense to tie writing rights directly on a resource.


Strict composition
~~~~~~~~~~~~~~~~~~

Expand Down
26 changes: 24 additions & 2 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ Keycloak also needs a databse:
docker exec -u postgres biodm-pg createdb keycloak
Then you may start keycloak itself:
.. code-block:: bash
Expand All @@ -164,9 +163,32 @@ Once you've created the realm, create the client. Then
* **dev**: `http://*` and `https://*`
* **prod**: provide the url of the login callback `{SERVER_HOST}/syn_ack`.
Additionally, ``BioDM`` expects token to feature groups. For this, a client scope is necessary. Go to
* `Client Scopes` -> `Create Client Scope`
* Name: `groups`
* Protocol: `OpenID Connect`
* Type: `Default`
* Include in token scope: `On`
* Save
* `Client Scopes` -> `Groups` -> `Mappers` -> `Configure a new mapper` -> `Group membership`
* Name: `groups`
* token claim name: `groups`
* At least `Full group path` and `Add to access token`: `On`
* Save
* `Clients` -> `MyClient` -> `Client Scopes` -> `Add Client Scope` -> `Groups` -> `Add - Default`
Moreover, admin privileges are granted to users belonging to `admin` group.
It is recommended to create that group and at least one user in it,
if you want to create keycloak entities from the API for instance.
.. note::
Depending on your keycloak version or running instance `SERVER_HOST` may have to be appended with `/auth`.
Depending on your keycloak version or running instance `KC_HOST` may have to be appended with `/auth`.
Then you should provide the server with the `SECRET` field located in the
`Credentials` tab, that appears **after** you changed access type and the realm public key
Expand Down
21 changes: 12 additions & 9 deletions docs/user_manual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,11 @@ This triggers creation of a new row with a version increment.

.. note::

``PUT /release`` is the way of updating versioned resources.
The endpoint ``PUT /`` (a.k.a ``update``) will not be available for such resources, and
any attempt at updating by reference through ``POST /`` will raise an error.
``POST /release`` is the way of updating versioned resources.
The endpoint ``PUT /`` (a.k.a ``update``) is available, however it is meant to be used
in order to update nested objects and collections of that resource. Thus,
any attempt at updating a versioned resource through either ``PUT /`` or ``POST /``
shall raise an error.


**E.g.**
Expand Down Expand Up @@ -178,15 +180,16 @@ and followed by:
* Use ``nested.field=val`` to select on a nested attribute field
* Use ``*`` in a string attribute for wildcards

* ``field.op(value)``

* Currently only ``[lt, le, gt, ge]`` operators are supported for numerical values.
* numeric operators ``field.op([value])``

**e.g.**
* ``[lt, le, gt, ge]`` are supported with a value.

* ``[min, max]`` are supported without a value

.. note::

When querying with ``curl``, don't forget to escape ``&`` symbol or enclose the whole url in quotes, else your scripting language may intepret it as several commands.
When querying with ``curl``, don't forget to escape ``&`` symbol or enclose the whole url
in quotes, else your scripting language may intepret it as several commands.


Query a nested collection
Expand Down Expand Up @@ -366,6 +369,6 @@ otherwise.

- Passing a top level group will allow all descending children group for that verb/resource tuple.

- Permissions are taken into account if and only if keyclaok functionalities are enabled.
- Permissions are taken into account if and only if keycloak functionalities are enabled.

- Without keycloak, no token exchange -> No way of getting back protected data.
Loading

0 comments on commit 3da5611

Please sign in to comment.