Skip to content

Commit 84ec0de

Browse files
committed
bears/general: Add FileModeBear
Closes #2370
1 parent cbe1841 commit 84ec0de

File tree

4 files changed

+273
-0
lines changed

4 files changed

+273
-0
lines changed

bear-languages.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ ESLintBear:
146146
- Typescript
147147
ElmLintBear:
148148
- Elm
149+
FileModeBear:
149150
FilenameBear:
150151
FormatRBear:
151152
- R

bears/general/FileModeBear.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import os
2+
import stat
3+
4+
from coalib.bears.LocalBear import LocalBear
5+
from coalib.results.Result import Result
6+
from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY
7+
8+
9+
class FileModeBear(LocalBear):
10+
LANGUAGES = {'All'}
11+
AUTHORS = {'The coala developers'}
12+
AUTHORS_EMAILS = {'[email protected]'}
13+
LICENSE = 'AGPL-3.0'
14+
15+
def run(self,
16+
filename,
17+
file,
18+
filemode: str,
19+
):
20+
"""
21+
The bear will check if the file has required permissions provided by
22+
the user.
23+
24+
:param filemode:
25+
Filemode to check, e.g. `rw`, `rwx`, etc.
26+
"""
27+
st = os.stat(filename)
28+
permissions = {'r': stat.S_IRUSR,
29+
'w': stat.S_IWUSR,
30+
'x': stat.S_IXUSR,
31+
}
32+
33+
invalid_chars = [ch for ch in filemode if ch not in permissions]
34+
35+
if invalid_chars:
36+
raise ValueError('Unable to recognize character `{}` in filemode '
37+
'`{}`.'.format(''.join(invalid_chars), filemode))
38+
39+
for char in filemode:
40+
if char not in permissions:
41+
raise ValueError('Unable to recognize character `{}` in '
42+
'filemode `{}`.'.format(char, filemode))
43+
44+
mode = st.st_mode
45+
for char in filemode:
46+
if not mode & permissions[char]:
47+
message = ('The file permissions are not adequate. '
48+
'The permissions are set to {}'
49+
.format(stat.filemode(mode)))
50+
return [Result.from_values(origin=self,
51+
message=message,
52+
severity=RESULT_SEVERITY.INFO,
53+
file=filename)]

tests/general/FileModeBearTest.py

