Skip to content

Commit

Permalink
Merge branch 'master' into feat/mcrypt_to_ccrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
BinamB committed Nov 15, 2024
2 parents 1d34da5 + 475e4b5 commit e0a794a
Show file tree
Hide file tree
Showing 13 changed files with 355 additions and 33 deletions.
6 changes: 3 additions & 3 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,14 @@
"filename": "tests/data/test_indexed_file.py",
"hashed_secret": "a62f2225bf70bfaccbc7f1ef2a397836717377de",
"is_verified": false,
"line_number": 411
"line_number": 449
},
{
"type": "Secret Keyword",
"filename": "tests/data/test_indexed_file.py",
"hashed_secret": "c258a8d1264cc59de81f8b1975ac06732b1cf182",
"is_verified": false,
"line_number": 432
"line_number": 470
}
],
"tests/keys/2018-05-01T21:29:02Z/jwt_private_key.pem": [
Expand Down Expand Up @@ -395,5 +395,5 @@
}
]
},
"generated_at": "2023-10-20T20:37:17Z"
"generated_at": "2024-11-04T09:20:13Z"
}
5 changes: 2 additions & 3 deletions fence/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,8 @@ def set_flask_session_values(user):

user = query_for_user(session=current_app.scoped_session(), username=username)
if user:
if user.active is False:
# Abort login if user.active is False (user.active is None or True are both
# considered active in this case):
if user.active == False:
# Abort login if user.active == False:
raise Unauthorized(
"User is known but not authorized/activated in the system"
)
Expand Down
22 changes: 19 additions & 3 deletions fence/blueprints/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def create_user():
Returns a json object
"""
username = request.get_json().get("name", None)
username = request.get_json().get("username", None)
role = request.get_json().get("role", None)
email = request.get_json().get("email", None)
display_name = request.get_json().get("display_name", None)
Expand Down Expand Up @@ -110,11 +110,13 @@ def update_user(username):
Returns a json object
"""
name = request.get_json().get("name", None)
new_username = request.get_json().get("username", None)
role = request.get_json().get("role", None)
email = request.get_json().get("email", None)
return jsonify(
admin.update_user(current_app.scoped_session(), username, role, email, name)
admin.update_user(
current_app.scoped_session(), username, role, email, new_username
)
)


Expand All @@ -133,6 +135,20 @@ def delete_user(username):
return response


@blueprint.route("/users/<username>/soft", methods=["DELETE"])
@blueprint.route("/user/<username>/soft", methods=["DELETE"])
@admin_login_required
@debug_log
def soft_delete_user(username):
"""
Soft-remove the user by marking it as active=False.
Returns json object
"""
response = jsonify(admin.soft_delete_user(current_app.scoped_session(), username))
return response


