m $Ec@s'dZdkZdkZdkZdklZdklZdkl Z l Z dk l Z l Z lZlZdk lZdklZdklZd klZd klZlZd klZdkZdkZd kl Z d k!l"Z"l#Z#dk$l%Z%l&Z&dk'l(Z(dk'l)Z)dk'l*Z*dk+l,Z,gZ-defdYZ.de.fdYZ/de/fdYZ0de/efdYZ1de0fdYZ2de0fdYZ3dZ4d Z5e4d!Z6e6o2e6d"Z5e2e6d e6d#d$fe6d%Z7n e3Z7e7Z8[6e0d&d'd(fgZ9e2d)d'd$fgZ:e9e_9e:e_:e7e_7e7e_8d*eee e e%efd+YZ;d,e;fd-YZ<ee<e=e=d.Z>d/Z?ei@d0iAZBei@d1iAZCd2ZDd3ZEd4ZFe2ZGdS(5sHAccess control package. $Id: User.py 40300 2005-11-21 16:54:03Z efge $ N(s decodestring(sImplicit(s NavigationsTabs(sDTMLFiles MessageDialogs PersistentsPersistentMapping(sInitializeClass(sClassSecurityInfo(s manage_users(sItem(s Unauthorizeds BadRequest(s implements(sIStandardUserFolder(s_what_not_even_god_should_dosrolesForPermissionOn(s RoleManagersDEFAULTMAXLISTUSERS(sgetSecurityManager(snewSecurityManager(snoSecurityManager(s_norolest BasicUsercBstZdZedZdZdZdZdZdZ dZ dZ d Z d Z d Zed Zd ZgZedZdZdZdZdZRS(sBase class for all User objectscCsd }||jodSnd S( Ntnamet__trolestdomainst _getPasswordt authenticatet _shared_rolesii(snames__srolessdomainss _getPasswords authenticates _shared_roles(t deny_namesR(tselfRtvalueR((t1/data/zmath/zope/lib/python/AccessControl/User.pyt*__allow_access_to_unprotected_subobjects__?s cCs tdS(N(tNotImplementedError(R RtpasswordRR((R t__init__FscCs tdS(sReturn the username of a userN(R (R ((R t getUserNameIscCs |iS(s~Get the ID of the user. The ID can be used, at least from Python, to get the user from the user's UserDatabaseN(R R(R ((R tgetIdMscCs tdS(s Return the password of the user.N(R (R ((R RSscCs tdS(s,Return the list of roles assigned to a user.N(R (R ((R tgetRolesWsc Cs.|i}|i}h} t|d|}xt|dd}|oRt |o |}n|ph}x(|i |gD]}d| |(R t __class__t__name__R(R ((R t__repr__s(RLt __module__t__doc__RR RRRRRR&R'RRR5R<RBRRERHRIRJRM(((R R.s(            @     t SimpleUsercBs;tZdZdZdZdZdZdZRS(sNA very simple user implementation that doesn't make a database commitmentcCs(||_||_||_||_dS(N(RR RRRR(R RRRR((R R"s   cCs|iS(sReturn the username of a userN(R R(R ((R R(scCs|iS(s Return the password of the user.N(R R(R ((R R,scCs6|idjot|iSnt|idSdS(s,Return the list of roles assigned to a user.sAnonymous UserR6N(s Authenticated(R RttupleR(R ((R R0scCs t|iS(s1Return the list of domain restrictions for a userN(RQR R(R ((R R'5s(RLRNRORRRRR'(((R RPs     t SpecialUsercBstZdZdZRS(s7Class for special users, like emergency user and nobodycCsdS(N((R ((R R;s(RLRNROR(((R RR9s tUsercBstZdZRS(sStandard User object(RLRNRO(((R RS=s tUnrestrictedUsercBs8tZdZedZdZedZdZRS(sxUser that passes all security checks. Note, however, that modules like Owner.py can still impose restrictions. cCs |tj S(N(RR8(R R"R((R R<DscOs-dk}|idt|i||dS(shasRole is an alias for 'allowed' and has been deprecated. Code still using this method should convert to either 'has_role' or 'allowed', depending on the intended behaviour. NsUnrestrictedUser.hasRole is deprecated, please use UnrestrictedUser.allowed instead; hasRole was an alias for allowed, but you may have ment to use has_role.(R=R>R?R R<R@RA(R R@RAR=((R RBGs   cCsdS(Ni((R RR((R REUscCsdS(Ni((R RGR((R RHWs(RLRNRORR<RBRERH(((R RT@s    tNullUnrestrictedUsercBswtZdZdZdZdZeZdZeZdZ dZ e dZ dZ e d Zd ZRS( sUser created if no emergency user exists. It is only around to satisfy third party userfolder implementations that may expect the emergency user to exist and to be able to call certain methods on it (in other words, backward compatibility). Note that when no emergency user is installed, this object that exists in its place is more of an anti-superuser since you cannot login as this user and it has no priveleges at all.icCsdS(N((R ((R RfscCsdS(N(NN(R(R ((R RiscCsfS(N((R ((R RnscCsfS(N((R R((R R&rscCsdS(Ni((R RR-((R RuscCsdS(Ni((R R"R((R R<xscOs-dk}|idt|i||dS(shasRole is an alias for 'allowed' and has been deprecated. Code still using this method should convert to either 'has_role' or 'allowed', depending on the intended behaviour. NsNullUnrestrictedUser.hasRole is deprecated, please use NullUnrestrictedUser.allowed instead; hasRole was an alias for allowed, but you may have ment to use has_role.(R=R>R?R R<R@RA(R R@RAR=((R RB{s   cCsdS(Ni((R RR((R REscCsdS(Ni((R RGR((R RHs(RLRNROt __null_user__RRRRR'R&RRR<RBRERH(((R RUZs         cCsdk}|ii}y;ttii|i |d}|i }|iWntj o dSnX|oc|iid}|d }y|did}Wn g}nX|d|d||fSndSdS(shReads an access file from the instance home. Returns name, password, domains, remote_user_mode. NR t:iit i(t App.configtApptconfigtgetConfigurationtcfgtopentostpathtjoint instancehometfilenametftreadlinetlinetclosetIOErrorRtstriptsplittdatatremote_user_modetds(RcRlRdR]RZRkRfRm((R treadUserAccessFiles$ !    itaccessiitmanageisAnonymous UsertR/sSystem ProcessestBasicUserFoldercBs*tZdZdZdZdZdZdZeZ dZ e Z hdd<dd<ddAd:Z?d;Z@d<ZAd=ZBe ied>d?ZCd@ZDRS(Cs&Base class for UserFolder-like objectss User Foldert acl_usersitlabeltContentstactiont manage_mainthelptOFSPsUser-Folder_Contents.stxt Propertiestmanage_userFolderPropertiessUser-Folder_Properties.stxt getUserNamescCs tdS(sReturn a list of usernamesN(R (R ((R R|stgetUserscCs tdS(sReturn a list of user objectsN(R (R ((R R}stgetUsercCs tdS(s$Return the named user object or NoneN(R (R R((R R~st getUserByIdcCs(|i|}|djo|Sn|S(s7Return the user corresponding to the given id. N(R R~tidtuserRtdefault(R RRR((R Rs  cKs tdS(sCreate a new user. This should be implemented by subclasses to do the actual adding of a user. The 'password' will be the original input password, unencrypted. The implementation of this method is responsible for performing any needed encryption.N(R (R RRRRRA((R t _doAddUserscKs tdS(s Modify an existing user. This should be implemented by subclasses to make the actual changes to a user. The 'password' will be the original input password, unencrypted. The implementation of this method is responsible for performing any needed encryption.N(R (R RRRRRA((R t _doChangeUserscCs tdS(sqDelete one or more users. This should be implemented by subclasses to do the actual deleting of users.N(R (R tnames((R t _doDelUsers stuserFolderAddUsercKs7t|do|i|||||SntdS(sAPI method for creating a new user object. Note that not all user folder implementations support dynamic creation of user objects.RN( R#R RRRRRRAR (R RRRRRA((R RstuserFolderEditUsercKs7t|do|i|||||SntdS(sAPI method for changing user object attributes. Note that not all user folder implementations support changing of user object attributes.RN( R#R RRRRRRAR (R RRRRRA((R R"stuserFolderDelUserscCs+t|do|i|SntdS(sAPI method for deleting one or more user objects. Note that not all user folder implementations support deletion of user objects.RN(R#R RRR (R R((R R+sicCs{|ol|iidoVy5tt|iddidd\}}WntdnX||fSndSdS(Nsbasic RXiRWisInvalid authentication token(NN( tauthtlowert startswithRQt decodestringRjRRt BadRequestR(R RRR((R tidentify?s5 cCs|i}|djodSn|o||ijo |}n|i|}|dj o|i||o|SndSdS(N( R t_emergency_usert emergencyRRRRR~RRR-(R RRR-RR((R RIs    cCst|d|i|}td|t}yryZ|t jo%|i ||||odSqn%|i |||||odSnWntnXWntj onXdS(Ntaq_baseii(RRt__of__R tnewSecurityManagerRtgetSecurityManagertsecurityRt_norolestvalidatetaccessedt containerRR tnoSecurityManagert Unauthorized(R RRRRR RR((R t authorizeVs"       Rqc Cs|d} |i| |\}}}} |p|io|xy|i D]g} | i oT|i | i d|o4|i| |||| |o| i|SqqqFqFWqn|i|\}} |i || |} |i}|o3| |jo&|io|i|SqdSn| djoK|io6|i|i|||| |o|ii|SqdSnx|i| |||| |o| i|SnH|io6|i|i|||| |o|ii|SndSdS(s this method performs identification, authentication, and authorization v is the object (value) we're validating access to n is the name used to access the object a is the object the object was accessed through c is the physical container of the object We allow the publishing machinery to defer to higher-level user folders or to raise an unauthorized by returning None from this method. t PUBLISHEDRqN(R-tvR t _getobcontexttatctnRt_domain_auth_modeR}RR'RRRRRRRRRRt_isTopRt_nobody( R R-RRRRRRRRRR((R Rms6     %   //c Cs|d} |i| |\}}}} |iidd}|djo|i o|xy|i D]g} | ioT|i| id|o4|i| |||| |o| i|SqqqaqaWqn|i|} |i}|o9||ijo&|io|i|SqdSn| djoK|io6|i|i|||| |o|ii|SqdSnx|i| |||| |o| i|SnH|io6|i|i|||| |o|ii|SndSdS(NRt REMOTE_USERRq(R-RR RRRRtenvironRRRRR}RR'RRRRRR~RRRR( R R-RRRRRRRRR((R Rs6     %   /c Cst|idjo|iidn|id}|dd}}t|d|}t|dd}|dj o |}n0t |do|i}t|d|}nt|dddg}||jo|dd}n||jo|dd}n||||fS( s v is the object (value) we're validating access to n is the name used to access the object a is the object the object was accessed through c is the physical container of the object is8no default view (root default view was probably deleted)itPARENTSRRRN(tlenR-tstepstRESPONSEt notFoundErrorRRRRRR!Rt innerparentR#Rtrequest_container( R RR-RRRR!RR((R Rs$      cCs#y|iiiSWn dSnXdS(Ni(R RRt$isTopLevelPrincipiaApplicationObject(R ((R RscCsdS(Ni((R ((R RIss dtml/mainUsers dtml/addUsertremote_user_mode__s dtml/editUsersdtml/userFolderPropscCs|i||d|ddS(s tmanage_tabs_messagetmanagement_viewRzN(R t_userFolderPropertiestREQUESTR(R RR((R R{sc Cs8| |_yt||_Wntj ot|_nX|o|od}xu|iD]g}|i }|i |pE|i |}|i|i||i|i|d}q^q^W|dj o2|p d}n d|}|i|d|Sq4|Sn%|dj o|i|ddSndS(s9 Sets the properties of the user folder. iis All passwords already encrypted.sEncrypted %d password(s).RsSaved changes.N(tencrypt_passwordsR tintt maxlistuserst ValueErrortDEFAULTMAXLISTUSERStupdate_passwordstchangedR}tuRtpwt_isPasswordEncryptedt_encryptPasswordRRRR'RRtmsgR{( R RRRRRRRR((R tmanage_setUserFolderPropertiess0        cCs ti|S(N(R)t is_encryptedR(R R((R R@scCsti|dS(NtSSHA(R)t pw_encryptR(R R((R RCscCsOxH|D]@}t|}t|}|djo|djodSqqWdS(Nii(tspectobt addr_matchtamt host_matchthmR(R RRRR((R tdomainSpecValidateGs   cCsm|ptddddddSn| p| o(|ptddddddSq\n|i|p |io3||iijotddddddSn|p|o*||jotdddd ddSn|p g}n|p g}n|o.|i | otdddd ddSn|i |||||o|i ||SndS( Nttitles Illegal valuetmessagesA username must be specifiedRvRws+Password and confirmation must be specifieds-A user with the specified name already existss&Password and confirmation do not matchsIllegal domain specification(Rt MessageDialogRtconfirmRR R~RRRRRRt _mainUser(R RRRRRR((R t_addUserTs8  0     cCs|djo|djod}}n|ptddddddSn||jo d jno(|ptdddd ddSqn|i|ptdddd ddSn|p|o*||jotdddd ddSn|p g}n|p g}n|o.|i | otdddd ddSn|i |||||o|i ||SndS(NRtpconfirmRs Illegal valueRsA username must be specifiedRvRwRqs+Password and confirmation must be specifieds Unknown users&Password and confirmation do not matchsIllegal domain specification( RRRRRRR R~RRRRR(R RRRRRR((R t _changeUserxs<       cCsP|ptddddddSn|i||o|i||SndS(NRs Illegal valueRsNo users specifiedRvRw(RRR RRR(R RR((R t _delUserss  t manage_usersc Cs|djo|i||Sn|djoby|it|d} Wn tdddddd SnX|i||d | d | i Sn|d jokt|d}t|d } t|d }t|d}t|d}|i|| ||||Sn|djokt|d}t|d } t|d }t|d}t|d}|i|| ||||Sn|djo#t|d}|i||Sn|i||S(sThis method handles operations on users for the web based forms of the ZMI. Application code (code that is outside of the forms that implement the UI of a user folder) are encouraged to use manage_std_addUsersAdd...tEditRRs Illegal valueRs!The specified user does not existRvRwRRtAddRRRtChangetDeleteRN(tsubmitR t _add_UserRR~treqattrRRt _editUserRRRRRRRRRRR( R RRRRRRRRRR((R Rs<   #    t user_namescCs |iS(N(R R|(R ((R RscCs)||joy |`Wq%q%XndS(N(titemR Rt__allow_groups__(R RR((R tmanage_beforeDeletes   cCs;||jo*t|do |i}n||_ndS(NR(RR R#RRR(R RR((R tmanage_afterAdds  cCsdS(Ni((R ((R t__creatable_by_emergency_user__scCs3||ijotddddddndS(NRs Invalid IdRs$Cannot change the id of a UserFolderRvs ./manage_main(RR R(R R((R t_setIds tsetDomainAuthenticationModecCs#|odpd}|_d|S(ssSet the domain-based authentication mode. By default, this mode is off due to the high overhead of the operation that is incurred for all anonymous accesses. If you have the 'Manage Users' permission, you can call this method via the web, passing a boolean value for domain_auth_mode to turn this behavior on or off.iis$Domain authentication mode set to %dN(tdomain_auth_modeRR R(R RR((R RscCst|ddS(s0 returns true if domain auth mode is set to trueRN(RR R(R ((R tdomainAuthModeEnableds(RysUser-Folder_Contents.stx(RysUser-Folder_Properties.stx(ERLRNROt meta_typeRRtisPrincipiaFolderisht isAUserFolderRRRtClassSecurityInfoRt RoleManagertmanage_optionstItemtdeclareProtectedt ManageUsersR|R}R~RRRRRRRRt_remote_user_modeRtemergency_userRt_supertnobodyRRRRRRRRRItDTMLFiletglobalsRRRRpRwt_setNameRR{RRRRRRRRRRRRRRR(((R Rrs  P          ?3 !        #   $ % '      t UserFoldercBstZdZeedZdZdZdZdZ dZ dZ dZ dZ d Zd Zd Zd ZRS( sStandard UserFolder object A UserFolder holds User objects which contain information about users including name, password domain, and roles. UserFolders function chiefly to control access by authenticating users and binding them to a collection of roles.s User FolderRss p_/UserFoldercCst|_dS(N(tPersistentMappingR Rk(R ((R R scCs|ii}|i|S(sReturn a list of usernamesN(R RkR%Rtsort(R R((R R| s cCsB|i}|i}|ig}|D]}|||q*~S(sReturn a list of user objectsN(R RkR%RRt_[1]R(R RRkRR((R R}s    cCs|ii|dS(s$Return the named user object or NoneN(R RkRRR(R R((R R~scCst|i S(s: This is not a formal API method: it is used only to provide a way for the quickstart page to determine if the default user folder contains any users to provide instructions on how to add a user for newbies. Using getUserNames or getUsers would have posed a denial of service risk.N(RR Rk(R ((R thasUsersscKs[|dj o.|io$|i| o|i|}nt|||||i |