
    2fhx[                     ~   d dl mZmZmZmZ d dlmZ d dlmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlmZmZ d dlmZ d	d
lmZmZmZmZ d	dlmZ d dlmZmZ d dlmZ d dl m!Z! d dlmZmZ d dlmZ d	dlm"Z"mZ d	dlm#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+  G d de      Z, G d dejZ                        Z. G d dej^                        Z0 G d dejZ                        Z1 G d dejZ                        Z2 G d dejf                        Z4 edgdde'ejj                  d !       G d" d#ej^                               Z6 edgd$d%e&e'ejj                  ejj                  d&'       G d( d)ejn                               Z8 edgd*d+d,d-d.d/d0d1d2id3ie'ejj                  d4'       G d5 d6ejn                               Z9 edgd7d8d,d-d9d/d0d:d2id3ie'ejj                  d4'       G d; d<ejn                               Z: ed=gd>d?e(ejj                  ejj                  d4'       G d@ dAejf                               Z; ed=gdBe)e)ejj                  d4C       G dD dEejx                               Z= ed=gdFdG edHej|                  ej~                  dIJ      gdK e*dLM      iN       G dO dPejZ                               Z@ ed=gdQdRejj                  ejj                  dS!       G dT dUej                               ZB ed=gdVdWdKejj                  i!       G dX dYejn                               ZC ed=gdZd[dKe+i!       G d\ d]ej^                               ZDy^)_    )genericspermissionsstatusserializers)Response)PageNumberPagination)UserGroup)Q)timezone)extend_schemaOpenApiParameter)OpenApiTypes   )IsSuperAdminOrAdminIsSuperAdminOrOwnerOrCreatedByIsAdminRoleIsAdminOrOwnerOrCreatedBy)UserProfile)api_viewpermission_classes)logout)Session)LoginSessionr   )	UserListSerializerUserDetailSerializerRoleSerializerUserProfileUpdateSerializerUserProfileDetailSerializerChangePasswordSerializerTwoFactorSettingsSerializerLoginSessionSerializerSecuritySettingsSerializerc                   "    e Zd ZdZdZdZdZd Zy)UserPaginationz"Custom pagination for user listing   	page_sized   c                    t        dd| j                  j                  j                  | j                  j                  j                  | j                  j
                  | j                         | j                         |d      S )NTzUsers retrieved successfully)successmessagecount
page_countcurrent_pagenextpreviousresults)r   page	paginatorr,   	num_pagesnumberget_next_linkget_previous_link)selfdatas     /backend/users/views/users.pyget_paginated_responsez%UserPagination.get_paginated_response   sh    5YY((..))--77 II,,&&(..0	
 	 		    N)__name__
__module____qualname____doc__r'   page_size_query_parammax_page_sizer;    r<   r:   r%   r%      s    ,I'M
r<   r%   c                        e Zd ZdZeZeZegZ	 e
ddd edej                  ej                  d       edej                  ej                  d	      gd
 ed      idg       fd       Zd Z xZS )UserListViewzLAPI View to get users (Super Admin = all users, Admin = hierarchical access)