@blueprint.route("/users/<username>/groups", methods=["GET"])
@blueprint.route("/user/<username>/groups", methods=["GET"])
@admin_login_required
Expand Down
18 changes: 15 additions & 3 deletions fence/resources/admin/admin_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"update_user",
"add_user_to_projects",
"delete_user",
"soft_delete_user",
"add_user_to_groups",
"connect_user_to_group",
"remove_user_from_groups",
Expand Down Expand Up @@ -77,7 +78,7 @@ def get_all_users(current_session):
users_names = []
for user in users:
new_user = {}
new_user["name"] = user.username
new_user["username"] = user.username
if user.is_admin:
new_user["role"] = "admin"
else:
Expand Down Expand Up @@ -123,7 +124,7 @@ def create_user(
except NotFound:
logger.debug(f"User not found for: {username}. Checking again ignoring case...")
user_list = [
user["name"].upper() for user in get_all_users(current_session)["users"]
user["username"].upper() for user in get_all_users(current_session)["users"]
]
if username.upper() in user_list:
logger.debug(f"User already exists for: {username}")
Expand Down Expand Up @@ -167,7 +168,7 @@ def create_user(
def update_user(current_session, username, role, email, new_name):
usr = us.get_user(current_session, username)
user_list = [
user["name"].upper() for user in get_all_users(current_session)["users"]
user["username"].upper() for user in get_all_users(current_session)["users"]
]
if (
new_name
Expand Down Expand Up @@ -359,6 +360,17 @@ def raise_unavailable(gpg_email):
logger.info("Done with Google deletions.")


def soft_delete_user(current_session, username):
"""
Soft-remove the user by marking it as active=False.
"""
logger.debug(f"Soft-delete user '{username}'")
usr = us.get_user(current_session, username)
usr.active = False
current_session.commit()
return us.get_user_info(current_session, usr.username)


def delete_user(current_session, username):
"""
Remove a user from both the userdatamodel
Expand Down
1 change: 1 addition & 0 deletions fence/resources/user/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def get_user_info(current_session, username):
"phone_number": user.phone_number,
"email": user.email,
"is_admin": user.is_admin,
"active": user.active,
"role": role,
"project_access": dict(user.project_access),
"certificates_uploaded": [],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Make User.active field non nullable
Revision ID: 3a5712474808
Revises: 9b3a5a7145d7
Create Date: 2024-11-08 22:00:41.161934
"""
from alembic import op
import sqlalchemy as sa
from userdatamodel.models import User
from sqlalchemy.orm import Session


# revision identifiers, used by Alembic.
revision = "3a5712474808" # pragma: allowlist secret
down_revision = "9b3a5a7145d7" # pragma: allowlist secret
branch_labels = None
depends_on = None


def upgrade():
conn = op.get_bind()
session = Session(bind=conn)
session.query(User)
active_users_count = session.query(User).filter(User.active.is_(True)).count()
if active_users_count > 0:
# if we have at least one user where "active" is explicitly set to "True", then we'll assume NULL is to mean "False":
op.execute('UPDATE "User" SET active = False WHERE active IS NULL')
else:
# else, we assume NULL means "True"
op.execute('UPDATE "User" SET active = True WHERE active IS NULL')
op.alter_column("User", "active", nullable=False, server_default="True")


def downgrade():
op.alter_column("User", "active", nullable=True, server_default=None)
117 changes: 117 additions & 0 deletions openapis/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,73 @@ paths:
'*/*':
schema:
$ref: '#/components/schemas/UserInfo'
'/admin/user/{username}':
get:
tags:
- 'admin/user'
summary: Return info about a given user
description: Admin method to retrieve info about any given user
parameters:
- name: username
required: true
in: path
description: Username of user to find
schema:
type: string
security:
- OAuth2:
- user
operationId: getUserInfo
responses:
'200':
description: successful operation
content:
'*/*':
schema:
$ref: '#/components/schemas/UserInfo'
'404':
description: Couldn't find user
'/admin/user/{username}/soft':
delete:
tags:
- 'admin/user'
summary: Soft-delete user
description: Admin method to soft-delete a user, setting the user to inactive
security:
- OAuth2:
- admin
operationId: softDeleteUser
parameters:
- name: username
required: true
in: path
description: Username of user to deactivate
schema:
type: string
responses:
'204':
description: successful deletion
'404':
description: Couldn't find user
/admin/user:
post:
tags:
- admin/user
summary: Add a new user
description: Admin method to add a new user
security:
- OAuth2:
- admin
operationId: createUser
responses:
'200':
description: New user
content:
'*/*':
schema:
$ref: '#/components/schemas/UserInfo'
requestBody:
$ref: '#/components/requestBodies/NewUser'
/logout:
get:
tags:
Expand Down Expand Up @@ -1683,6 +1750,13 @@ components:
$ref: '#/components/schemas/APIKeyScopes'
description: API key scopes
required: false
NewUser:
content:
application/json:
schema:
$ref: '#/components/schemas/NewUser'
description: New User
required: true
securitySchemes:
OAuth2:
type: oauth2
Expand All @@ -1693,6 +1767,46 @@ components:
scopes:
user: generic user access
schemas:
NewUser:
type: object
required:
- username
- role
- email
properties:
username:
type: string
description: 'This value is deprecated in favor of name.'
role:
type: string
description: 'Set to "admin" if the user should be given admin rights. Any other value is not parsed or used, and results in user being a normal/regular user.'
email:
type: string
description: 'The email of the end-user'
display_name:
type: string
description: 'The display name of the end-user.'
phone_number:
type: string
description: 'The phone number of the end-user.'
idp_name:
type: string
description: |
Name of the preferred Identity Provider used to autheticate the user. Given instances of Fence
may or may not have all of these available (the set of IDPs available is a configuration).
* *google* - Google/GSuite
* *ras* - NIH's Researcher Auth Service (RAS)
* *itrust* - NIH Login / iTrust / eRA Commons
* *fence* - Upstream Fence (the idp used depends on the specific configuration, consult the Gen3 Operators)
* *orcid* - ORCHID
* *microsoft* - Microsoft
* *elixir* - Elixir
* *synapse* - Synapse
* *cognito* - AWS Cognito
* More may be added in the future...
tags:
type: object
description: User's tags
RequestUploadBlank:
type: object
required:
Expand Down Expand Up @@ -2335,6 +2449,9 @@ components:
is_admin:
type: boolean
description: 'Boolean value stating if end-user is an admin or not'
active:
type: boolean
description: 'Boolean value stating if user is active or not'
role:
type: string
description: ''
Expand Down
15 changes: 8 additions & 7 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pyyaml = "^6.0.1"
requests = ">=2.18.0"
retry = "^0.9.2"
sqlalchemy = "^1.3.3"
userdatamodel = ">=2.4.3"
userdatamodel = ">=3.0.1"
werkzeug = ">=3.0.0"
cachelib = "^0.2.0"
azure-storage-blob = "^12.6.0"
Expand Down
Loading

0 comments on commit e0a794a

Please sign in to comment.