Attachment 'safeuser.patch'

Download

   1 * looking for arch@arch.thinkmo.de--2003-archives/moin--main--1.3--patch-507 to compare with
   2 * comparing to arch@arch.thinkmo.de--2003-archives/moin--main--1.3--patch-507
   3 M  MoinMoin/user.py
   4 
   5 * modified files
   6 
   7 --- orig/MoinMoin/user.py
   8 +++ mod/MoinMoin/user.py
   9 @@ -502,21 +502,20 @@
  10          """
  11          if not self.id:
  12              return
  13 -
  14 +        
  15          user_dir = self._cfg.user_dir
  16 +        # Self repair missing user dir
  17          if not os.path.isdir(user_dir):
  18              os.mkdir(user_dir, 0777 & config.umask)
  19              os.chmod(user_dir, 0777 & config.umask)
  20  
  21 -        self.last_saved = str(time.time())
  22 +        now = time.time()
  23 +        self.last_saved = str(now)
  24  
  25 -        # !!! should write to a temp file here to avoid race conditions,
  26 -        # or even better, use locking
  27 -        
  28 -        data = codecs.open(self.__filename(), "w", config.charset)
  29 -        data.write("# Data saved '%s' for id '%s'\n" % (
  30 -            time.strftime(self._cfg.datetime_fmt, time.localtime(time.time())),
  31 -            self.id))
  32 +        # Prapare data for file
  33 +        data = []
  34 +        timestamp = time.strftime(self._cfg.datetime_fmt, time.localtime(now))
  35 +        data.append("# Data saved '%s' for id '%s'\n" % (timestamp, self.id))
  36          attrs = vars(self).items()
  37          attrs.sort()
  38          for key, value in attrs:
  39 @@ -525,17 +524,82 @@
  40                  if key in ['quicklinks', 'subscribed_pages']:
  41                      value = encodeList(value)
  42                  line = u"%s=%s\n" % (key, unicode(value))
  43 -                data.write(line)
  44 -        data.close()
  45 -
  46 -        try:
  47 -            os.chmod(self.__filename(), 0666 & config.umask)
  48 -        except OSError:
  49 -            pass
  50 +                data.append(line)
  51 +        data = ''.join(data)
  52 +        data = data.encode(config.charset)
  53  
  54 +        # Write data to user file
  55 +        self._writeFile(data)
  56 +        
  57          if not self.disabled:
  58              self.valid = 1
  59  
  60 +    def _writeFile(self, data):
  61 +        """ Write to user file in a secure way, using a temporary file
  62 +
  63 +        This method is well secured on Python 2.3, and less secure on
  64 +        older Pythons. Upgrade!
  65 +
  66 +        Do not call directly, use save()
  67 +
  68 +        @param data: user data (string)
  69 +        """
  70 +        import tempfile
  71 +        
  72 +        # Try to get the most secure method to create a temporary file:
  73 +        # mkstemp, if its not available, use mktemp
  74 +        try:
  75 +            mktemp = tempfile.mkstemp
  76 +        except AttributeError:
  77 +            mktemp = tempfile.mktemp
  78 +
  79 +        # Write to user file - first write to a temporary file, then
  80 +        # rename the temporary file to the user file, which is atomic on
  81 +        # Posix.
  82 +        try:
  83 +            try:
  84 +                # Write to the temporary file
  85 +                try:
  86 +                    fd, temppath = mktemp(suffix='.temp', prefix=self.id,
  87 +                                          dir=self._cfg.user_dir)
  88 +                    os.write(fd, data)
  89 +                finally:
  90 +                    os.close(fd)
  91 +
  92 +                # Rename to user file
  93 +                userpath = self.__filename()
  94 +                try:
  95 +                    os.rename(temppath, userpath)
  96 +                except OSError:
  97 +                    # Probably on winodws, which does not have atomic
  98 +                    # rename. Try to rename in a safe way: remove backup
  99 +                    # file if one exists, then rename the user file to
 100 +                    # the backup file, then rename the tempfile to the
 101 +                    # userfile.
 102 +                    backup = userpath + '.bak'
 103 +                    try:
 104 +                        os.remove(backup)
 105 +                    except OSError:
 106 +                        pass # No such file
 107 +                    os.rename(userpath, backup)
 108 +                    os.rename(temppath, userpath)
 109 +                    
 110 +                os.chmod(userpath, 0666 & config.umask)
 111 +            except OSError:
 112 +                # What should we do with errors here?
 113 +                pass
 114 +        finally:
 115 +            # Cleanup left overs in case of an error
 116 +            try:
 117 +                os.remove(temppath)
 118 +            except OSError:
 119 +                pass
 120 +
 121 +    # Make this fuction tread safe if we use threads
 122 +    if config.use_threads:
 123 +        from MoinMoin.util import pysupport
 124 +        _writeFile = pysupport.makeThreadSafe(_writeFile)
 125 +        
 126      def getTime(self, tm):
 127          """
 128          Get time in user's timezone.

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2004-12-29 23:37:35, 4.4 KB) [[attachment:safeuser.patch]]
  • [get | view] (2005-04-15 19:15:41, 6.7 KB) [[attachment:trail.patch]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.