#! /usr/bin/python3 # ------------------------------------------------------------------ # # Copyright (C) 2016 Christian Boltz # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 of the GNU General Public # License published by the Free Software Foundation. # # ------------------------------------------------------------------ import gettext import os import subprocess import unittest from apparmor.ui import CMDS, get_translated_hotkey from common_test import AATest, setup_all_loops class TestHotkeyConflicts(AATest): # check if there are any hotkey conflicts in one of the apparmor-utils translations tests = ( (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_OFF (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_NEW (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_ON (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_OFF', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_OFF and CMD_USER_OFF (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_ON', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_ON (('CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_GLOB', 'CMD_GLOBEXT', 'CMD_NEW', 'CMD_AUDIT_NEW', 'CMD_USER_OFF', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py available_buttons() with CMD_AUDIT_NEW and CMD_USER_OFF (('CMD_SAVE_CHANGES', 'CMD_SAVE_SELECTED', 'CMD_VIEW_CHANGES', 'CMD_VIEW_CHANGES_CLEAN', 'CMD_ABORT'), True), # aa.py save_profiles() (('CMD_VIEW_PROFILE', 'CMD_USE_PROFILE', 'CMD_CREATE_PROFILE', 'CMD_ABORT'), True), # aa.py get_profile() (('CMD_ix', 'CMD_pix', 'CMD_cix', 'CMD_nix', 'CMD_EXEC_IX_OFF', 'CMD_ux', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py build_x_functions() with exec_toggle (('CMD_ix', 'CMD_cx', 'CMD_px', 'CMD_nx', 'CMD_ux', 'CMD_EXEC_IX_ON', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py build_x_functions() without exec_toggle (('CMD_ADDHAT', 'CMD_USEDEFAULT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa.py ask_addhat() (('CMD_YES', 'CMD_NO', 'CMD_CANCEL'), True), # ui.py UI_YesNo() and UI_YesNoCancel (('CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT', 'CMD_IGNORE_ENTRY'), True), # aa-mergeprof act() (('CMD_ALLOW', 'CMD_ABORT'), True), # aa-mergeprof conflict_mode() (('CMD_ADDSUBPROFILE', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa-mergeprof ask_the_questions() - new subprofile (('CMD_ADDHAT', 'CMD_DENY', 'CMD_ABORT', 'CMD_FINISHED'), True), # aa-mergeprof ask_the_questions() - new hat ) def _run_test(self, params, expected): self.createTmpdir() subprocess.run("make -C ../po >/dev/null", shell=True, check=True) subprocess.run( "DESTDIR={} NAME=apparmor-utils make -C ../po install >/dev/null".format(self.tmpdir), shell=True, check=True, ) self.localedir = '{}/usr/share/locale'.format(self.tmpdir) self.languages = os.listdir(self.localedir) # make sure we found all translations if len(self.languages) < 15: raise Exception('None or not all languages found, only {}'.format(self.languages)) # we also want to detect hotkey conflicts in the untranslated english strings self.languages.append('C') for language in self.languages: with self.subTest(language=language): t = gettext.translation( 'apparmor-utils', fallback=True, localedir=self.localedir, languages=(language,), ) keys = {} for key in params: text = t.gettext(CMDS[key]) hotkey = get_translated_hotkey(text) if keys.get(hotkey): raise Exception("Hotkey conflict: '{}' and '{}'".format(keys[hotkey], text)) else: keys[hotkey] = text setup_all_loops(__name__) if __name__ == '__main__': unittest.main(verbosity=1)