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.You are not allowed to attach a file to this page.