14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
19
"""Tests for bzr setting permissions.
28
28
# TODO: jam 20051215 There are no tests for ftp yet, because we have no ftp server
29
# TODO: jam 20051215 Currently the default behavior for 'bzr branch' is just
29
# TODO: jam 20051215 Currently the default behavior for 'bzr branch' is just
30
30
# defined by the local umask. This isn't terrible, is it
31
31
# the truly desired behavior?
36
from cStringIO import StringIO
36
from bzrlib import urlutils
37
39
from bzrlib.branch import Branch
38
from bzrlib.controldir import ControlDir
40
from bzrlib.bzrdir import BzrDir
41
from bzrlib.lockable_files import LockableFiles, TransportLock
39
42
from bzrlib.tests import TestCaseWithTransport, TestSkipped
40
43
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
44
from bzrlib.transport import get_transport
41
45
from bzrlib.workingtree import WorkingTree
62
66
:param dir_mode: The mode for all directories
63
67
:param include_base: If false, only check the subdirectories
65
t = test.get_transport()
69
t = get_transport(".")
67
71
test.assertTransportMode(t, base, dir_mode)
68
72
for root, dirs, files in os.walk(base):
70
p = '/'.join([urlutils.quote(x) for x in root.split('/\\') + [d]])
74
p = '/'.join([urllib.quote(x) for x in root.split('/\\') + [d]])
71
75
test.assertTransportMode(t, p, dir_mode)
73
77
p = os.path.join(root, f)
74
p = '/'.join([urlutils.quote(x) for x in root.split('/\\') + [f]])
78
p = '/'.join([urllib.quote(x) for x in root.split('/\\') + [f]])
75
79
test.assertTransportMode(t, p, file_mode)
84
88
t = self.make_branch_and_tree('.')
86
with open('a', 'wb') as f: f.write('foo\n')
90
open('a', 'wb').write('foo\n')
87
91
# ensure check_mode_r works with capital-letter file-ids like TREE_ROOT
88
92
t.add('a', 'CAPS-ID')
94
98
# although we are modifying the filesystem
95
99
# underneath the objects, they are not locked, and thus it must
96
# be safe for most operations. But here we want to observe a
100
# be safe for most operations. But here we want to observe a
97
101
# mode change in the control bits, which current do not refresh
98
102
# when a new lock is taken out.
99
103
t = WorkingTree.open('.')
104
108
self.assertEqualMode(0644, b.bzrdir._get_file_mode())
106
110
# Modifying a file shouldn't break the permissions
107
with open('a', 'wb') as f: f.write('foo2\n')
111
open('a', 'wb').write('foo2\n')
109
113
# The mode should be maintained after commit
110
114
check_mode_r(self, '.bzr', 0644, 0755)
112
116
# Adding a new file should maintain the permissions
113
with open('b', 'wb') as f: f.write('new b\n')
117
open('b', 'wb').write('new b\n')
115
119
t.commit('new b')
116
120
check_mode_r(self, '.bzr', 0644, 0755)
125
129
self.assertEqualMode(0775, b.bzrdir._get_dir_mode())
126
130
self.assertEqualMode(0664, b.bzrdir._get_file_mode())
128
with open('a', 'wb') as f: f.write('foo3\n')
132
open('a', 'wb').write('foo3\n')
130
134
check_mode_r(self, '.bzr', 0664, 0775)
132
with open('c', 'wb') as f: f.write('new c\n')
136
open('c', 'wb').write('new c\n')
134
138
t.commit('new c')
135
139
check_mode_r(self, '.bzr', 0664, 0775)
137
def test_new_files_group_sticky_bit(self):
138
if sys.platform == 'win32':
139
raise TestSkipped('chmod has no effect on win32')
140
elif sys.platform == 'darwin' or 'freebsd' in sys.platform:
141
# FreeBSD-based platforms create temp dirs with the 'wheel' group,
142
# which users are not likely to be in, and this prevents us from
143
# setting the sgid bit
144
os.chown(self.test_dir, os.getuid(), os.getgid())
146
t = self.make_branch_and_tree('.')
149
141
# Test the group sticky bit
150
142
# Recursively update the modes of all files
151
143
chmod_r('.bzr', 0664, 02775)
157
149
self.assertEqualMode(02775, b.bzrdir._get_dir_mode())
158
150
self.assertEqualMode(0664, b.bzrdir._get_file_mode())
160
with open('a', 'wb') as f: f.write('foo4\n')
152
open('a', 'wb').write('foo4\n')
162
154
check_mode_r(self, '.bzr', 0664, 02775)
164
with open('d', 'wb') as f: f.write('new d\n')
156
open('d', 'wb').write('new d\n')
166
158
t.commit('new d')
167
159
check_mode_r(self, '.bzr', 0664, 02775)
178
170
# bodge around for stubsftpserver not letting use connect
180
_t = self.get_transport()
172
_t = get_transport(self.get_url())
182
174
os.mkdir('local')
183
175
t_local = self.make_branch_and_tree('local')
184
176
b_local = t_local.branch
185
with open('local/a', 'wb') as f: f.write('foo\n')
177
open('local/a', 'wb').write('foo\n')
187
179
t_local.commit('foo')
212
204
self.assertEqualMode(0755, b_sftp.bzrdir._get_dir_mode())
213
205
self.assertEqualMode(0644, b_sftp.bzrdir._get_file_mode())
215
with open('local/a', 'wb') as f: f.write('foo2\n')
207
open('local/a', 'wb').write('foo2\n')
216
208
t_local.commit('foo2')
217
209
b_sftp.pull(b_local)
218
210
# The mode should be maintained after commit
219
211
check_mode_r(self, 'sftp/.bzr', 0644, 0755)
221
with open('local/b', 'wb') as f: f.write('new b\n')
213
open('local/b', 'wb').write('new b\n')
223
215
t_local.commit('new b')
224
216
b_sftp.pull(b_local)
235
227
self.assertEqualMode(0775, b_sftp.bzrdir._get_dir_mode())
236
228
self.assertEqualMode(0664, b_sftp.bzrdir._get_file_mode())
238
with open('local/a', 'wb') as f: f.write('foo3\n')
230
open('local/a', 'wb').write('foo3\n')
239
231
t_local.commit('foo3')
240
232
b_sftp.pull(b_local)
241
233
check_mode_r(self, 'sftp/.bzr', 0664, 0775)
243
with open('local/c', 'wb') as f: f.write('new c\n')
235
open('local/c', 'wb').write('new c\n')
245
237
t_local.commit('new c')
246
238
b_sftp.pull(b_local)
254
246
original_umask = os.umask(umask)
257
t = self.get_transport()
249
t = get_transport(self.get_url())
258
250
# Direct access should be masked by umask
259
251
t._sftp_open_exclusive('a', mode=0666).write('foo\n')
260
252
self.assertTransportMode(t, 'a', 0666 &~umask)