+219
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
import os
2+
import platform
3+
import stat
4+
5+
from queue import Queue
6+
7+
from bears.general.FileModeBear import FileModeBear
8+
from coalib.testing.LocalBearTestHelper import LocalBearTestHelper
9+
from coalib.results.Result import RESULT_SEVERITY, Result
10+
from coalib.settings.Section import Section
11+
from coalib.settings.Setting import Setting
12+
13+
14+
FILE_PATH = os.path.join(os.path.dirname(__file__),
15+
'filemode_test_files', 'test_file.txt')
16+
17+
18+
class FileModeBearTest(LocalBearTestHelper):
19+
20+
def setUp(self):
21+
self.section = Section('')
22+
self.uut = FileModeBear(self.section, Queue())
23+
24+
def test_r_to_r_permissions(self):
25+
os.chmod(FILE_PATH, stat.S_IRUSR)
26+
self.section.append(Setting('filemode', 'r'))
27+
self.check_results(
28+
self.uut,
29+
[],
30+
[],
31+
filename=FILE_PATH,
32+
)
33+
34+
def test_w_to_w_permissions(self):
35+
os.chmod(FILE_PATH, stat.S_IWUSR)
36+
self.section.append(Setting('filemode', 'w'))
37+
self.check_results(
38+
self.uut,
39+
[],
40+
[],
41+
filename=FILE_PATH,
42+
)
43+
os.chmod(FILE_PATH, stat.S_IRUSR)
44+
45+
def test_x_to_x_permissions(self):
46+
os.chmod(FILE_PATH, stat.S_IXUSR)
47+
if platform.system() != 'Windows':
48+
self.section.append(Setting('filemode', 'x'))
49+
self.check_results(
50+
self.uut,
51+
[],
52+
[],
53+
filename=FILE_PATH,
54+
)
55+
os.chmod(FILE_PATH, stat.S_IRUSR)
56+
57+
def test_rw_to_rw_permissions(self):
58+
os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IWUSR)
59+
self.section.append(Setting('filemode', 'rw'))
60+
self.check_results(
61+
self.uut,
62+
[],
63+
[],
64+
filename=FILE_PATH,
65+
)
66+
os.chmod(FILE_PATH, stat.S_IRUSR)
67+
68+
def test_wx_to_wx_permissions(self):
69+
os.chmod(FILE_PATH, stat.S_IWUSR | stat.S_IXUSR)
70+
if platform.system() != 'Windows':
71+
self.section.append(Setting('filemode', 'wx'))
72+
self.check_results(
73+
self.uut,
74+
[],
75+
[],
76+
filename=FILE_PATH,
77+
)
78+
os.chmod(FILE_PATH, stat.S_IRUSR)
79+
80+
def test_rx_to_rx_permissions(self):
81+
os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IXUSR)
82+
if platform.system() != 'Windows':
83+
self.section.append(Setting('filemode', 'rx'))
84+
self.check_results(
85+
self.uut,
86+
[],
87+
[],
88+
filename=FILE_PATH,
89+
)
90+
os.chmod(FILE_PATH, stat.S_IRUSR)
91+
92+
def test_rwx_to_rwx_permissions(self):
93+
os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR)
94+
if platform.system() != 'Windows':
95+
self.section.append(Setting('filemode', 'rwx'))
96+
self.check_results(
97+
self.uut,
98+
[],
99+
[],
100+
filename=FILE_PATH,
101+
settings={'filemode': 'rwx'})
102+
os.chmod(FILE_PATH, stat.S_IRUSR)
103+
104+
def test_r_to_rwx_permissions(self):
105+
os.chmod(FILE_PATH, stat.S_IRUSR)
106+
filemode = '-r--------'
107+
if platform.system() == 'Windows':
108+
filemode = '-r--r--r--'
109+
message = ('The file permissions are not adequate. The '
110+
'permissions are set to {}'.format(filemode))
111+
self.section.append(Setting('filemode', 'rwx'))
112+
self.check_results(
113+
self.uut,
114+
[],
115+
[Result.from_values('FileModeBear',
116+
message,
117+
file=FILE_PATH,
118+
severity=RESULT_SEVERITY.INFO)],
119+
filename=FILE_PATH,
120+
settings={'filemode': 'rwx'})
121+
122+
def test_w_to_rwx_permissions(self):
123+
os.chmod(FILE_PATH, stat.S_IWUSR)
124+
filemode = '--w-------'
125+
if platform.system() == 'Windows':
126+
filemode = '-rw-rw-rw-'
127+
message = ('The file permissions are not adequate. The '
128+
'permissions are set to {}'.format(filemode))
129+
self.section.append(Setting('filemode', 'rwx'))
130+
self.check_results(
131+
self.uut,
132+
[],
133+
[Result.from_values('FileModeBear',
134+
message,
135+
file=FILE_PATH,
136+
severity=RESULT_SEVERITY.INFO)],
137+
filename=FILE_PATH,
138+
)
139+
os.chmod(FILE_PATH, stat.S_IRUSR)
140+
141+
def test_x_to_rwx_permissions(self):
142+
os.chmod(FILE_PATH, stat.S_IXUSR)
143+
filemode = '---x------'
144+
if platform.system() != 'Windows':
145+
message = ('The file permissions are not adequate. The '
146+
'permissions are set to {}'.format(filemode))
147+
self.section.append(Setting('filemode', 'rwx'))
148+
self.check_results(
149+
self.uut,
150+
[],
151+
[Result.from_values('FileModeBear',
152+
message,
153+
file=FILE_PATH,
154+
severity=RESULT_SEVERITY.INFO)],
155+
filename=FILE_PATH,
156+
)
157+
os.chmod(FILE_PATH, stat.S_IRUSR)
158+
159+
def test_rx_to_rwx_permissions(self):
160+
os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IXUSR)
161+
filemode = '-r-x------'
162+
if platform.system() != 'Windows':
163+
message = ('The file permissions are not adequate. The '
164+
'permissions are set to {}'.format(filemode))
165+
self.section.append(Setting('filemode', 'rwx'))
166+
self.check_results(
167+
self.uut,
168+
[],
169+
[Result.from_values('FileModeBear',
170+
message,
171+
file=FILE_PATH,
172+
severity=RESULT_SEVERITY.INFO)],
173+
filename=FILE_PATH,
174+
)
175+
os.chmod(FILE_PATH, stat.S_IRUSR)
176+
177+
def test_wx_to_rwx_permissions(self):
178+
os.chmod(FILE_PATH, stat.S_IWUSR | stat.S_IXUSR)
179+
filemode = '--wx------'
180+
if platform.system() != 'Windows':
181+
message = ('The file permissions are not adequate. The '
182+
'permissions are set to {}'.format(filemode))
183+
self.section.append(Setting('filemode', 'rwx'))
184+
self.check_results(
185+
self.uut,
186+
[],
187+
[Result.from_values('FileModeBear',
188+
message,
189+
file=FILE_PATH,
190+
severity=RESULT_SEVERITY.INFO)],
191+
filename=FILE_PATH,
192+
)
193+
os.chmod(FILE_PATH, stat.S_IRUSR)
194+
195+
def test_rw_to_rwx_permissions(self):
196+
os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IWUSR)
197+
filemode = '-rw-------'
198+
if platform.system() == 'Windows':
199+
filemode = '-rw-rw-rw-'
200+
message = ('The file permissions are not adequate. The '
201+
'permissions are set to {}'.format(filemode))
202+
self.section.append(Setting('filemode', 'rwx'))
203+
self.check_results(
204+
self.uut,
205+
[],
206+
[Result.from_values('FileModeBear',
207+
message,
208+
file=FILE_PATH,
209+
severity=RESULT_SEVERITY.INFO)],
210+
filename=FILE_PATH,
211+
)
212+
os.chmod(FILE_PATH, stat.S_IRUSR)
213+
214+
def test_invalid_char_in_filemode(self):
215+
self.section.append(Setting('filemode', 'rwmc'))
216+
error_msg = ('ValueError: Unable to recognize '
217+
'character `mc` in filemode `rwmc`.')
218+
with self.assertRaisesRegex(AssertionError, error_msg):
219+
self.check_validity(self.uut, [], filename=FILE_PATH)

tests/general/filemode_test_files/test_file.txt

Whitespace-only changes.

0 commit comments

Comments
 (0)