1- #$Id: actions.py,v 1.35 2004-07-20 02:07:58 richard Exp $
1+ #$Id: actions.py,v 1.36 2004-07-28 02:29:45 richard Exp $
22
33import re , cgi , StringIO , urllib , Cookie , time , random
44
@@ -53,10 +53,13 @@ def permission(self):
5353 raise Unauthorised , self ._ ('You do not have permission to '
5454 '%(action)s the %(classname)s class.' )% info
5555
56- def hasPermission (self , permission ):
56+ _marker = []
57+ def hasPermission (self , permission , classname = _marker ):
5758 """Check whether the user has 'permission' on the current class."""
59+ if classname is self ._marker :
60+ classname = self .client .classname
5861 return self .db .security .hasPermission (permission , self .client .userid ,
59- self . client . classname )
62+ classname )
6063
6164 def gettext (self , msgid ):
6265 """Return the localized translation of msgid"""
@@ -314,46 +317,8 @@ def handle(self):
314317
315318 self .client .ok_message .append (self ._ ('Items edited OK' ))
316319
317- class _EditAction (Action ):
318- def isEditingSelf (self ):
319- """Check whether a user is editing his/her own details."""
320- return (self .nodeid == self .userid
321- and self .db .user .get (self .nodeid , 'username' ) != 'anonymous' )
322-
323- def editItemPermission (self , props ):
324- """Determine whether the user has permission to edit this item.
325-
326- Base behaviour is to check the user can edit this class. If we're
327- editing the "user" class, users are allowed to edit their own details.
328- Unless it's the "roles" property, which requires the special Permission
329- "Web Roles".
330- """
331- if self .classname == 'user' :
332- if props .has_key ('roles' ) and not self .hasPermission ('Web Roles' ):
333- raise Unauthorised , self ._ (
334- "You do not have permission to edit user roles" )
335- if self .isEditingSelf ():
336- return 1
337- if self .hasPermission ('Edit' ):
338- return 1
339- return 0
340-
341- def newItemPermission (self , props ):
342- """Determine whether the user has permission to create (edit) this item.
343-
344- Base behaviour is to check the user can edit this class. No additional
345- property checks are made. Additionally, new user items may be created
346- if the user has the "Web Registration" Permission.
347-
348- """
349- if (self .classname == 'user' and self .hasPermission ('Web Registration' )
350- or self .hasPermission ('Edit' )):
351- return 1
352- return 0
353-
354- #
355- # Utility methods for editing
356- #
320+ class EditCommon :
321+ '''Utility methods for editing.'''
357322 def _editnodes (self , all_props , all_links , newids = None ):
358323 ''' Use the props in all_props to perform edit and creation, then
359324 use the link specs in all_links to do linking.
@@ -475,7 +440,38 @@ def _createnode(self, cn, props):
475440 cl = self .db .classes [cn ]
476441 return cl .create (** props )
477442
478- class EditItemAction (_EditAction ):
443+ def isEditingSelf (self ):
444+ """Check whether a user is editing his/her own details."""
445+ return (self .nodeid == self .userid
446+ and self .db .user .get (self .nodeid , 'username' ) != 'anonymous' )
447+
448+ def editItemPermission (self , props ):
449+ """Determine whether the user has permission to edit this item.
450+
451+ Base behaviour is to check the user can edit this class. If we're
452+ editing the "user" class, users are allowed to edit their own details.
453+ Unless it's the "roles" property, which requires the special Permission
454+ "Web Roles".
455+ """
456+ if self .classname == 'user' :
457+ if props .has_key ('roles' ) and not self .hasPermission ('Web Roles' ):
458+ raise Unauthorised , self ._ (
459+ "You do not have permission to edit user roles" )
460+ if self .isEditingSelf ():
461+ return 1
462+ if self .hasPermission ('Edit' ):
463+ return 1
464+ return 0
465+
466+ def newItemPermission (self , props ):
467+ """Determine whether the user has permission to create this item.
468+
469+ Base behaviour is to check the user can edit this class. No additional
470+ property checks are made.
471+ """
472+ return self .hasPermission ('Create' , self .classname )
473+
474+ class EditItemAction (EditCommon , Action ):
479475 def lastUserActivity (self ):
480476 if self .form .has_key (':lastactivity' ):
481477 d = date .Date (self .form [':lastactivity' ].value )
@@ -539,7 +535,7 @@ def handle(self):
539535 url += '&' + req .indexargs_href ('' , {})[1 :]
540536 raise Redirect , url
541537
542- class NewItemAction (_EditAction ):
538+ class NewItemAction (EditCommon , Action ):
543539 def handle (self ):
544540 ''' Add a new item to the database.
545541
@@ -677,28 +673,21 @@ def handle(self):
677673
678674 self .client .ok_message .append (self ._ ('Email sent to %s' ) % address )
679675
680- class ConfRegoAction (Action ):
681- def handle (self ):
682- """Grab the OTK, use it to load up the new user details."""
683- try :
684- # pull the rego information out of the otk database
685- self .userid = self .db .confirm_registration (self .form ['otk' ].value )
686- except (ValueError , KeyError ), message :
687- self .client .error_message .append (str (message ))
688- return
689-
676+ class RegoCommon :
677+ def finishRego (self ):
690678 # log the new user in
691- self .client .user = self .db .user .get (self .userid , 'username' )
679+ self .client .userid = self .userid
680+ user = self .client .user = self .db .user .get (self .userid , 'username' )
692681 # re-open the database for real, using the user
693- self .client .opendb (self . client . user )
682+ self .client .opendb (user )
694683
695684 # if we have a session, update it
696- if hasattr (self , 'session' ):
697- self .client .db .sessions .set (self .session , user = self . user ,
698- last_use = time .time ())
685+ if hasattr (self . client , 'session' ):
686+ self .client .db .getSessionManager () .set (self .client . session ,
687+ user = user , last_use = time .time ())
699688 else :
700689 # new session cookie
701- self .client .set_cookie (self . user )
690+ self .client .set_cookie (user )
702691
703692 # nice message
704693 message = self ._ ('You are now registered, welcome!' )
@@ -713,48 +702,80 @@ def handle(self):
713702 window.setTimeout('window.location = "%s"', 1000);
714703 </script>''' % (message , url , message , url )
715704
716- class RegisterAction (Action ):
705+ class ConfRegoAction (RegoCommon , Action ):
706+ def handle (self ):
707+ """Grab the OTK, use it to load up the new user details."""
708+ try :
709+ # pull the rego information out of the otk database
710+ self .userid = self .db .confirm_registration (self .form ['otk' ].value )
711+ except (ValueError , KeyError ), message :
712+ self .client .error_message .append (str (message ))
713+ return
714+ self .finishRego ()
715+
716+ class RegisterAction (RegoCommon , EditCommon , Action ):
717717 name = 'register'
718- permissionType = 'Web Registration '
718+ permissionType = 'Create '
719719
720720 def handle (self ):
721721 """Attempt to create a new user based on the contents of the form
722722 and then set the cookie.
723723
724724 Return 1 on successful login.
725725 """
726- props = self .client .parsePropsFromForm (create = 1 )[0 ][('user' , None )]
726+ # parse the props from the form
727+ try :
728+ props , links = self .client .parsePropsFromForm (create = 1 )
729+ except (ValueError , KeyError ), message :
730+ self .client .error_message .append (self ._ ('Error: %s' )
731+ % str (message ))
732+ return
727733
728734 # registration isn't allowed to supply roles
729- if props .has_key ('roles' ):
735+ user_props = props [('user' , None )]
736+ if user_props .has_key ('roles' ):
730737 raise Unauthorised , self ._ (
731738 "It is not permitted to supply roles at registration." )
732739
733- username = props ['username' ]
734- try :
735- self .db .user .lookup (username )
736- self .client .error_message .append (self ._ ('Error: A user with the '
737- 'username "%(username)s" already exists' )% props )
738- return
739- except KeyError :
740- pass
740+ # skip the confirmation step?
741+ if self .db .config ['INSTANT_REGISTRATION' ]:
742+ # handle the create now
743+ try :
744+ # when it hits the None element, it'll set self.nodeid
745+ messages = self ._editnodes (props , links )
746+ except (ValueError , KeyError , IndexError , exceptions .Reject ), \
747+ message :
748+ # these errors might just be indicative of user dumbness
749+ self .client .error_message .append (_ ('Error: %s' ) % str (message ))
750+ return
751+
752+ # fix up the initial roles
753+ self .db .user .set (self .nodeid ,
754+ roles = self .db .config ['NEW_WEB_USER_ROLES' ])
755+
756+ # commit now that all the tricky stuff is done
757+ self .db .commit ()
758+
759+ # finish off by logging the user in
760+ self .userid = self .nodeid
761+ return self .finishRego ()
741762
742763 # generate the one-time-key and store the props for later
743764 for propname , proptype in self .db .user .getprops ().items ():
744- value = props .get (propname , None )
765+ value = user_props .get (propname , None )
745766 if value is None :
746767 pass
747768 elif isinstance (proptype , hyperdb .Date ):
748- props [propname ] = str (value )
769+ user_props [propname ] = str (value )
749770 elif isinstance (proptype , hyperdb .Interval ):
750- props [propname ] = str (value )
771+ user_props [propname ] = str (value )
751772 elif isinstance (proptype , hyperdb .Password ):
752- props [propname ] = str (value )
773+ user_props [propname ] = str (value )
753774 otks = self .db .getOTKManager ()
754775 otk = '' .join ([random .choice (chars ) for x in range (32 )])
755776 while otks .exists (otk ):
756777 otk = '' .join ([random .choice (chars ) for x in range (32 )])
757- otks .set (otk , ** props )
778+ otks .set (otk , ** user_props )
758779
759780 # send the email
760781 tracker_name = self .db .config .TRACKER_NAME
@@ -771,9 +792,9 @@ def handle(self):
771792
772793%(url)s?@action=confrego&otk=%(otk)s
773794
774- """ % {'name' : props ['username' ], 'tracker' : tracker_name , 'url' : self . base ,
775- 'otk' : otk , 'tracker_email' : tracker_email }
776- if not self .client .standard_message ([props ['address' ]], subject ,
795+ """ % {'name' : user_props ['username' ], 'tracker' : tracker_name ,
796+ 'url' : self . base , ' otk' : otk , 'tracker_email' : tracker_email }
797+ if not self .client .standard_message ([user_props ['address' ]], subject ,
777798 body , (tracker_name , tracker_email )):
778799 return
779800
0 commit comments