list_userszGet All UserszMSuper Admins see all users, Admins see only accessible users (own + created).	is_activez$Filter by active status (true/false)nametypelocationdescriptionsearchz3Search in username, first name, last name, or email   TmanyUser Management)operation_idsummaryrL   
parameters	responsestagsc                 *    t        |   |g|i |S Nsuperlistr8   requestargskwargs	__class__s       r:   getzUserListView.get/   s    , w|G5d5f55r<   c                    | j                   j                  }	 |j                  }|j                  r.t        j
                  j                         j                  d      }n~|j                  g}t        j
                  j                  |      j                  dd      }|j                  |       t        j
                  j                  |      j                  d      }| j                   j"                  j%                  d	d
      }|#|j                  |j'                         dk(        }| j                   j"                  j%                  dd
      }|B|j                  t)        |      t)        |      z  t)        |      z  t)        |      z        }|S # t        j                  $ r |j                  j                  d      j                         r|j                  g}t        j
                  j                  |      j                  dd      }|j                  |       t        j
                  j                  |      j                  d      }nt        j
                  j!                         }Y w xY w)z'Return users based on user's privileges-date_joinedprofile__created_byidTflatid__inAdmin)rI   rG   NtruerG   rM   )username__icontains)first_name__icontains)last_name__icontains)email__icontains)r]   userprofilesuper_adminr	   objectsallorder_byrf   filtervalues_listextendr   DoesNotExistgroupsexistsnonequery_paramsra   lowerr   )r8   current_userrs   querysetaccessible_user_idscreated_usersrG   rM   s           r:   get_querysetzUserListView.get_querysetG   s   ||((	/"**G""<<++-66~F (4&7# $ 3 3(4 !4 !+d+.  $**=9<<..6I.JSSTbc LL--11+tD	 1Bf1LMH**..x>f-/0v./ 6*+H 5 '' 
	/""))w)7>>@'3&7# $ 3 3(4 !4 !+d+.  $**=9<<..6I.JSSTbc<<,,.
	/s   CF CI10I1)r=   r>   r?   r@   r   serializer_classr%   pagination_classr   r   r   r   r   BOOLQUERYSTRra   r   __classcell__r`   s   @r:   rE   rE   )   s    V)%-.!c !&&)//B	 !%%)//Q	
 *56 '*6+*6,r<   rE   c                       e Zd ZdZej
                  j                         ZeZ	e
egZdZ eddddeidg      d	        Zy
)UserDetailViewz'API View to get individual user detailsrf   retrieve_userzGet User DetailszYRetrieve user details. Super Admins can access any user, Admins have hierarchical access.rN   rQ   rR   rS   rL   rU   rV   c                     	 | j                         }| j                  |      }t        dd|j                  d      S # t        j
                  $ r" t        ddd dt        j                        cY S w xY w)NTz#User details retrieved successfullyr*   r+   r9   FzUser not found or access deniedr   )
get_objectget_serializerr   r9   r	   r{   r   HTTP_404_NOT_FOUNDr8   r]   r^   r_   instance
serializers         r:   retrievezUserDetailView.retrieve|   s    	1(H,,X6J@"  
    	1 < //	1 1	1s   9< 2A10A1N)r=   r>   r?   r@   r	   ru   rv   r   r   r   r   r   r   lookup_fieldr   r   rC   r<   r:   r   r   u   s]    1||!H+-/MNL$"o,- 11r<   r   c            	       j     e Zd ZdZeZeZegZ	 e
dddd ed      idg	       fd
       Zd Z xZS )ActiveUsersViewz!API View to get only active userslist_active_userszGet Active Users OnlyzXGet active users. Super Admins see all active users, Admins see accessible active users.rN   TrO   rQ   r   c                 *    t        |   |g|i |S rX   rY   r\   s       r:   ra   zActiveUsersView.get   s     w|G5d5f55r<   c                 X   | j                   j                  }	 |j                  }|j                  r1t        j
                  j                  d      j                  d      }|S |j                  g}t        j
                  j                  |      j                  dd      }|j                  |       t        j
                  j                  |d      j                  d      }	 |S # t        j                  $ r3 t        j
                  j                  d      j                  d      }Y |S w xY w)NTrm   rc   rd   rf   rg   )rj   rG   )r]   rr   rs   rt   r	   ru   rx   rw   rf   ry   rz   r   r{   )r8   r   rs   r   r   r   s         r:   r   zActiveUsersView.get_queryset   s   ||((	T"**G""<<...>GGW   (4&7# $ 3 3(4 !4 !+d+.  $**=9<<..." /  (>*  	 '' 	T||**T*:CCNSH		Ts   AC# !A?C# #AD)(D))r=   r>   r?   r@   r   r   r%   r   r   r   r   ra   r   r   r   s   @r:   r   r      sT    +)%-.('n*56 66r<   r   c                        e Zd ZdZej
                  j                         ZeZ	e
j                  gZ eddd ed      ej                  ddg	       fd
       Z xZS )RoleListViewz#API View to get all available roles
list_roleszGet All Rolesz3Retrieve a list of all available user roles/groups.TrO   rN     rQ   r   c                 *    t        |   |g|i |S rX   rY   r\   s       r:   ra   zRoleListView.get   s     w|G5d5f55r<   )r=   r>   r?   r@   r
   ru   rv   r   r   r   r   IsAuthenticatedr   r   r   OBJECTra   r   r   s   @r:   r   r      sk    -}}  "H%%556!IT*$$
   	6	6r<   r   c                       e Zd ZdZej
                  j                         ZeZ	e
j                  e
j                  gZdZ eddddddd	d
diddidieej"                  ej"                  ddg      d        Zy)UserRoleUpdateViewzAPI View to update user rolesrf   update_user_roleszUpdate User Rolesz-Update the roles assigned to a specific user.zapplication/jsonobjectrole_idsarrayrJ   integerz'Array of role IDs to assign to the user)rJ   itemsrL   rJ   
properties)rN     r   rQ   )rR   rS   rL   r]   rU   rV   c                 \   | j                         }|j                  j                  dg       }|j                  j	                          |r;t
        j                  j                  |      }|j                  j                  |       | j                  |      }t        dd|j                  d      S )Nr   ri   TzUser roles updated successfullyr   )r   r9   ra   r|   clearr
   ru   rx   setr   r   )r8   r]   r^   r_   rr   r   rolesr   s           r:   patchzUserRoleUpdateView.patch   s    0  <<##J3 	MM(((9EKKOOE"((.
8OO
  	r<   N)r=   r>   r?   r@   r	   ru   rv   r   r   r   r   r   IsAdminUserr   r   r   r   r   r   rC   r<   r:   r   r      s    '||!H+%55{7N7NOL(#C  '"()!4'P!	!
 &$$$$

   +./.r<   r   zUser Profile&Get current user's profile informationz=Retrieve complete profile information for the logged-in user.r   )rV   rS   rL   rU   c                   :    e Zd ZdZeZej                  gZd Z	d Z
y)CurrentUserProfileViewr   c                 .    | j                   j                  S rX   r]   rr   r8   s    r:   r   z!CurrentUserProfileView.get_object      ||   r<   c                 v    | j                         }| j                  |      }t        dd|j                  d      S )NTz#User profile retrieved successfullyr   r   r   r   r9   r   s         r:   r   zCurrentUserProfileView.retrieve  s=    ??$((2
<OO
  	r<   N)r=   r>   r?   r@   r   r   r   r   r   r   r   rC   r<   r:   r   r      s&     12%556!r<   r   )Update current user's profile informationzoUpdate profile information for the logged-in user including personal details, company info, and profile images.)rN     r   )rV   rS   rL   r]   rU   c                   :    e Zd ZdZeZej                  gZd Z	d Z
y)UpdateUserProfileViewr   c                 .    | j                   j                  S rX   r   r   s    r:   r   z UpdateUserProfileView.get_object)  r   r<   c                    | j                         }| j                  ||j                  d      }|j                         r4|j	                         }t        |      }t        dd|j                  d      S t        dd|j                  dd	      S )
NTr9   partialzProfile updated successfullyr   FzValidation errorr*   r+   errorsr   r   )r   r   r9   is_validsaver   r   r   )r8   r]   r^   r_   r   r   updated_userresponse_serializers           r:   postzUpdateUserProfileView.post,  s    ??$((d(S
 %??,L #>l"K9+00   ) ''
 	 	r<   N)r=   r>   r?   r@   r   r   r   r   r   r   r   rC   r<   r:   r   r     s&     42%556!r<   r   zUpload and update profile imagez;Upload a new profile image and update the user's image_url.zmultipart/form-datar   	image_urlstringurizURL of the uploaded image)rJ   formatrL   r   )rN   r   c                   N    e Zd ZdZej
                  Zej                  gZ	d Z
d Zy)UpdateProfileImageViewzUpdate user's profile imagec                 .    | j                   j                  S rX   r   r   s    r:   r   z!UpdateProfileImageView.get_object[  r   r<   c                 8   | j                         }|j                  j                  d      }|st        dddd      S t        j
                  j                  |      \  }}||_        |j                          t        |      }t        dd	|j                  d
      S )Nr   Fzimage_url is requiredr*   r+   r   r   rr   Tz"Profile image updated successfullyr   )
r   r9   ra   r   r   ru   get_or_creater   r   r   )	r8   r]   r^   r_   rr   r   rs   createdr   s	            r:   r   zUpdateProfileImageView.post^  s     LL$$[1	 2   '..<<$<G% :$?;',,
  	r<   Nr=   r>   r?   r@   r   
Serializerr   r   r   r   r   r   rC   r<   r:   r   r   A  s,    , &"--%556!r<   r   zUpload and update company logozAUpload a new company logo and update the user's company_logo_url.company_logo_urlz URL of the uploaded company logoc                   N    e Zd ZdZej
                  Zej                  gZ	d Z
d Zy)UpdateCompanyLogoViewzUpdate user's company logoc                 .    | j                   j                  S rX   r   r   s    r:   r   z UpdateCompanyLogoView.get_object  r   r<   c                 8   | j                         }|j                  j                  d      }|st        dddd      S t        j
                  j                  |      \  }}||_        |j                          t        |      }t        dd	|j                  d
      S )Nr   Fzcompany_logo_url is requiredr   r   r   r   Tz!Company logo updated successfullyr   )
r   r9   ra   r   r   ru   r   r   r   r   )	r8   r]   r^   r_   rr   logo_urlrs   r   r   s	            r:   r   zUpdateCompanyLogoView.post  s     <<##$67 9   '..<<$<G#+  :$?:',,
  	r<   Nr   rC   r<   r:   r   r   u  s,    , %"--%556!r<   r   zUser SecurityChange user passwordz5Change the password for the currently logged-in user.c                   :    e Zd ZdZeZej                  gZd Z	d Z
y)ChangePasswordViewr   c                 .    | j                   j                  S rX   r   r   s    r:   r   zChangePasswordView.get_object  r   r<   c                    | j                  |j                        }|j                         r|j                          |j                  j
                  }|rKt        j                  j                  |j                  d      j                  |      j                  d       t        ddd      S t        dd	|j                  d
d      S )N)r9   Trr   rG   session_keyFrm   zJPassword changed successfully. Please log in again with your new password.r   zPassword change failedr   r   r   )r   r9   r   r   sessionr   r   ru   rx   rr   excludeupdater   r   )r8   r]   r^   r_   r   current_session_keys         r:   r   zChangePasswordView.update  s    ((gll(;
 OO #*//"="="$$++ " ,  '&9':66E6;Rg  
 / ''
 	 	r<   N)r=   r>   r?   r@   r    r   r   r   r   r   r   rC   r<   r:   r   r     s&     /%556!r<   r   zGet/Update 2FA settings)rV   rS   r]   rU   c                   @    e Zd ZdZeZej                  gZd Z	d Z
d Zy)TwoFactorSettingsViewzGet and update 2FA settingsc                 t    t         j                  j                  | j                  j                        \  }}|S Nr   r   ru   r   r]   rr   r8   rs   r   s      r:   r   z TwoFactorSettingsView.get_object  /    &..<<$,,BSBS<Tr<   c                 t    | j                         }| j                  |      }t        d|j                  d      S NT)r*   r9   r   r   s         r:   r   zTwoFactorSettingsView.retrieve  s:    ??$((2
OO
  	r<   c                    | j                         }| j                  ||j                  d      }|j                         r)|j	                          t        dd|j                  d      S t        d|j                  dd      S )	NTr   z!2FA settings updated successfullyr   F)r*   r   r   r   )r   r   r9   r   r   r   r   r   s         r:   r   zTwoFactorSettingsView.update  s    ??$((d(S
 OO>"    ''
  	r<   N)r=   r>   r?   r@   r!   r   r   r   r   r   r   r   rC   r<   r:   r   r     s+     &2%556r<   r   Get user's login sessionsz6Get a list of all login sessions for the current user.active_onlyz#Filter to show only active sessionsrH   rN   TrO   )rV   rS   rL   rT   rU   c                   :    e Zd ZdZeZej                  gZd Z	d Z
y)LoginSessionsListViewr   c                    t         j                  j                  | j                  j                        }| j                  j
                  j                  dd      j                         dk(  }|r|j                  d      }|S )Nr   r    rl   Trm   )r   ru   rx   r]   rr   r   ra   r   )r8   r   r   s      r:   r   z"LoginSessionsListView.get_queryset  sj    ''..DLL4E4E.F ll//33M2FLLNRXX6Hr<   c                     | j                         }| j                  |d      }t        dd|j                         |j                  d      S )NTrO   z%Login sessions retrieved successfully)r*   r+   r,   r9   )r   r   r   r,   r9   )r8   r]   r^   r_   r   r   s         r:   r[   zLoginSessionsListView.list  sN    $$&(((=
>^^%OO	
  	r<   N)r=   r>   r?   r@   r"   r   r   r   r   r   r[   rC   r<   r:   r   r      s&     $-%556	r<   r   z"Terminate a specific login sessionz1Terminate a specific login session by session ID.)rN   r   c                   0    e Zd ZdZej
                  gZd Zy)TerminateSessionViewzTerminate a specific sessionc                    	 t         j                  j                  ||j                        }d|_        t        j                         |_        |j                          	 t        j                  j                  |j                        }|j                          t        ddd      S # t        j                  $ r Y #w xY w# t         j                  $ r t        dddd	      cY S w xY w)
N)rf   rr   Fr   TzSession terminated successfullyr   zSession not foundr   r   )r   ru   ra   rr   rG   r   nowlogout_timer   r   r   deleter{   r   )r8   r]   
session_idr^   r_   login_sessiondjango_sessions          r:   r  zTerminateSessionView.delete5  s    	(0044\\ 5 M ',M#(0M% !(!4!4AZAZ!4![%%' <   ''  (( 	 .  	s6   AB? :B& B? &B<9B? ;B<<B? ?#C%$C%N)r=   r>   r?   r@   r   r   r   r  rC   r<   r:   r  r  (  s     '%556r<   r  zTerminate all other sessionsz4Terminate all login sessions except the current one.c                   0    e Zd ZdZej
                  gZd Zy)TerminateAllOtherSessionsViewz+Terminate all other sessions except currentc                    |j                   j                  }t        j                  j	                  |j
                  d      }|r|j                  |      }|j                  dt        j                               }|D ]=  }	 t        j                  j                  |j                        }|j                          ? t        dd| dd      S # t        j                  $ r Y gw xY w)	NTr   r   F)rG   r  zTerminated z other sessions successfullyr   )r   r   r   ru   rx   rr   r   r   r   r  r   ra   r  r{   r   )	r8   r]   r^   r_   r   other_sessionsterminated_countr
  r  s	            r:   r   z"TerminateAllOtherSessionsView.post]  s    %oo99 &--44 5 

 +33@S3TN *00  1 
 ,M!(!4!4AZAZ!4![%%' , $%5$66RS
  	 '' s   :CC%$C%N)r=   r>   r?   r@   r   r   r   r   rC   r<   r:   r  r  S  s     6%556r<   r  Get security overviewz@Get an overview of user's security settings and active sessions.c                   :    e Zd ZdZeZej                  gZd Z	d Z
y)SecurityOverviewViewr  c                 t    t         j                  j                  | j                  j                        \  }}|S r   r   r   s      r:   r   zSecurityOverviewView.get_object  r   r<   c                 t    | j                         }| j                  |      }t        d|j                  d      S r   r   r   s         r:   r   zSecurityOverviewView.retrieve  s:    ??$((2
OO
  	r<   N)r=   r>   r?   r@   r#   r   r   r   r   r   r   rC   r<   r:   r  r  |  s&      1%556r<   r  N)Erest_frameworkr   r   r   r   rest_framework.responser   rest_framework.paginationr   django.contrib.auth.modelsr	   r
   django.db.modelsr   django.utilsr   drf_spectacular.utilsr   r   drf_spectacular.typesr   r   r   r   r   modelsr   rest_framework.decoratorsr   r   django.contrib.authr   django.contrib.sessions.modelsr   r   r   r   r   r   r   r    r!   r"   r#   r%   ListAPIViewrE   RetrieveAPIViewr   r   r   UpdateAPIViewr   r   r   CreateAPIViewr   r   r   r   RetrieveUpdateAPIViewr   r   r   r   DestroyAPIViewr  r  r  rC   r<   r:   <module>r(     s   E E , : 2  ! A . t t   B & 2 A . .  ) $J8'' JX1X-- 1<(h** (T68'' 6&-// -^ 
	4O(  	X55 " 
	7 B'(    
H22 
: 
	-M$##>	 
 )  !*X33 +*> 
	,S"$##E%	 
 )  !*H22 +*> 
	"G$    	 //  	 D 
	%'(  	 H::   D 
	'H""%++=		
 *56H00 4 
	0C    	 822   D 
	*FL''(	!H$:$: !!F 
	#R./	833 r<   