1
# Copyright (C) 2005, 2008 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
"""Tests for bzr setting permissions.
20
Files in the branch control directory (.bzr or .bzr/branch) should inherit
21
the .bzr directory permissions.
22
So if the directory is group writable, the files and subdirs should be as well.
25
# TODO: jam 20051215 Currently the default behavior for 'bzr branch' is just
26
# defined by the local umask. This isn't terrible, is it
27
# the truly desired behavior?
32
from StringIO import StringIO
34
from bzrlib import tests
35
from bzrlib.branch import Branch
36
from bzrlib.bzrdir import BzrDir
37
from bzrlib.lockable_files import LockableFiles
38
from bzrlib.remote import RemoteBranchFormat
39
from bzrlib.tests.test_permissions import chmod_r, check_mode_r
40
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
41
from bzrlib.transport import get_transport
42
from bzrlib.workingtree import WorkingTree
45
class _NullPermsStat(object):
46
"""A class that proxy's a stat result and strips permissions."""
48
def __init__(self, orig_stat):
49
self._orig_stat = orig_stat
50
# We strip all permission bits from st_mode
51
self.st_mode = orig_stat.st_mode & ~07777
53
def __getattr__(self, name):
54
return getattr(self._orig_stat, name)
57
class TestPermissions(tests.TestCaseWithTransport):
59
def test_new_branch(self):
60
if isinstance(self.branch_format, RemoteBranchFormat):
61
# Remote branch format have no permission logic in them; there's
62
# nothing to test here.
63
raise tests.TestNotApplicable('Remote branches have no'
65
if sys.platform == 'win32':
66
raise tests.TestNotApplicable('chmod has no effect on win32')
67
# also, these are BzrBranch format specific things..
69
mode = stat.S_IMODE(os.stat('a').st_mode)
70
t = self.make_branch_and_tree('.')
72
self.assertEqualMode(mode, b.bzrdir._get_dir_mode())
73
self.assertEqualMode(mode & ~07111, b.bzrdir._get_file_mode())
74
self.assertEqualMode(mode, b.control_files._dir_mode)
75
self.assertEqualMode(mode & ~07111, b.control_files._file_mode)
79
b = self.make_branch('d')
80
self.assertEqualMode(0700, b.bzrdir._get_dir_mode())
81
self.assertEqualMode(0600, b.bzrdir._get_file_mode())
82
self.assertEqualMode(0700, b.control_files._dir_mode)
83
self.assertEqualMode(0600, b.control_files._file_mode)
84
check_mode_r(self, 'd/.bzr', 00600, 00700)
86
def test_new_branch_group_sticky_bit(self):
87
if isinstance(self.branch_format, RemoteBranchFormat):
88
# Remote branch format have no permission logic in them; there's
89
# nothing to test here.
90
raise tests.TestNotApplicable('Remote branches have no'
92
if sys.platform == 'win32':
93
raise tests.TestNotApplicable('chmod has no effect on win32')
94
elif sys.platform == 'darwin':
95
# OS X creates temp dirs with the 'wheel' group, which users are
96
# not likely to be in, and this prevents us from setting the sgid
98
os.chown(self.test_dir, os.getuid(), os.getgid())
99
# also, these are BzrBranch format specific things..
100
t = self.make_branch_and_tree('.')
104
b = self.make_branch('b')
105
self.assertEqualMode(02777, b.bzrdir._get_dir_mode())
106
self.assertEqualMode(00666, b.bzrdir._get_file_mode())
107
self.assertEqualMode(02777, b.control_files._dir_mode)
108
self.assertEqualMode(00666, b.control_files._file_mode)
109
check_mode_r(self, 'b/.bzr', 00666, 02777)
113
b = self.make_branch('c')
114
self.assertEqualMode(02750, b.bzrdir._get_dir_mode())
115
self.assertEqualMode(00640, b.bzrdir._get_file_mode())
116
self.assertEqualMode(02750, b.control_files._dir_mode)
117
self.assertEqualMode(00640, b.control_files._file_mode)
118
check_mode_r(self, 'c/.bzr', 00640, 02750)
120
def test_mode_0(self):
121
"""Test when a transport returns null permissions for .bzr"""
122
if isinstance(self.branch_format, RemoteBranchFormat):
123
# Remote branch format have no permission logic in them; there's
124
# nothing to test here.
125
raise tests.TestNotApplicable('Remote branches have no'
127
self.make_branch_and_tree('.')
128
bzrdir = BzrDir.open('.')
129
# Monkey patch the transport
130
_orig_stat = bzrdir.transport.stat
131
def null_perms_stat(*args, **kwargs):
132
result = _orig_stat(*args, **kwargs)
133
return _NullPermsStat(result)
134
bzrdir.transport.stat = null_perms_stat
135
self.assertIs(None, bzrdir._get_dir_mode())
136
self.assertIs(None, bzrdir._get_file_mode())