From b9be18f281c91bb7bb2d23f1119e5c99a3456801 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 27 Jan 2021 19:10:13 -0800 Subject: [PATCH 1/7] Role and User update logs --- lemur/auth/views.py | 7 ++++--- lemur/logs/service.py | 15 ++++++++++++++- lemur/roles/service.py | 11 ++++++++++- lemur/users/service.py | 6 ++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index eaed419d..fe3b8cf5 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -20,6 +20,7 @@ from lemur.common.utils import get_psuedo_random_string from lemur.users import service as user_service from lemur.roles import service as role_service +from lemur.logs import service as log_service from lemur.auth.service import create_token, fetch_token_header, get_rsa_public_key from lemur.auth import ldap @@ -184,8 +185,6 @@ def create_user_roles(profile): current_app.config["LEMUR_DEFAULT_ROLE"], description="This is the default Lemur role.", ) - if not default.third_party: - role_service.set_third_party(default.id, third_party_status=True) roles.append(default) return roles @@ -198,7 +197,7 @@ def update_user(user, profile, roles): :param profile: :param roles: """ - + log_service.audit_log("TEST", user.name, "Edit role") # if we get an sso user create them an account if not user: user = user_service.create( @@ -215,6 +214,8 @@ def update_user(user, profile, roles): for ur in user.roles: if not ur.third_party: roles.append(ur) + else: + log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for {user.name}") # update any changes to the user user_service.update( diff --git a/lemur/logs/service.py b/lemur/logs/service.py index f4949911..96b4b14f 100644 --- a/lemur/logs/service.py +++ b/lemur/logs/service.py @@ -7,7 +7,7 @@ :license: Apache, see LICENSE for more details. .. moduleauthor:: Kevin Glisson """ -from flask import current_app +from flask import current_app, g from lemur import database from lemur.logs.models import Log @@ -34,6 +34,19 @@ def create(user, type, certificate=None): database.commit() +def audit_log(action, entity, message): + """ + Logs given action + :param action: The action being logged e.g. assign_role, create_role etc + :param entity: The entity undergoing the action e.g. name of the role + :param message: Additional info e.g. Role being assigned to user X + :return: + """ + current_app.logger.info( + f"[lemur-audit] action: {action}, user: {g.current_user.email}, entity: {entity} [{message}]" + ) + + def get_all(): """ Retrieve all logs from the database. diff --git a/lemur/roles/service.py b/lemur/roles/service.py index fa4c9c97..cb733d40 100644 --- a/lemur/roles/service.py +++ b/lemur/roles/service.py @@ -12,6 +12,7 @@ from lemur import database from lemur.roles.models import Role from lemur.users.models import User +from lemur.logs import service as log_service def update(role_id, name, description, users): @@ -29,6 +30,8 @@ def update(role_id, name, description, users): role.description = description role.users = users database.update(role) + + log_service.audit_log("update_role", name, f"Role with id {role_id} updated") return role @@ -44,6 +47,8 @@ def set_third_party(role_id, third_party_status=False): role = get(role_id) role.third_party = third_party_status database.update(role) + + log_service.audit_log("update_role", role.name, f"Updated third_party_status={third_party_status}") return role @@ -71,6 +76,7 @@ def create( if users: role.users = users + log_service.audit_log("create_role", name, "Creating new role") return database.create(role) @@ -101,7 +107,10 @@ def delete(role_id): :param role_id: :return: """ - return database.delete(get(role_id)) + + role = get(role_id) + log_service.audit_log("delete_role", role.name, "Deleting role") + return database.delete(role) def render(args): diff --git a/lemur/users/service.py b/lemur/users/service.py index 8fb91aa3..a67f0262 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -8,6 +8,7 @@ .. moduleauthor:: Kevin Glisson """ from lemur import database +from lemur.logs import service as log_service from lemur.users.models import User @@ -31,6 +32,7 @@ def create(username, password, email, active, profile_picture, roles): profile_picture=profile_picture, ) user.roles = roles + log_service.audit_log("create_user", username, f"Creating new user") return database.create(user) @@ -52,6 +54,8 @@ def update(user_id, username, email, active, profile_picture, roles): user.active = active user.profile_picture = profile_picture update_roles(user, roles) + + log_service.audit_log("update_user", username, f"Updating user with id {user_id}") return database.update(user) @@ -70,6 +74,7 @@ def update_roles(user, roles): break else: user.roles.remove(ur) + log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for user {user.username}") for r in roles: for ur in user.roles: @@ -77,6 +82,7 @@ def update_roles(user, roles): break else: user.roles.append(r) + log_service.audit_log("assign_role", ur.name, f"Assigning the role to user {user.username}") def get(user_id): From f14a236739853c70ed426bb2f0fdc2b05a7082f7 Mon Sep 17 00:00:00 2001 From: sayali Date: Wed, 27 Jan 2021 22:57:33 -0800 Subject: [PATCH 2/7] lint fix --- lemur/users/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/users/service.py b/lemur/users/service.py index a67f0262..293288ce 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -32,7 +32,7 @@ def create(username, password, email, active, profile_picture, roles): profile_picture=profile_picture, ) user.roles = roles - log_service.audit_log("create_user", username, f"Creating new user") + log_service.audit_log("create_user", username, "Creating new user") return database.create(user) From fe2fc0eadd2ff3e4d46210b9c2ed7a3951ee5a4e Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 11:19:47 -0800 Subject: [PATCH 3/7] PR comments --- lemur/auth/views.py | 1 - lemur/users/service.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index fe3b8cf5..5bf80201 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -197,7 +197,6 @@ def update_user(user, profile, roles): :param profile: :param roles: """ - log_service.audit_log("TEST", user.name, "Edit role") # if we get an sso user create them an account if not user: user = user_service.create( diff --git a/lemur/users/service.py b/lemur/users/service.py index 293288ce..ffc81f5c 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -82,7 +82,7 @@ def update_roles(user, roles): break else: user.roles.append(r) - log_service.audit_log("assign_role", ur.name, f"Assigning the role to user {user.username}") + log_service.audit_log("assign_role", r.name, f"Assigning the role to user {user.username}") def get(user_id): From ed57a5a45af148734b0fb037af5daf85c65e176f Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 13:43:25 -0800 Subject: [PATCH 4/7] Keep default role third-party (old code) --- lemur/auth/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index 5bf80201..f9eb11d0 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -185,6 +185,8 @@ def create_user_roles(profile): current_app.config["LEMUR_DEFAULT_ROLE"], description="This is the default Lemur role.", ) + if not default.third_party: + role_service.set_third_party(default.id, third_party_status=True) roles.append(default) return roles From 20792dfe3a3fe6754f2a4810fa4b18b6aeeea9e1 Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 15:58:12 -0800 Subject: [PATCH 5/7] Club role assignment logs --- lemur/auth/views.py | 8 ++++++-- lemur/users/service.py | 12 ++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lemur/auth/views.py b/lemur/auth/views.py index f9eb11d0..85a8f636 100644 --- a/lemur/auth/views.py +++ b/lemur/auth/views.py @@ -212,12 +212,16 @@ def update_user(user, profile, roles): else: # we add 'lemur' specific roles, so they do not get marked as removed + removed_roles = [] for ur in user.roles: if not ur.third_party: roles.append(ur) - else: - log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for {user.name}") + elif ur not in roles: + # This is a role assigned in lemur, but not returned by sso during current login + removed_roles.append(ur.name) + if removed_roles: + log_service.audit_log("unassign_role", user.name, f"Un-assigning roles {removed_roles}") # update any changes to the user user_service.update( user.id, diff --git a/lemur/users/service.py b/lemur/users/service.py index ffc81f5c..d708d295 100644 --- a/lemur/users/service.py +++ b/lemur/users/service.py @@ -68,21 +68,29 @@ def update_roles(user, roles): :param user: :param roles: """ + removed_roles = [] for ur in user.roles: for r in roles: if r.id == ur.id: break else: user.roles.remove(ur) - log_service.audit_log("unassign_role", ur.name, f"Un-assigning the role for user {user.username}") + removed_roles.append(ur.name) + if removed_roles: + log_service.audit_log("unassign_role", user.username, f"Un-assigning roles {removed_roles}") + + added_roles = [] for r in roles: for ur in user.roles: if r.id == ur.id: break else: user.roles.append(r) - log_service.audit_log("assign_role", r.name, f"Assigning the role to user {user.username}") + added_roles.append(r.name) + + if added_roles: + log_service.audit_log("assign_role", user.username, f"Assigning roles {added_roles}") def get(user_id): From 77a50e0abfa749874cede765dc774d4fb3b628e8 Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 17:56:12 -0800 Subject: [PATCH 6/7] API Key logs --- lemur/api_keys/service.py | 9 ++++++++- lemur/logs/service.py | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lemur/api_keys/service.py b/lemur/api_keys/service.py index ea681a62..3cb896aa 100644 --- a/lemur/api_keys/service.py +++ b/lemur/api_keys/service.py @@ -7,6 +7,7 @@ """ from lemur import database from lemur.api_keys.models import ApiKey +from lemur.logs import service as log_service def get(aid): @@ -24,6 +25,7 @@ def delete(access_key): :param access_key: :return: """ + log_service.audit_log("delete_api_key", access_key.name, "Deleting the API key") database.delete(access_key) @@ -34,8 +36,9 @@ def revoke(aid): :return: """ api_key = get(aid) - setattr(api_key, "revoked", False) + setattr(api_key, "revoked", True) + log_service.audit_log("revoke_api_key", api_key.name, "Revoking API key") return database.update(api_key) @@ -55,6 +58,9 @@ def create(**kwargs): :return: """ api_key = ApiKey(**kwargs) + # this logs only metadata about the api key + log_service.audit_log("create_api_key", api_key.name, f"Creating the API key {api_key}") + database.create(api_key) return api_key @@ -69,6 +75,7 @@ def update(api_key, **kwargs): for key, value in kwargs.items(): setattr(api_key, key, value) + log_service.audit_log("update_api_key", api_key.name, f"Update summary - {kwargs}") return database.update(api_key) diff --git a/lemur/logs/service.py b/lemur/logs/service.py index 96b4b14f..f569a05d 100644 --- a/lemur/logs/service.py +++ b/lemur/logs/service.py @@ -42,8 +42,9 @@ def audit_log(action, entity, message): :param message: Additional info e.g. Role being assigned to user X :return: """ + user = g.current_user.email if hasattr(g, 'current_user') else "LEMUR" current_app.logger.info( - f"[lemur-audit] action: {action}, user: {g.current_user.email}, entity: {entity} [{message}]" + f"[lemur-audit] action: {action}, user: {user}, entity: {entity}, details:{message}" ) From 38fc80fb470a2edb7374c7289ebf734a7e67891b Mon Sep 17 00:00:00 2001 From: sayali Date: Thu, 28 Jan 2021 17:59:35 -0800 Subject: [PATCH 7/7] space --- lemur/logs/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lemur/logs/service.py b/lemur/logs/service.py index f569a05d..5e5f30db 100644 --- a/lemur/logs/service.py +++ b/lemur/logs/service.py @@ -44,7 +44,7 @@ def audit_log(action, entity, message): """ user = g.current_user.email if hasattr(g, 'current_user') else "LEMUR" current_app.logger.info( - f"[lemur-audit] action: {action}, user: {user}, entity: {entity}, details:{message}" + f"[lemur-audit] action: {action}, user: {user}, entity: {entity}, details: {message}" )