Skip to content

Commit

Permalink
Create GET Roles endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
index-git committed Dec 21, 2023
1 parent 5072310 commit 7368fbe
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [GET](doc/rest.md#get-workspace-map)/[PATCH](doc/rest.md#patch-workspace-map) Workspace Map
- GET Workspace [Layers](doc/rest.md#get-workspace-layers)/[Maps](doc/rest.md#get-workspace-maps)
- GET [Layers](doc/rest.md#get-layers)/[Maps](doc/rest.md#get-maps)/[Publications](doc/rest.md#get-publications)
- [#165](https://github.com/LayerManager/layman/issues/165) New REST endpoint [GET Roles](doc/rest.md#get-roles) with list of all roles registered in [JDBC Role Service](https://docs.geoserver.org/2.21.x/en/user/security/usergrouprole/roleservices.html#jdbc-role-service).
- All changes from [v1.22.1](#v1221), [v1.22.2](#v1222) and [v1.22.3](#v1223).
- [#960](https://github.com/LayerManager/layman/issues/960) Handle WMS requests with HTTP error more efficiently in timgen.
- [#962](https://github.com/LayerManager/layman/issues/962) Make values of `layman_metadata.publication_status` and `status` key(s) more consistent in responses of PATCH Workspace [Layer](doc/rest.md#patch-workspace-layer)/[Map](doc/rest.md#patch-workspace-map) and GET Workspace [Layer](doc/rest.md#get-workspace-layer)/[Map](doc/rest.md#get-workspace-map).
Expand Down
16 changes: 16 additions & 0 deletions doc/rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
|Workspace Map Metadata Comparison|`/rest/workspaces/<workspace_name>/layers/<layername>/metadata-comparison`|[GET](#get-workspace-map-metadata-comparison) | x | x | x |
|Users|`/rest/users`|[GET](#get-users)| x | x | x |
|Current [User](models.md#user)|`/rest/current-user`|[GET](#get-current-user)| x | [PATCH](#patch-current-user) | [DELETE](#delete-current-user) |
|Roles|`/rest/roles`|[GET](#get-roles)| x | x | x |
|Version|`/rest/about/version`|[GET](#get-version)| x | x | x |

#### REST path parameters
Expand Down Expand Up @@ -850,6 +851,21 @@ Content-Type: `application/json`

HTTP status code 200 if credentials were deleted.

## Roles
### URL
`/rest/roles`

### GET Roles
Get list of roles.

#### Request.
No action parameters.

#### Response
Content-Type: `application/json`

JSON array of role names, where each role name is a `string`.

## Version
### URL
`/rest/about/version`
Expand Down
2 changes: 2 additions & 0 deletions src/layman/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@
from .user.rest_current_user import bp as current_user_bp
from .geoserver_proxy import bp as geoserver_proxy_bp
from .user.rest_users import bp as users_bp
from .user.rest_roles import bp as roles_bp

app.register_blueprint(current_user_bp, url_prefix='/rest/current-user')
app.register_blueprint(geoserver_proxy_bp, url_prefix='/geoserver')
app.register_blueprint(users_bp, url_prefix=f'/rest/{settings.REST_USERS_PREFIX}')
app.register_blueprint(roles_bp, url_prefix=f'/rest/{settings.REST_ROLES_PREFIX}')

logger.info(f"IN_CELERY_WORKER_PROCESS={IN_CELERY_WORKER_PROCESS}")
logger.info(f"IN_PYTEST_PROCESS={IN_PYTEST_PROCESS}")
Expand Down
16 changes: 16 additions & 0 deletions src/layman/authz/role_service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import logging

from db import util as db_util
from layman import settings

logger = logging.getLogger(__name__)

ROLE_NAME_PATTERN = r'^(?!.{65,})[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$'


Expand All @@ -22,3 +26,15 @@ def get_existent_roles(roles_to_check):
"""
rows = db_util.run_query(query, (list(roles_to_check),), uri_str=settings.LAYMAN_ROLE_SERVICE_URI)
return {row[0] for row in rows}


def get_all_roles():
query = f"""
select name
from {settings.LAYMAN_ROLE_SERVICE_SCHEMA}.roles
where name not in (%s, %s, %s)
and LEFT(name, 5) != 'USER_'
and name ~ %s
"""
roles = db_util.run_query(query, ('ADMIN', 'GROUP_ADMIN', settings.LAYMAN_GS_ROLE, ROLE_NAME_PATTERN), uri_str=settings.LAYMAN_ROLE_SERVICE_URI)
return [role[0] for role in roles] + [settings.RIGHTS_EVERYONE_ROLE]
17 changes: 17 additions & 0 deletions src/layman/user/rest_roles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import logging
from flask import current_app as app, Blueprint, jsonify

from layman.authz.role_service import get_all_roles

logger = logging.getLogger(__name__)

bp = Blueprint('rest_roles', __name__)


@bp.route('', methods=['GET'])
def get():
app.logger.info(f"GET Roles")

roles = get_all_roles()

return jsonify(roles), 200
1 change: 1 addition & 0 deletions src/layman_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ class EnumWfsWmsStatus(Enum):
micka.set_settings(DEFAULT_CONNECTION_TIMEOUT)

REST_USERS_PREFIX = 'users'
REST_ROLES_PREFIX = 'roles'
REST_WORKSPACES_PREFIX = 'workspaces'
REST_PUBLICATIONS_PREFIX = 'publications'
RESERVED_WORKSPACE_NAMES = {REST_USERS_PREFIX, REST_WORKSPACES_PREFIX}
Expand Down
Empty file.
30 changes: 30 additions & 0 deletions tests/dynamic_data/users_roles/test_roles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import requests
import pytest

from layman import app, settings
from test_tools import role_service
from test_tools.util import url_for


@pytest.mark.usefixtures('ensure_layman')
def test_get_roles():
rolename = 'TEST_GET_ROLES_ROLE'

with app.app_context():
# roles.GET
url = url_for('rest_roles.get')
assert url.endswith('/' + settings.REST_ROLES_PREFIX)

# Without role
response = requests.get(url, timeout=settings.DEFAULT_CONNECTION_TIMEOUT)
assert response.status_code == 200, response.json()
assert response.json() == [settings.RIGHTS_EVERYONE_ROLE]

# With role
with app.app_context():
role_service.ensure_role(rolename)
response = requests.get(url, timeout=settings.DEFAULT_CONNECTION_TIMEOUT)
assert response.status_code == 200, response.json()
assert response.json() == [rolename, settings.RIGHTS_EVERYONE_ROLE]

role_service.delete_role(rolename)

0 comments on commit 7368fbe

Please sign in to comment.