From 84ec0de700ba32816319fa54c3314837cecbfbe0 Mon Sep 17 00:00:00 2001 From: Bhushan Khanale Date: Sun, 2 Jun 2019 10:25:54 +0530 Subject: [PATCH] bears/general: Add FileModeBear Closes https://github.com/coala/coala-bears/issues/2370 --- bear-languages.yaml | 1 + bears/general/FileModeBear.py | 53 +++++ tests/general/FileModeBearTest.py | 219 ++++++++++++++++++ .../general/filemode_test_files/test_file.txt | 0 4 files changed, 273 insertions(+) create mode 100644 bears/general/FileModeBear.py create mode 100644 tests/general/FileModeBearTest.py create mode 100644 tests/general/filemode_test_files/test_file.txt diff --git a/bear-languages.yaml b/bear-languages.yaml index b8095b55a9..fe4da6f83b 100644 --- a/bear-languages.yaml +++ b/bear-languages.yaml @@ -146,6 +146,7 @@ ESLintBear: - Typescript ElmLintBear: - Elm +FileModeBear: FilenameBear: FormatRBear: - R diff --git a/bears/general/FileModeBear.py b/bears/general/FileModeBear.py new file mode 100644 index 0000000000..377f913cf5 --- /dev/null +++ b/bears/general/FileModeBear.py @@ -0,0 +1,53 @@ +import os +import stat + +from coalib.bears.LocalBear import LocalBear +from coalib.results.Result import Result +from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY + + +class FileModeBear(LocalBear): + LANGUAGES = {'All'} + AUTHORS = {'The coala developers'} + AUTHORS_EMAILS = {'coala-devel@googlegroups.com'} + LICENSE = 'AGPL-3.0' + + def run(self, + filename, + file, + filemode: str, + ): + """ + The bear will check if the file has required permissions provided by + the user. + + :param filemode: + Filemode to check, e.g. `rw`, `rwx`, etc. + """ + st = os.stat(filename) + permissions = {'r': stat.S_IRUSR, + 'w': stat.S_IWUSR, + 'x': stat.S_IXUSR, + } + + invalid_chars = [ch for ch in filemode if ch not in permissions] + + if invalid_chars: + raise ValueError('Unable to recognize character `{}` in filemode ' + '`{}`.'.format(''.join(invalid_chars), filemode)) + + for char in filemode: + if char not in permissions: + raise ValueError('Unable to recognize character `{}` in ' + 'filemode `{}`.'.format(char, filemode)) + + mode = st.st_mode + for char in filemode: + if not mode & permissions[char]: + message = ('The file permissions are not adequate. ' + 'The permissions are set to {}' + .format(stat.filemode(mode))) + return [Result.from_values(origin=self, + message=message, + severity=RESULT_SEVERITY.INFO, + file=filename)] diff --git a/tests/general/FileModeBearTest.py b/tests/general/FileModeBearTest.py new file mode 100644 index 0000000000..e5bb878027 --- /dev/null +++ b/tests/general/FileModeBearTest.py @@ -0,0 +1,219 @@ +import os +import platform +import stat + +from queue import Queue + +from bears.general.FileModeBear import FileModeBear +from coalib.testing.LocalBearTestHelper import LocalBearTestHelper +from coalib.results.Result import RESULT_SEVERITY, Result +from coalib.settings.Section import Section +from coalib.settings.Setting import Setting + + +FILE_PATH = os.path.join(os.path.dirname(__file__), + 'filemode_test_files', 'test_file.txt') + + +class FileModeBearTest(LocalBearTestHelper): + + def setUp(self): + self.section = Section('') + self.uut = FileModeBear(self.section, Queue()) + + def test_r_to_r_permissions(self): + os.chmod(FILE_PATH, stat.S_IRUSR) + self.section.append(Setting('filemode', 'r')) + self.check_results( + self.uut, + [], + [], + filename=FILE_PATH, + ) + + def test_w_to_w_permissions(self): + os.chmod(FILE_PATH, stat.S_IWUSR) + self.section.append(Setting('filemode', 'w')) + self.check_results( + self.uut, + [], + [], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_x_to_x_permissions(self): + os.chmod(FILE_PATH, stat.S_IXUSR) + if platform.system() != 'Windows': + self.section.append(Setting('filemode', 'x')) + self.check_results( + self.uut, + [], + [], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_rw_to_rw_permissions(self): + os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IWUSR) + self.section.append(Setting('filemode', 'rw')) + self.check_results( + self.uut, + [], + [], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_wx_to_wx_permissions(self): + os.chmod(FILE_PATH, stat.S_IWUSR | stat.S_IXUSR) + if platform.system() != 'Windows': + self.section.append(Setting('filemode', 'wx')) + self.check_results( + self.uut, + [], + [], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_rx_to_rx_permissions(self): + os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IXUSR) + if platform.system() != 'Windows': + self.section.append(Setting('filemode', 'rx')) + self.check_results( + self.uut, + [], + [], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_rwx_to_rwx_permissions(self): + os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) + if platform.system() != 'Windows': + self.section.append(Setting('filemode', 'rwx')) + self.check_results( + self.uut, + [], + [], + filename=FILE_PATH, + settings={'filemode': 'rwx'}) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_r_to_rwx_permissions(self): + os.chmod(FILE_PATH, stat.S_IRUSR) + filemode = '-r--------' + if platform.system() == 'Windows': + filemode = '-r--r--r--' + message = ('The file permissions are not adequate. The ' + 'permissions are set to {}'.format(filemode)) + self.section.append(Setting('filemode', 'rwx')) + self.check_results( + self.uut, + [], + [Result.from_values('FileModeBear', + message, + file=FILE_PATH, + severity=RESULT_SEVERITY.INFO)], + filename=FILE_PATH, + settings={'filemode': 'rwx'}) + + def test_w_to_rwx_permissions(self): + os.chmod(FILE_PATH, stat.S_IWUSR) + filemode = '--w-------' + if platform.system() == 'Windows': + filemode = '-rw-rw-rw-' + message = ('The file permissions are not adequate. The ' + 'permissions are set to {}'.format(filemode)) + self.section.append(Setting('filemode', 'rwx')) + self.check_results( + self.uut, + [], + [Result.from_values('FileModeBear', + message, + file=FILE_PATH, + severity=RESULT_SEVERITY.INFO)], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_x_to_rwx_permissions(self): + os.chmod(FILE_PATH, stat.S_IXUSR) + filemode = '---x------' + if platform.system() != 'Windows': + message = ('The file permissions are not adequate. The ' + 'permissions are set to {}'.format(filemode)) + self.section.append(Setting('filemode', 'rwx')) + self.check_results( + self.uut, + [], + [Result.from_values('FileModeBear', + message, + file=FILE_PATH, + severity=RESULT_SEVERITY.INFO)], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_rx_to_rwx_permissions(self): + os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IXUSR) + filemode = '-r-x------' + if platform.system() != 'Windows': + message = ('The file permissions are not adequate. The ' + 'permissions are set to {}'.format(filemode)) + self.section.append(Setting('filemode', 'rwx')) + self.check_results( + self.uut, + [], + [Result.from_values('FileModeBear', + message, + file=FILE_PATH, + severity=RESULT_SEVERITY.INFO)], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_wx_to_rwx_permissions(self): + os.chmod(FILE_PATH, stat.S_IWUSR | stat.S_IXUSR) + filemode = '--wx------' + if platform.system() != 'Windows': + message = ('The file permissions are not adequate. The ' + 'permissions are set to {}'.format(filemode)) + self.section.append(Setting('filemode', 'rwx')) + self.check_results( + self.uut, + [], + [Result.from_values('FileModeBear', + message, + file=FILE_PATH, + severity=RESULT_SEVERITY.INFO)], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_rw_to_rwx_permissions(self): + os.chmod(FILE_PATH, stat.S_IRUSR | stat.S_IWUSR) + filemode = '-rw-------' + if platform.system() == 'Windows': + filemode = '-rw-rw-rw-' + message = ('The file permissions are not adequate. The ' + 'permissions are set to {}'.format(filemode)) + self.section.append(Setting('filemode', 'rwx')) + self.check_results( + self.uut, + [], + [Result.from_values('FileModeBear', + message, + file=FILE_PATH, + severity=RESULT_SEVERITY.INFO)], + filename=FILE_PATH, + ) + os.chmod(FILE_PATH, stat.S_IRUSR) + + def test_invalid_char_in_filemode(self): + self.section.append(Setting('filemode', 'rwmc')) + error_msg = ('ValueError: Unable to recognize ' + 'character `mc` in filemode `rwmc`.') + with self.assertRaisesRegex(AssertionError, error_msg): + self.check_validity(self.uut, [], filename=FILE_PATH) diff --git a/tests/general/filemode_test_files/test_file.txt b/tests/general/filemode_test_files/test_file.txt new file mode 100644 index 0000000000..e69de29bb2