Skip to content

Commit 2eca2d8

Browse files
Merge pull request #1023 from Rajandeep98/sbcq202_keyclockauditscript
sbcq-202 : Keyclock Audit script
2 parents bab1232 + c26aae2 commit 2eca2d8

File tree

2 files changed

+135
-0
lines changed

2 files changed

+135
-0
lines changed

api/audit_script/.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
KEYCLOAK_SERVER_URL=
2+
REALM_NAME=
3+
OIDC_PROVIDER_TOKEN_URL=
4+
SERVICE_ACCOUNT_ID=
5+
SERVICE_ACCOUNT_SECRET=
6+
USERNAME=
7+
PASSWORD=
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import os
2+
import requests
3+
from dotenv import load_dotenv
4+
import csv
5+
from datetime import datetime
6+
7+
load_dotenv()
8+
def get_access_token():
9+
token_url = os.getenv('OIDC_PROVIDER_TOKEN_URL')
10+
client_id = os.getenv('SERVICE_ACCOUNT_ID')
11+
client_secret = os.getenv('SERVICE_ACCOUNT_SECRET')
12+
username = os.getenv('USERNAME')
13+
password = os.getenv('PASSWORD')
14+
if not all([token_url, client_id, username, password]):
15+
raise ValueError("Missing required environment variables.")
16+
data = {
17+
'grant_type': 'password',
18+
'client_id': client_id,
19+
'username': username,
20+
'password': password
21+
}
22+
if client_secret:
23+
data['client_secret'] = client_secret
24+
headers = {
25+
'Content-Type': 'application/x-www-form-urlencoded'
26+
}
27+
token_response = requests.post(token_url, data=data, headers=headers)
28+
if token_response.status_code != 200:
29+
raise Exception(f"Failed to get token: {token_response.status_code} - {token_response.text}")
30+
access_token = token_response.json().get('access_token')
31+
print(access_token)
32+
if not access_token:
33+
raise Exception("Failed to retrieve access token")
34+
return access_token
35+
36+
def get_users():
37+
access_token = get_access_token()
38+
keycloak_server_url = os.getenv('KEYCLOAK_SERVER_URL')
39+
realm_name = os.getenv('REALM_NAME')
40+
41+
count_endpoint = f"{keycloak_server_url}/admin/realms/{realm_name}/users/count"
42+
headers = {
43+
'Authorization': f'Bearer {access_token}',
44+
'Content-Type': 'application/json'
45+
}
46+
count_response = requests.get(count_endpoint, headers=headers)
47+
count_response.raise_for_status()
48+
total_users = count_response.json()
49+
50+
all_users = []
51+
first = 0
52+
max_results = 100
53+
54+
print("Total Results Found :", total_users)
55+
while first < total_users:
56+
users_endpoint = f"{keycloak_server_url}/admin/realms/{realm_name}/users?first={first}&max={max_results}"
57+
response = requests.get(users_endpoint, headers=headers)
58+
response.raise_for_status()
59+
users_data = response.json()
60+
61+
for user in users_data:
62+
user_id = user['id']
63+
print("Processing ", user_id)
64+
user_groups_endpoint = f"{keycloak_server_url}/admin/realms/{realm_name}/users/{user_id}/groups"
65+
user_groups_response = requests.get(user_groups_endpoint, headers=headers)
66+
user_groups_response.raise_for_status()
67+
68+
user_groups = user_groups_response.json()
69+
70+
group_names = [group['name'] for group in user_groups]
71+
72+
user['group_names'] = group_names
73+
74+
all_users.extend(users_data)
75+
76+
first += max_results
77+
78+
return all_users
79+
80+
def write_to_csv(filtered_users):
81+
current_datetime = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
82+
csv_file_name = f"users_with_groups_{current_datetime}.csv"
83+
84+
with open(csv_file_name, mode='w', newline='', encoding='utf-8') as file:
85+
writer = csv.writer(file)
86+
writer.writerow(['Groups', 'Username', 'Display Name', 'User ID', 'User Email', 'Identity Provider'])
87+
88+
for user in filtered_users:
89+
groups = user.get('group_names', [])
90+
display_name = f"{user.get('firstName', '')} {user.get('lastName', '')}".strip()
91+
92+
if not groups:
93+
writer.writerow(['N/A',
94+
user.get('username', 'N/A'),
95+
display_name,
96+
user.get('id', 'N/A'),
97+
user.get('email', 'N/A'),
98+
user.get('attributes', {}).get('identity_provider', ['N/A'])[0]])
99+
else:
100+
for group in groups:
101+
writer.writerow([group,
102+
user.get('username', 'N/A'),
103+
display_name,
104+
user.get('id', 'N/A'),
105+
user.get('email', 'N/A'),
106+
user.get('attributes', {}).get('identity_provider', ['N/A'])[0]])
107+
108+
print(f"New file created: {csv_file_name}")
109+
110+
111+
112+
if __name__ == "__main__":
113+
try:
114+
users_data = get_users()
115+
count = 0
116+
filtered_users = []
117+
for user in users_data:
118+
attributes = user.get('attributes', {})
119+
identity_provider = attributes.get('identity_provider', [])
120+
username = user.get('username', '')
121+
if 'idir' in identity_provider or '@idir' in username:
122+
count+=1
123+
filtered_users.append(user)
124+
print(count,"total users")
125+
126+
write_to_csv(filtered_users)
127+
except Exception as e:
128+
print(f"Error: {e}")

0 commit comments

Comments
 (0)