Skip to content

Commit

Permalink
[Backend] Make New Users Viewers By Default [#2866] (#2900)
Browse files Browse the repository at this point in the history
  • Loading branch information
pattisdr authored Mar 24, 2023
1 parent da065f8 commit 9082c94
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ The types of changes are:
* Deprecated adding scopes to users directly; you can only add roles. [#2848](https://github.com/ethyca/fides/pull/2848/files)
* Changed About Fides page to say "Fides Core Version:" over "Version". [#2899](https://github.com/ethyca/fides/pull/2899)
* Polish Admin UI header & navigation [#2897](https://github.com/ethyca/fides/pull/2897)
* Give new users a "viewer" role by default [#2900](https://github.com/ethyca/fides/pull/2900)


### Fixed

Expand Down
2 changes: 1 addition & 1 deletion src/fides/api/ops/schemas/user_permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class UserPermissionsCreate(BaseSchema):
cannot be assigned directly to users.
"""

roles: List[RoleRegistryEnum] = []
roles: List[RoleRegistryEnum]

class Config:
"""So roles are strings when we add to the db"""
Expand Down
3 changes: 2 additions & 1 deletion src/fides/lib/oauth/api/routes/user_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from fides.lib.models.fides_user_permissions import FidesUserPermissions
from fides.lib.oauth.api import urn_registry as urls
from fides.lib.oauth.api.deps import get_db
from fides.lib.oauth.roles import VIEWER
from fides.lib.oauth.schemas.oauth import AccessToken
from fides.lib.oauth.schemas.user import (
UserCreate,
Expand Down Expand Up @@ -80,7 +81,7 @@ def create_user(
logger.info("Created user with id: '{}'.", user.id)
FidesUserPermissions.create(
db=db,
data={"user_id": user.id, "roles": []},
data={"user_id": user.id, "roles": [VIEWER]},
)
return user

Expand Down
3 changes: 3 additions & 0 deletions tests/ops/api/v1/endpoints/test_user_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ def test_create_user(
assert HTTP_201_CREATED == response.status_code
assert response_body == {"id": user.id}
assert user.permissions is not None
assert user.permissions.roles == [
VIEWER
], "User given viewer role by default on create"

def test_create_user_as_root(
self,
Expand Down
116 changes: 115 additions & 1 deletion tests/ops/api/v1/endpoints/test_user_permission_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,43 @@ def test_create_user_permissions_add_bad_role(
in response_body["detail"][0]["msg"]
)

def test_create_user_permissions_roles_are_an_empty_list(
self, db, api_client, generate_auth_header
) -> None:
"""If roles are an empty list, user will have no roles"""
auth_header = generate_auth_header([USER_PERMISSION_CREATE])
user = FidesUser.create(
db=db,
data={"username": "user_1", "password": "test_password"},
)

body = {"user_id": user.id, "roles": []}
response = api_client.post(
f"{V1_URL_PREFIX}/user/{user.id}/permission", headers=auth_header, json=body
)
permissions = FidesUserPermissions.get_by(db, field="user_id", value=user.id)
response_body = response.json()
assert HTTP_201_CREATED == response.status_code
assert response_body["roles"] == []
assert permissions.roles == []
user.delete(db)

def test_create_user_permissions_no_role_key(
self, db, api_client, generate_auth_header
) -> None:
"""Roles key explicitly required"""
auth_header = generate_auth_header([USER_PERMISSION_CREATE])
user = FidesUser.create(
db=db,
data={"username": "user_1", "password": "test_password"},
)

body = {"user_id": user.id}
response = api_client.post(
f"{V1_URL_PREFIX}/user/{user.id}/permission", headers=auth_header, json=body
)
assert HTTP_422_UNPROCESSABLE_ENTITY == response.status_code

def test_create_user_permissions_add_roles(
self, db, api_client, generate_auth_header
) -> None:
Expand Down Expand Up @@ -269,10 +306,11 @@ def test_edit_user_permissions_invalid_user_id(
headers=auth_header,
json=body,
)
assert HTTP_404_NOT_FOUND == response.status_code

permissions = FidesUserPermissions.get_by(
db, field="user_id", value=invalid_user_id
)
assert HTTP_404_NOT_FOUND == response.status_code
assert permissions is None
user.delete(db)

Expand Down Expand Up @@ -416,6 +454,82 @@ def test_edit_user_roles(self, db, api_client, generate_auth_header) -> None:

user.delete(db)

def test_edit_user_roles_remove_role(
self, db, api_client, generate_auth_header
) -> None:
auth_header = generate_auth_header(
[USER_PERMISSION_UPDATE, USER_PERMISSION_ASSIGN_OWNERS]
)
user = FidesUser.create(
db=db,
data={"username": "user_1", "password": "test_password"},
)

permissions = FidesUserPermissions.create(
db=db,
data={
"user_id": user.id,
"roles": [OWNER],
},
)

ClientDetail.create_client_and_secret(
db,
CONFIG.security.oauth_client_id_length_bytes,
CONFIG.security.oauth_client_secret_length_bytes,
roles=[VIEWER],
user_id=user.id,
)

body = {"id": permissions.id, "roles": []}
response = api_client.put(
f"{V1_URL_PREFIX}/user/{user.id}/permission", headers=auth_header, json=body
)
response_body = response.json()
assert HTTP_200_OK == response.status_code
assert response_body["roles"] == []

client: ClientDetail = ClientDetail.get_by(db, field="user_id", value=user.id)
assert (
client.scopes == []
), "Assert client scopes are not updated via the user permissions update flow"
assert client.roles == []

db.refresh(permissions)
assert permissions.roles == []

user.delete(db)

def test_edit_user_roles_request_no_role_key(
self, db, api_client, generate_auth_header
) -> None:
auth_header = generate_auth_header(
[USER_PERMISSION_UPDATE, USER_PERMISSION_ASSIGN_OWNERS]
)
user = FidesUser.create(
db=db,
data={"username": "user_1", "password": "test_password"},
)

permissions = FidesUserPermissions.create(
db=db,
data={
"user_id": user.id,
"roles": [OWNER],
},
)

body = {"id": permissions.id}
response = api_client.put(
f"{V1_URL_PREFIX}/user/{user.id}/permission", headers=auth_header, json=body
)
assert HTTP_422_UNPROCESSABLE_ENTITY == response.status_code

db.refresh(permissions)
assert permissions.roles == [OWNER]

user.delete(db)

@pytest.mark.parametrize(
"acting_user,updating_role,updated_user,expected_response",
[
Expand Down

0 comments on commit 9082c94

Please sign in to comment.