trovesuite 1.0.11__py3-none-any.whl → 1.0.13__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- trovesuite/auth/auth_service.py +85 -21
- {trovesuite-1.0.11.dist-info → trovesuite-1.0.13.dist-info}/METADATA +1 -1
- {trovesuite-1.0.11.dist-info → trovesuite-1.0.13.dist-info}/RECORD +6 -6
- {trovesuite-1.0.11.dist-info → trovesuite-1.0.13.dist-info}/WHEEL +0 -0
- {trovesuite-1.0.11.dist-info → trovesuite-1.0.13.dist-info}/licenses/LICENSE +0 -0
- {trovesuite-1.0.11.dist-info → trovesuite-1.0.13.dist-info}/top_level.txt +0 -0
trovesuite/auth/auth_service.py
CHANGED
|
@@ -77,7 +77,7 @@ class AuthService:
|
|
|
77
77
|
)
|
|
78
78
|
|
|
79
79
|
if not is_tenant_verified or len(is_tenant_verified) == 0:
|
|
80
|
-
logger.warning("
|
|
80
|
+
logger.warning("Authorization failed - tenant not found: %s", tenant_id)
|
|
81
81
|
return Respons[AuthServiceReadDto](
|
|
82
82
|
detail=f"Tenant '{tenant_id}' not found or has been deleted",
|
|
83
83
|
data=[],
|
|
@@ -87,7 +87,7 @@ class AuthService:
|
|
|
87
87
|
)
|
|
88
88
|
|
|
89
89
|
if not is_tenant_verified[0]['is_verified']:
|
|
90
|
-
logger.warning("
|
|
90
|
+
logger.warning("Authorization failed - tenant not verified for user: %s, tenant: %s", user_id, tenant_id)
|
|
91
91
|
return Respons[AuthServiceReadDto](
|
|
92
92
|
detail=f"Tenant '{tenant_id}' is not verified. Please contact your administrator.",
|
|
93
93
|
data=[],
|
|
@@ -146,35 +146,54 @@ class AuthService:
|
|
|
146
146
|
error="USER_SUSPENDED"
|
|
147
147
|
)
|
|
148
148
|
|
|
149
|
+
# ✅ UPDATED: Mutually exclusive login restrictions logic
|
|
149
150
|
if not login_settings_details[0]['can_always_login']:
|
|
150
|
-
|
|
151
|
+
# Get from database (should already be datetime objects)
|
|
152
|
+
login_on = login_settings_details[0]['login_on']
|
|
153
|
+
logout_on = login_settings_details[0]['logout_on']
|
|
154
|
+
working_days = login_settings_details[0]['working_days']
|
|
151
155
|
|
|
152
|
-
|
|
153
|
-
|
|
156
|
+
# Only ONE restriction type can be active at a time:
|
|
157
|
+
# 1. working_days restriction (if login_on/logout_on are NULL)
|
|
158
|
+
# 2. time period restriction (if login_on/logout_on are set)
|
|
154
159
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
# Get from database (should already be datetime objects)
|
|
159
|
-
login_on = login_settings_details[0]['login_on']
|
|
160
|
-
logout_on = login_settings_details[0]['logout_on']
|
|
160
|
+
if login_on and logout_on:
|
|
161
|
+
# Time period restriction is active
|
|
162
|
+
logger.info(f"Checking time period restriction for user: {user_id}")
|
|
161
163
|
|
|
162
|
-
#
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
logout_on = datetime.max.replace(tzinfo=timezone.utc)
|
|
164
|
+
# Get current datetime (full date and time) with timezone
|
|
165
|
+
current_datetime = datetime.now(timezone.utc).replace(
|
|
166
|
+
microsecond=0, second=0
|
|
167
|
+
)
|
|
167
168
|
|
|
168
169
|
# Compare full datetime objects (both date and time)
|
|
169
170
|
if not (login_on <= current_datetime <= logout_on):
|
|
170
|
-
logger.warning(
|
|
171
|
+
logger.warning(
|
|
172
|
+
f"Authorization failed - outside allowed period for user: {user_id}"
|
|
173
|
+
)
|
|
171
174
|
return Respons[AuthServiceReadDto](
|
|
172
|
-
detail="
|
|
175
|
+
detail="Access is not allowed at this time. Please check your access schedule.",
|
|
173
176
|
data=[],
|
|
174
177
|
success=False,
|
|
175
178
|
status_code=403,
|
|
176
179
|
error="LOGIN_TIME_RESTRICTED"
|
|
177
180
|
)
|
|
181
|
+
elif working_days:
|
|
182
|
+
# Working days restriction is active
|
|
183
|
+
logger.info(f"Checking working days restriction for user: {user_id}")
|
|
184
|
+
current_day = datetime.now().strftime("%A").upper()
|
|
185
|
+
|
|
186
|
+
if current_day not in working_days:
|
|
187
|
+
logger.warning(
|
|
188
|
+
f"Authorization failed - not a working day for user: {user_id}"
|
|
189
|
+
)
|
|
190
|
+
return Respons[AuthServiceReadDto](
|
|
191
|
+
detail="Access is not allowed on this day. Please contact your administrator.",
|
|
192
|
+
data=[],
|
|
193
|
+
success=False,
|
|
194
|
+
status_code=403,
|
|
195
|
+
error="LOGIN_DAY_RESTRICTED"
|
|
196
|
+
)
|
|
178
197
|
|
|
179
198
|
# 4️⃣ Build query dynamically to include groups (if any) + user
|
|
180
199
|
# ⚠️ CHANGED: Simplified to new schema - only select user_id, group_id, role_id, resource_type
|
|
@@ -206,18 +225,62 @@ class AuthService:
|
|
|
206
225
|
(user_id,),
|
|
207
226
|
)
|
|
208
227
|
|
|
228
|
+
# ✅ NEW: Get system-level roles from main.system_user_groups and main.system_assign_roles
|
|
229
|
+
logger.info(f"Fetching system-level roles for user: {user_id}")
|
|
230
|
+
|
|
231
|
+
system_roles = DatabaseManager.execute_query(
|
|
232
|
+
"""
|
|
233
|
+
SELECT DISTINCT sug.group_id, sug.user_id, sar.role_id, sar.resource_type
|
|
234
|
+
FROM main.system_user_groups sug
|
|
235
|
+
INNER JOIN main.system_assign_roles sar ON sug.group_id = sar.group_id
|
|
236
|
+
WHERE sug.user_id = %s
|
|
237
|
+
AND sug.delete_status = 'NOT_DELETED'
|
|
238
|
+
AND sar.is_active = true
|
|
239
|
+
AND sar.delete_status = 'NOT_DELETED'
|
|
240
|
+
""",
|
|
241
|
+
(user_id,)
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
if system_roles:
|
|
245
|
+
logger.info(f"Found {len(system_roles)} system-level role(s) for user: {user_id}")
|
|
246
|
+
else:
|
|
247
|
+
logger.info(f"No system-level roles found for user: {user_id}")
|
|
248
|
+
|
|
249
|
+
# ✅ NEW: Also check for direct system role assignments (user_id in system_assign_roles)
|
|
250
|
+
direct_system_roles = DatabaseManager.execute_query(
|
|
251
|
+
"""
|
|
252
|
+
SELECT DISTINCT NULL as group_id, sar.user_id, sar.role_id, sar.resource_type
|
|
253
|
+
FROM main.system_assign_roles sar
|
|
254
|
+
WHERE sar.user_id = %s
|
|
255
|
+
AND sar.is_active = true
|
|
256
|
+
AND sar.delete_status = 'NOT_DELETED'
|
|
257
|
+
""",
|
|
258
|
+
(user_id,)
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
if direct_system_roles:
|
|
262
|
+
logger.info(f"Found {len(direct_system_roles)} direct system-level role assignment(s) for user: {user_id}")
|
|
263
|
+
system_roles.extend(direct_system_roles)
|
|
264
|
+
|
|
265
|
+
# ✅ NEW: Merge tenant-level and system-level roles
|
|
266
|
+
all_roles = get_user_roles + system_roles
|
|
267
|
+
logger.info(f"Total roles (tenant + system) for user {user_id}: {len(all_roles)}")
|
|
268
|
+
|
|
209
269
|
# GET permissions and Append to Role
|
|
210
270
|
get_user_roles_with_tenant_and_permissions = []
|
|
211
|
-
for role in
|
|
271
|
+
for role in all_roles:
|
|
212
272
|
permissions = DatabaseManager.execute_query(
|
|
213
273
|
f"""SELECT permission_id FROM {db_settings.MAIN_ROLE_PERMISSIONS_TABLE} WHERE role_id = %s""",
|
|
214
|
-
params=(role["role_id"],),
|
|
274
|
+
params=(role["role_id"],),
|
|
275
|
+
)
|
|
215
276
|
|
|
216
277
|
role_dict = {**role, "tenant_id": tenant_id, "permissions": [p['permission_id'] for p in permissions]}
|
|
217
278
|
get_user_roles_with_tenant_and_permissions.append(role_dict)
|
|
218
279
|
|
|
219
280
|
roles_dto = Helper.map_to_dto(get_user_roles_with_tenant_and_permissions, AuthServiceReadDto)
|
|
220
281
|
|
|
282
|
+
logger.info(f"Authorization successful for user: {user_id} with {len(roles_dto)} total role entries")
|
|
283
|
+
|
|
221
284
|
return Respons[AuthServiceReadDto](
|
|
222
285
|
detail="Authorized",
|
|
223
286
|
data=roles_dto,
|
|
@@ -230,7 +293,7 @@ class AuthService:
|
|
|
230
293
|
raise http_ex
|
|
231
294
|
|
|
232
295
|
except Exception as e:
|
|
233
|
-
logger.error("Authorization check failed for user: %s", str(e))
|
|
296
|
+
logger.error("Authorization check failed for user: %s - Error: %s", user_id, str(e), exc_info=True)
|
|
234
297
|
return Respons[AuthServiceReadDto](
|
|
235
298
|
detail=None,
|
|
236
299
|
data=[],
|
|
@@ -239,6 +302,7 @@ class AuthService:
|
|
|
239
302
|
error="Authorization check failed due to an internal error"
|
|
240
303
|
)
|
|
241
304
|
|
|
305
|
+
|
|
242
306
|
@staticmethod
|
|
243
307
|
def check_permission(users_data: list, action=None, resource_type=None) -> bool:
|
|
244
308
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trovesuite
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.13
|
|
4
4
|
Summary: TroveSuite services package providing authentication, authorization, notifications, Azure Storage, and other enterprise services for TroveSuite applications
|
|
5
5
|
Home-page: https://dev.azure.com/brightgclt/trovesuite/_git/packages
|
|
6
6
|
Author: Bright Debrah Owusu
|
|
@@ -3,7 +3,7 @@ trovesuite/auth/__init__.py,sha256=OjZllVvjul1glDazJ-d5TrNjgHFigFlQQi1G99DYshk,2
|
|
|
3
3
|
trovesuite/auth/auth_base.py,sha256=rZHQVLeJRBQ8GClgF5UwG-er4_HXVX5-nt8o6_Z29uY,75
|
|
4
4
|
trovesuite/auth/auth_controller.py,sha256=PAgaVlf5TYEfkSfK4vGGsvO84i8zEmeVVXyUF2YBppI,420
|
|
5
5
|
trovesuite/auth/auth_read_dto.py,sha256=e27JqKVPVUM83A_mYF452QCflsvGNo7aKje7q_urwFc,571
|
|
6
|
-
trovesuite/auth/auth_service.py,sha256=
|
|
6
|
+
trovesuite/auth/auth_service.py,sha256=N5ax0rdGlHcu7cpJyAFrrwdkwKN8gsoh-t6ngIvXBAk,17548
|
|
7
7
|
trovesuite/auth/auth_write_dto.py,sha256=rdwI7w6-9QZGv1H0PAGrjkLBCzaMHjgPIXeLb9RmNec,234
|
|
8
8
|
trovesuite/configs/__init__.py,sha256=h1mSZOaZ3kUy1ZMO_m9O9KklsxywM0RfMVZLh9h9WvQ,328
|
|
9
9
|
trovesuite/configs/database.py,sha256=IPSu8fXjxyYeJ3bFknJG06Qm2L2ub6Ht19xhKv8g7nA,11731
|
|
@@ -26,8 +26,8 @@ trovesuite/storage/storage_service.py,sha256=V7LIePIV6b_iuhm-9x8r4zwpZHgeRPL1YIe
|
|
|
26
26
|
trovesuite/storage/storage_write_dto.py,sha256=vl1iCZ93bpFmpvkCrn587QtMtOA_TPDseXSoTuj9RTQ,1355
|
|
27
27
|
trovesuite/utils/__init__.py,sha256=3UPKTz9cluTgAM-ldNsJxsnoPTZiqacXlAmzUEHy6q8,143
|
|
28
28
|
trovesuite/utils/helper.py,sha256=lvZ1mvaqY84dkIPB5Ov0uwYDOWBziAS8twobEJZh2Ik,1002
|
|
29
|
-
trovesuite-1.0.
|
|
30
|
-
trovesuite-1.0.
|
|
31
|
-
trovesuite-1.0.
|
|
32
|
-
trovesuite-1.0.
|
|
33
|
-
trovesuite-1.0.
|
|
29
|
+
trovesuite-1.0.13.dist-info/licenses/LICENSE,sha256=EJT35ct-Q794JYPdAQy3XNczQGKkU1HzToLeK1YVw2s,1070
|
|
30
|
+
trovesuite-1.0.13.dist-info/METADATA,sha256=V0DYYd8qAzusR_UKkg--F4scCYY0PhONHhjoa6fZ91k,21737
|
|
31
|
+
trovesuite-1.0.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
32
|
+
trovesuite-1.0.13.dist-info/top_level.txt,sha256=GzKhG_-MTaxeHrIgkGkBH_nof2vroGFBrjeHKWUIwNc,11
|
|
33
|
+
trovesuite-1.0.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|