mirror of
https://github.com/SELinuxProject/setools
synced 2025-05-16 23:29:16 +00:00
Clean up item model classes.
* Remove "Model" from names of model classes. * Remove remaining *_detail() functions. * Add typing. * Make models dir a package. * Update for superclass data() method as fallback. * Switch to match/case statements. Signed-off-by: Chris PeBenito <pebenito@ieee.org>
This commit is contained in:
parent
f9d0a7f1f3
commit
2d755c46ca
@ -3,6 +3,6 @@
|
||||
from .boolean import boolean_detail, boolean_detail_action, boolean_tooltip
|
||||
from .objclass import objclass_detail, objclass_detail_action, objclass_tooltip
|
||||
from .role import role_detail, role_detail_action, role_tooltip
|
||||
from .typeattr import typeattr_detail, typeattr_tooltip
|
||||
from .typeattr import (typeattr_detail, typeattr_detail_action, typeattr_tooltip)
|
||||
from .type import (type_detail, type_or_attr_detail, type_detail_action,
|
||||
type_or_attr_detail_action, type_tooltip, type_or_attr_tooltip)
|
||||
|
@ -49,4 +49,4 @@ def role_tooltip(role: "Role") -> str:
|
||||
return f"{role} is a role associated with {n_types} types."
|
||||
else:
|
||||
return f"{role} is a role associated with types: " \
|
||||
f"{', '.join(t.name for t in role.expand())}"
|
||||
f"{', '.join(t.name for t in role.types())}"
|
||||
|
@ -30,6 +30,16 @@ def typeattr_detail(attr: "TypeAttribute", parent: "Optional[QtWidgets.QWidget]"
|
||||
parent)
|
||||
|
||||
|
||||
def typeattr_detail_action(attr: "TypeAttribute",
|
||||
parent: QtWidgets.QWidget | None = None) -> QtWidgets.QAction:
|
||||
|
||||
"""Return a QAction that, when triggered, opens an detail popup for the attr."""
|
||||
|
||||
a = QtWidgets.QAction(f"Properties of {attr}")
|
||||
a.triggered.connect(lambda _: typeattr_detail(attr, parent))
|
||||
return a
|
||||
|
||||
|
||||
def typeattr_tooltip(attr: "TypeAttribute") -> str:
|
||||
"""Return tooltip text for this type attribute."""
|
||||
n_types = len(attr)
|
||||
|
@ -5,8 +5,7 @@ from typing import TYPE_CHECKING
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
import setools
|
||||
|
||||
from . import criteria, tab
|
||||
from .models.mlsrule import MLSRuleTableModel
|
||||
from . import criteria, models, tab
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional
|
||||
@ -130,7 +129,7 @@ class MLSRuleQueryTab(tab.TableResultTabWidget):
|
||||
self.criteria = (rt, src, dst, tclass, dflt)
|
||||
|
||||
# Set result table's model
|
||||
self.table_results_model = MLSRuleTableModel(self.table_results)
|
||||
self.table_results_model = models.MLSRuleTable(self.table_results)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
24
setoolsgui/widgets/models/__init__.py
Normal file
24
setoolsgui/widgets/models/__init__.py
Normal file
@ -0,0 +1,24 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
|
||||
from .boolean import BooleanList
|
||||
from .bounds import BoundsTable
|
||||
from .common import CommonTable
|
||||
from .constraint import ConstraintTable
|
||||
from .default import DefaultTable
|
||||
from .fsuse import FSUseTable
|
||||
from .genfscon import GenfsconTable
|
||||
from .ibendportcon import IbendportconTable
|
||||
from .ibpkeycon import IbpkeyconTable
|
||||
from .initsid import InitialSIDTable
|
||||
from .mls import MLSComponentTable
|
||||
from .mlsrule import MLSRuleTable
|
||||
from .netifcon import NetifconTable
|
||||
from .nodecon import NodeconTable
|
||||
from .objclass import ObjClassTable
|
||||
from .portcon import PortconTable
|
||||
from .rbacrule import RBACRuleTable
|
||||
from .role import RoleTable
|
||||
from .terule import TERuleTable
|
||||
from .type import TypeTable
|
||||
from .typeattr import TypeAttributeTable
|
||||
from .user import UserTable
|
@ -3,20 +3,16 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from . import modelroles
|
||||
from .list import SEToolsListModel
|
||||
from .table import SEToolsTableModel
|
||||
from .. import details
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from setools import Boolean
|
||||
|
||||
|
||||
class BooleanList(SEToolsListModel["Boolean"]):
|
||||
class BooleanList(SEToolsListModel[setools.Boolean]):
|
||||
|
||||
"""List-based model for Booleans."""
|
||||
|
||||
@ -27,32 +23,35 @@ class BooleanList(SEToolsListModel["Boolean"]):
|
||||
row = index.row()
|
||||
item = self.item_list[row]
|
||||
|
||||
if role == modelroles.ContextMenuRole:
|
||||
return (details.boolean_detail_action(item), )
|
||||
elif role == QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
return details.boolean_tooltip(item)
|
||||
match role:
|
||||
case modelroles.ContextMenuRole:
|
||||
return (details.boolean_detail_action(item), )
|
||||
case QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
return details.boolean_tooltip(item)
|
||||
|
||||
return super().data(index, role)
|
||||
|
||||
|
||||
class BooleanTableModel(SEToolsTableModel):
|
||||
class BooleanTable(SEToolsTableModel):
|
||||
|
||||
"""Table-based model for booleans."""
|
||||
|
||||
headers = ["Name", "Default State"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
boolean = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return boolean.name
|
||||
elif col == 1:
|
||||
return str(boolean.state)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
boolean = self.item_list[row]
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.UserRole:
|
||||
# get the whole rule for boolean boolean
|
||||
return boolean
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return boolean.name
|
||||
case 1:
|
||||
return str(boolean.state)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,30 +3,34 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class BoundsTableModel(SEToolsTableModel):
|
||||
class BoundsTable(SEToolsTableModel[setools.Bounds]):
|
||||
|
||||
"""Table-based model for *bounds."""
|
||||
|
||||
headers = ["Rule Type", "Parent", "Child"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.ruletype.name
|
||||
elif col == 1:
|
||||
return item.parent.name
|
||||
elif col == 2:
|
||||
return item.child.name
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return item
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return item.ruletype.name
|
||||
case 1:
|
||||
return item.parent.name
|
||||
case 2:
|
||||
return item.child.name
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,50 +3,32 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QPalette, QTextCursor
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from setools.exception import NoCommon
|
||||
|
||||
from .details import DetailsPopup
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
def common_detail(parent, common):
|
||||
"""
|
||||
Create a dialog box for common perm set details.
|
||||
|
||||
Parameters:
|
||||
parent The parent Qt Widget
|
||||
class_ The type
|
||||
"""
|
||||
|
||||
detail = DetailsPopup(parent, "Common detail: {0}".format(common))
|
||||
|
||||
detail.append_header("Permissions ({0}):".format(len(common.perms)))
|
||||
for p in sorted(common.perms):
|
||||
detail.append(" {0}".format(p))
|
||||
|
||||
detail.show()
|
||||
|
||||
|
||||
class CommonTableModel(SEToolsTableModel):
|
||||
class CommonTable(SEToolsTableModel[setools.Common]):
|
||||
|
||||
"""Table-based model for common permission sets."""
|
||||
|
||||
headers = ["Name", "Permissions"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.name
|
||||
elif col == 1:
|
||||
return ", ".join(sorted(item.perms))
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return item
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return item.name
|
||||
case 1:
|
||||
return ", ".join(sorted(item.perms))
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,36 +3,40 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from setools.exception import ConstraintUseError
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class ConstraintTableModel(SEToolsTableModel):
|
||||
class ConstraintTable(SEToolsTableModel[setools.Constraint]):
|
||||
|
||||
"""A table-based model for constraints."""
|
||||
|
||||
headers = ["Rule Type", "Class", "Permissions", "Expression"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.ruletype.name
|
||||
elif col == 1:
|
||||
return rule.tclass.name
|
||||
elif col == 2:
|
||||
try:
|
||||
return ", ".join(sorted(rule.perms))
|
||||
except ConstraintUseError:
|
||||
return None
|
||||
elif col == 3:
|
||||
return str(rule.expression)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.ruletype.name
|
||||
case 1:
|
||||
return rule.tclass.name
|
||||
case 2:
|
||||
if rule.ruletype in (setools.ConstraintRuletype.constrain,
|
||||
setools.ConstraintRuletype.mlsconstrain):
|
||||
return ", ".join(sorted(rule.perms))
|
||||
else:
|
||||
return None
|
||||
case 3:
|
||||
return str(rule.expression)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -5,33 +5,38 @@
|
||||
#
|
||||
from contextlib import suppress
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class DefaultTableModel(SEToolsTableModel):
|
||||
class DefaultTable(SEToolsTableModel[setools.Default]):
|
||||
|
||||
"""Table-based model for default_*."""
|
||||
|
||||
headers = ["Rule Type", "Class", "Default", "Default Range"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.ruletype.name
|
||||
elif col == 1:
|
||||
return item.tclass.name
|
||||
elif col == 2:
|
||||
return item.default.name
|
||||
elif col == 3:
|
||||
with suppress(AttributeError):
|
||||
return item.default_range.name
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return item
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return item.ruletype.name
|
||||
case 1:
|
||||
return item.tclass.name
|
||||
case 2:
|
||||
return item.default.name
|
||||
case 3:
|
||||
with suppress(AttributeError):
|
||||
return item.default_range.name # type: ignore
|
||||
return None
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,30 +3,34 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class FSUseTableModel(SEToolsTableModel):
|
||||
class FSUseTable(SEToolsTableModel[setools.FSUse]):
|
||||
|
||||
"""Table-based model for fs_use_*."""
|
||||
|
||||
headers = ["Ruletype", "FS Type", "Context"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.ruletype.name
|
||||
elif col == 1:
|
||||
return rule.fs
|
||||
elif col == 2:
|
||||
return str(rule.context)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.ruletype.name
|
||||
case 1:
|
||||
return rule.fs
|
||||
case 2:
|
||||
return str(rule.context)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -5,12 +5,13 @@
|
||||
#
|
||||
import stat
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class GenfsconTableModel(SEToolsTableModel):
|
||||
class GenfsconTable(SEToolsTableModel[setools.Genfscon]):
|
||||
|
||||
"""Table-based model for genfscons."""
|
||||
|
||||
@ -26,21 +27,24 @@ class GenfsconTableModel(SEToolsTableModel):
|
||||
stat.S_IFLNK: "Symbolic Link",
|
||||
stat.S_IFSOCK: "Socket"}
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.fs
|
||||
elif col == 1:
|
||||
return rule.path
|
||||
elif col == 2:
|
||||
return self._filetype_to_text[rule.filetype]
|
||||
elif col == 3:
|
||||
return str(rule.context)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.fs
|
||||
case 1:
|
||||
return rule.path
|
||||
case 2:
|
||||
return self._filetype_to_text[rule.filetype]
|
||||
case 3:
|
||||
return str(rule.context)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,30 +3,34 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class IbendportconTableModel(SEToolsTableModel):
|
||||
class IbendportconTable(SEToolsTableModel[setools.Ibendportcon]):
|
||||
|
||||
"""Table-based model for ibendportcons."""
|
||||
|
||||
headers = ["Device", "Endport", "Context"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.name
|
||||
elif col == 1:
|
||||
return str(rule.port)
|
||||
elif col == 2:
|
||||
return str(rule.context)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.name
|
||||
case 1:
|
||||
return str(rule.port)
|
||||
case 2:
|
||||
return str(rule.context)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,34 +3,37 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class IbpkeyconTableModel(SEToolsTableModel):
|
||||
class IbpkeyconTable(SEToolsTableModel[setools.Ibpkeycon]):
|
||||
|
||||
"""Table-based model for ibpkeycons."""
|
||||
|
||||
headers = ["Subnet Prefix", "Partition Keys", "Context"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return str(rule.subnet_prefix)
|
||||
elif col == 1:
|
||||
low, high = rule.pkeys
|
||||
if low == high:
|
||||
return "{0:#x}".format(low)
|
||||
else:
|
||||
return "{0:#x}-{1:#x}".format(low, high)
|
||||
elif col == 2:
|
||||
return str(rule.context)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return str(rule.subnet_prefix)
|
||||
case 1:
|
||||
low, high = rule.pkeys
|
||||
if low == high:
|
||||
return f"{low:#x}"
|
||||
return f"{low:#x}-{high:#x}"
|
||||
case 2:
|
||||
return str(rule.context)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,28 +3,32 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class InitialSIDTableModel(SEToolsTableModel):
|
||||
class InitialSIDTable(SEToolsTableModel[setools.InitialSID]):
|
||||
|
||||
"""Table-based model for initial SIDs."""
|
||||
|
||||
headers = ["SID", "Context"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.name
|
||||
elif col == 1:
|
||||
return str(rule.context)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.name
|
||||
case 1:
|
||||
return str(rule.context)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -14,6 +14,7 @@ from .typing import MetaclassFix
|
||||
T = typing.TypeVar("T")
|
||||
|
||||
|
||||
# pylint: disable=invalid-metaclass
|
||||
class SEToolsListModel(QtCore.QAbstractListModel, typing.Generic[T], metaclass=MetaclassFix):
|
||||
|
||||
"""
|
||||
|
@ -3,71 +3,31 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QPalette, QTextCursor
|
||||
from PyQt5 import QtCore
|
||||
|
||||
from .details import DetailsPopup
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
def _mls_detail(parent, obj, objtype):
|
||||
"""
|
||||
Create a dialog box for category or sensitivity details.
|
||||
|
||||
Parameters:
|
||||
parent The parent Qt Widget
|
||||
type_ The type
|
||||
"""
|
||||
|
||||
detail = DetailsPopup(parent, "{0} detail: {1}".format(objtype, obj))
|
||||
|
||||
aliases = sorted(obj.aliases())
|
||||
detail.append_header("Aliases ({0}):".format(len(aliases)))
|
||||
for a in aliases:
|
||||
detail.append(" {0}".format(a))
|
||||
|
||||
detail.show()
|
||||
|
||||
|
||||
def category_detail(parent, obj):
|
||||
"""
|
||||
Create a dialog box for category details.
|
||||
|
||||
Parameters:
|
||||
parent The parent Qt Widget
|
||||
type_ The type
|
||||
"""
|
||||
_mls_detail(parent, obj, "Category")
|
||||
|
||||
|
||||
def sensitivity_detail(parent, obj):
|
||||
"""
|
||||
Create a dialog box for sensitivity details.
|
||||
|
||||
Parameters:
|
||||
parent The parent Qt Widget
|
||||
type_ The type
|
||||
"""
|
||||
_mls_detail(parent, obj, "Sensitivity")
|
||||
|
||||
|
||||
class MLSComponentTableModel(SEToolsTableModel):
|
||||
class MLSComponentTable(SEToolsTableModel):
|
||||
|
||||
"""Table-based model for sensitivities and categories."""
|
||||
|
||||
headers = ["Name", "Aliases"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.name
|
||||
elif col == 1:
|
||||
return ", ".join(sorted(a for a in item.aliases()))
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return item
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return item.name
|
||||
case 1:
|
||||
return ", ".join(sorted(a for a in item.aliases()))
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,15 +3,15 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from setools import MLSRuletype
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from . import modelroles
|
||||
from .table import SEToolsTableModel
|
||||
from .. import details
|
||||
|
||||
|
||||
class MLSRuleTableModel(SEToolsTableModel):
|
||||
class MLSRuleTable(SEToolsTableModel[setools.MLSRule]):
|
||||
|
||||
"""A table-based model for MLS rules."""
|
||||
|
||||
@ -25,66 +25,75 @@ class MLSRuleTableModel(SEToolsTableModel):
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.ruletype.name
|
||||
elif col == 1:
|
||||
return rule.source.name
|
||||
elif col == 2:
|
||||
return rule.target.name
|
||||
elif col == 3:
|
||||
return rule.tclass.name
|
||||
elif col == 4:
|
||||
return str(rule.default)
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.ruletype.name
|
||||
case 1:
|
||||
return rule.source.name
|
||||
case 2:
|
||||
return rule.target.name
|
||||
case 3:
|
||||
return rule.tclass.name
|
||||
case 4:
|
||||
return str(rule.default)
|
||||
|
||||
elif role == modelroles.ContextMenuRole:
|
||||
if col == 1:
|
||||
return (details.type_or_attr_detail_action(rule.source), )
|
||||
elif col == 2:
|
||||
return (details.type_or_attr_detail_action(rule.target), )
|
||||
elif col == 3:
|
||||
return (details.objclass_detail_action(rule.tclass), )
|
||||
case modelroles.ContextMenuRole:
|
||||
match col:
|
||||
case 1:
|
||||
return (details.type_or_attr_detail_action(rule.source), )
|
||||
case 2:
|
||||
return (details.type_or_attr_detail_action(rule.target), )
|
||||
case 3:
|
||||
return (details.objclass_detail_action(rule.tclass), )
|
||||
|
||||
return ()
|
||||
case QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
match col:
|
||||
case 1:
|
||||
return details.type_or_attr_tooltip(rule.source)
|
||||
case 2:
|
||||
return details.type_or_attr_tooltip(rule.target)
|
||||
case 3:
|
||||
return details.objclass_tooltip(rule.tclass)
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
if col in (1, 2):
|
||||
if col == 1:
|
||||
return details.type_or_attr_tooltip(rule.source)
|
||||
else:
|
||||
return details.type_or_attr_tooltip(rule.target)
|
||||
elif col == 3:
|
||||
return details.objclass_tooltip(rule.tclass)
|
||||
case QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
match col:
|
||||
case 0:
|
||||
column_whatsthis = \
|
||||
f"""
|
||||
<p>The Rule Type column is the type of the rule; it is one of:</p>
|
||||
<ul>
|
||||
{"".join(f"<li>{t.name}</li>" for t in setools.MLSRuletype)}
|
||||
</ul>
|
||||
"""
|
||||
case 1:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This is the source type or type attribute (subject) in the rule.</p>
|
||||
"""
|
||||
case 2:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This is the target type or type attribute (object) in the rule.</p>
|
||||
"""
|
||||
case 3:
|
||||
column_whatsthis = "<p>This is the object class of the rule.</p>"
|
||||
case 4:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>Default Range: This the the default range specified in the rule.</p>
|
||||
"""
|
||||
case _:
|
||||
column_whatsthis = ""
|
||||
|
||||
return None
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
if col == 0:
|
||||
column_whatsthis = \
|
||||
return \
|
||||
f"""
|
||||
<p>The Rule Type column is the type of the rule; it is one of:</p>
|
||||
<ul>
|
||||
{"".join(f"<li>{t.name}</li>" for t in MLSRuletype)}
|
||||
</ul>
|
||||
<b><p>Table Representation of Multi-Level Security Rules</p></b>
|
||||
|
||||
<p>Each part of the rule is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
elif col == 1:
|
||||
column_whatsthis = \
|
||||
"<p>This is the source type or type attribute (subject) in the rule.</p>"
|
||||
elif col == 2:
|
||||
column_whatsthis = \
|
||||
"<p>This is the target type or type attribute (object) in the rule.</p>"
|
||||
elif col == 3:
|
||||
column_whatsthis = "<p>This is the object class of the rule.</p>"
|
||||
elif col == 4:
|
||||
column_whatsthis = \
|
||||
"""<p>Default Range: This the the default range specified in the rule.</p>"""
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of Multi-Level Security Rules</p></b>
|
||||
|
||||
<p>Each part of the rule is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,30 +3,34 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class NetifconTableModel(SEToolsTableModel):
|
||||
class NetifconTable(SEToolsTableModel[setools.Netifcon]):
|
||||
|
||||
"""Table-based model for netifcons."""
|
||||
|
||||
headers = ["Device", "Device Context", "Packet Context"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.netif
|
||||
elif col == 1:
|
||||
return str(rule.context)
|
||||
elif col == 2:
|
||||
return str(rule.packet)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.netif
|
||||
case 1:
|
||||
return str(rule.context)
|
||||
case 2:
|
||||
return str(rule.packet)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,28 +3,32 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class NodeconTableModel(SEToolsTableModel):
|
||||
class NodeconTable(SEToolsTableModel[setools.Nodecon]):
|
||||
|
||||
"""Table-based model for nodecons."""
|
||||
|
||||
headers = ["Network", "Context"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return str(rule.network.with_netmask)
|
||||
elif col == 1:
|
||||
return str(rule.context)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return str(rule.network.with_netmask)
|
||||
case 1:
|
||||
return str(rule.context)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -4,21 +4,17 @@
|
||||
#
|
||||
#
|
||||
from itertools import chain
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from setools.exception import NoCommon
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from . import modelroles
|
||||
from .list import SEToolsListModel
|
||||
from .table import SEToolsTableModel
|
||||
from .. import details
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from setools import ObjClass
|
||||
|
||||
|
||||
class ObjClassList(SEToolsListModel["ObjClass"]):
|
||||
class ObjClassList(SEToolsListModel[setools.ObjClass]):
|
||||
|
||||
"""List-based model for object classes."""
|
||||
|
||||
@ -29,36 +25,39 @@ class ObjClassList(SEToolsListModel["ObjClass"]):
|
||||
row = index.row()
|
||||
item = self.item_list[row]
|
||||
|
||||
if role == modelroles.ContextMenuRole:
|
||||
return (details.objclass_detail_action(item), )
|
||||
elif role == QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
return details.objclass_tooltip(item)
|
||||
match role:
|
||||
case modelroles.ContextMenuRole:
|
||||
return (details.objclass_detail_action(item), )
|
||||
|
||||
case QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
return details.objclass_tooltip(item)
|
||||
|
||||
return super().data(index, role)
|
||||
|
||||
|
||||
class ObjClassTableModel(SEToolsTableModel["ObjClass"]):
|
||||
class ObjClassTable(SEToolsTableModel[setools.ObjClass]):
|
||||
|
||||
"""Table-based model for object classes."""
|
||||
|
||||
headers = ["Name", "Permissions"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.name
|
||||
elif col == 1:
|
||||
try:
|
||||
com_perms = item.common.perms
|
||||
except NoCommon:
|
||||
com_perms = []
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
|
||||
return ", ".join(sorted(chain(com_perms, item.perms)))
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return item.name
|
||||
case 1:
|
||||
try:
|
||||
return ", ".join(sorted(chain(item.common.perms, item.perms)))
|
||||
except setools.exception.NoCommon:
|
||||
return ", ".join(sorted(item.perms))
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.UserRole:
|
||||
return item
|
||||
return super().data(index, role)
|
||||
|
@ -3,34 +3,37 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class PortconTableModel(SEToolsTableModel):
|
||||
class PortconTable(SEToolsTableModel[setools.Portcon]):
|
||||
|
||||
"""Table-based model for portcons."""
|
||||
|
||||
headers = ["Port/Port Range", "Protocol", "Context"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
low, high = rule.ports
|
||||
if low == high:
|
||||
return str(low)
|
||||
else:
|
||||
return "{0}-{1}".format(low, high)
|
||||
elif col == 1:
|
||||
return rule.protocol.name
|
||||
elif col == 2:
|
||||
return str(rule.context)
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return rule
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
low, high = rule.ports
|
||||
if low == high:
|
||||
return str(low)
|
||||
return f"{low}-{high}"
|
||||
case 1:
|
||||
return rule.protocol.name
|
||||
case 2:
|
||||
return str(rule.context)
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,16 +3,15 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from setools import AnyRBACRule, Role, Type
|
||||
from setools.exception import RuleUseError
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from . import modelroles
|
||||
from .table import SEToolsTableModel
|
||||
from .. import details
|
||||
|
||||
|
||||
class RBACRuleTableModel(SEToolsTableModel[AnyRBACRule]):
|
||||
class RBACRuleTable(SEToolsTableModel[setools.AnyRBACRule]):
|
||||
|
||||
"""A table-based model for RBAC rules."""
|
||||
|
||||
@ -26,105 +25,97 @@ class RBACRuleTableModel(SEToolsTableModel[AnyRBACRule]):
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.ruletype.name
|
||||
elif col == 1:
|
||||
return rule.source.name
|
||||
elif col == 2:
|
||||
return rule.target.name
|
||||
elif col == 3:
|
||||
try:
|
||||
return rule.tclass.name
|
||||
except RuleUseError:
|
||||
# role allow
|
||||
return None
|
||||
elif col == 4:
|
||||
try:
|
||||
return rule.default.name
|
||||
except RuleUseError:
|
||||
# role allow
|
||||
return None
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.ruletype.name
|
||||
case 1:
|
||||
return rule.source.name
|
||||
case 2:
|
||||
return rule.target.name
|
||||
case 3:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
return rule.tclass.name
|
||||
case 4:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
return rule.default.name
|
||||
|
||||
elif role == modelroles.ContextMenuRole:
|
||||
if col in (1, 2, 4):
|
||||
if col == 1:
|
||||
obj = rule.source
|
||||
elif col == 2:
|
||||
obj = rule.target
|
||||
else:
|
||||
try:
|
||||
obj = rule.default
|
||||
except RuleUseError:
|
||||
return ()
|
||||
return None
|
||||
|
||||
if isinstance(obj, Role):
|
||||
return (details.role_detail_action(obj), )
|
||||
else:
|
||||
return (details.type_or_attr_detail_action(obj), )
|
||||
case modelroles.ContextMenuRole:
|
||||
match col:
|
||||
case 1:
|
||||
return (details.role_detail_action(rule.source), )
|
||||
case 2:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
return (details.type_or_attr_detail_action(rule.target), )
|
||||
return (details.role_detail_action(rule.target), )
|
||||
case 3:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
return (details.objclass_detail_action(rule.tclass), )
|
||||
case 4:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
return (details.role_detail_action(rule.default), )
|
||||
|
||||
elif col == 3:
|
||||
try:
|
||||
return (details.objclass_detail_action(rule.tclass), )
|
||||
except RuleUseError:
|
||||
pass
|
||||
case QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
match col:
|
||||
case 1:
|
||||
return details.role_tooltip(rule.source)
|
||||
case 2:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
return details.type_or_attr_tooltip(rule.target)
|
||||
return details.role_tooltip(rule.target)
|
||||
case 3:
|
||||
return details.objclass_tooltip(rule.tclass)
|
||||
case 4:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
return details.role_tooltip(rule.default)
|
||||
|
||||
return ()
|
||||
case QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
match col:
|
||||
case 0:
|
||||
column_whatsthis = f"<p>{rule.ruletype} is the type of the rule.</p>"
|
||||
case 1:
|
||||
column_whatsthis = \
|
||||
f"<p>{rule.source} is the source role (subject) in the rule.</p>"
|
||||
case 2:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
column_whatsthis = \
|
||||
f"""
|
||||
<p>{rule.target} is the target type/attribute (object) in the rule.
|
||||
</p>"""
|
||||
else:
|
||||
column_whatsthis = \
|
||||
f"<p>{rule.target} is the target role (object) in the rule.</p>"
|
||||
case 3:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
column_whatsthis = \
|
||||
f"<p>{rule.tclass} is the object class of the rule.</p>"
|
||||
else:
|
||||
column_whatsthis = \
|
||||
f"""
|
||||
<p>The object class column does not apply to {rule.ruletype} rules.
|
||||
</p>"""
|
||||
case 4:
|
||||
if rule.ruletype == setools.RBACRuletype.role_transition:
|
||||
column_whatsthis = \
|
||||
f"<p>{rule.default} is the default role in the rule.<p>"
|
||||
else:
|
||||
column_whatsthis = \
|
||||
f"""
|
||||
<p>The default role column does not apply to {rule.ruletype} rules.
|
||||
</p>"""
|
||||
case _:
|
||||
column_whatsthis = ""
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
if col in (1, 2):
|
||||
if col == 1:
|
||||
obj = rule.source
|
||||
elif col == 2:
|
||||
obj = rule.target
|
||||
else:
|
||||
try:
|
||||
obj = rule.default
|
||||
except RuleUseError:
|
||||
return None
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of Role-based Access Control (RBAC) Rules</p></b>
|
||||
|
||||
if isinstance(obj, Role):
|
||||
return details.role_tooltip(obj)
|
||||
else:
|
||||
return details.type_or_attr_tooltip(obj)
|
||||
elif col == 3:
|
||||
return details.objclass_tooltip(rule.tclass)
|
||||
<p>Each part of the rule is represented as a column in the table.</p>
|
||||
|
||||
return None
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
if col == 0:
|
||||
column_whatsthis = f"<p>{rule.ruletype} is the type of the rule.</p>"
|
||||
elif col == 1:
|
||||
column_whatsthis = \
|
||||
f"<p>{rule.source} is the source role (subject) in the rule.</p>"
|
||||
elif col == 2:
|
||||
if isinstance(rule.target, Role):
|
||||
column_whatsthis = \
|
||||
f"<p>{rule.target} is the target role (object) in the rule.</p>"
|
||||
else:
|
||||
column_whatsthis = \
|
||||
f"<p>{rule.target} is the target type/attribute (object) in the rule.</p>"
|
||||
elif col == 3:
|
||||
try:
|
||||
column_whatsthis = f"<p>{rule.tclass} is the object class of the rule.</p>"
|
||||
except RuleUseError:
|
||||
column_whatsthis = \
|
||||
f"<p>The object class column does not apply to {rule.ruletype} rules.</p>"
|
||||
elif col == 4:
|
||||
try:
|
||||
column_whatsthis = f"<p>{rule.default} is the default role in the rule.<p>"
|
||||
except RuleUseError:
|
||||
column_whatsthis = \
|
||||
f"<p>The default role column does not apply to {rule.ruletype} rules.</p>"
|
||||
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of Role-based Access Control (RBAC) Rules</p></b>
|
||||
|
||||
<p>Each part of the rule is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
{column_whatsthis}
|
||||
"""
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,34 +3,60 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QPalette, QTextCursor
|
||||
|
||||
from setools.exception import MLSDisabled
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .. import details
|
||||
from . import modelroles
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class RoleTableModel(SEToolsTableModel):
|
||||
class RoleTable(SEToolsTableModel[setools.Role]):
|
||||
|
||||
"""Table-based model for roles."""
|
||||
|
||||
headers = ["Name", "Types"]
|
||||
|
||||
def data(self, index, role):
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
# There are two roles here.
|
||||
# The parameter, role, is the Qt role
|
||||
# The below item is a role in the list.
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.name
|
||||
elif col == 1:
|
||||
return ", ".join(sorted(t.name for t in item.types()))
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
# get the whole object
|
||||
return item
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return item.name
|
||||
case 1:
|
||||
return ", ".join(sorted(t.name for t in item.types()))
|
||||
|
||||
case modelroles.ContextMenuRole:
|
||||
if col == 1:
|
||||
return (details.type_detail_action(t) for t in sorted(item.types()))
|
||||
|
||||
case QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
match col:
|
||||
case 0:
|
||||
column_whatsthis = "<p>This is the name of the role.</p>"
|
||||
case 1:
|
||||
column_whatsthis = \
|
||||
"<p>This is the list of types associated with this role.</p>"
|
||||
case _:
|
||||
column_whatsthis = ""
|
||||
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of Roles</p></b>
|
||||
|
||||
<p>Each part of the declaration is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -14,6 +14,7 @@ from .typing import MetaclassFix
|
||||
T = typing.TypeVar("T")
|
||||
|
||||
|
||||
# pylint: disable=invalid-metaclass
|
||||
class SEToolsTableModel(QtCore.QAbstractTableModel, typing.Generic[T], metaclass=MetaclassFix):
|
||||
|
||||
"""Base class for SETools table models, modeling a list in a tabular form."""
|
||||
|
@ -5,8 +5,8 @@
|
||||
#
|
||||
from contextlib import suppress
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from setools import AnyTERule, TERuletype, TypeAttribute
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
from setools.exception import RuleNotConditional, RuleUseError
|
||||
|
||||
from . import modelroles
|
||||
@ -14,7 +14,7 @@ from .table import SEToolsTableModel
|
||||
from .. import details
|
||||
|
||||
|
||||
class TERuleTableModel(SEToolsTableModel[AnyTERule]):
|
||||
class TERuleTable(SEToolsTableModel[setools.AnyTERule]):
|
||||
|
||||
"""A table-based model for TE rules."""
|
||||
|
||||
@ -29,107 +29,114 @@ class TERuleTableModel(SEToolsTableModel[AnyTERule]):
|
||||
col = index.column()
|
||||
rule = self.item_list[row]
|
||||
|
||||
if role == QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return rule.ruletype.name
|
||||
elif col == 1:
|
||||
return rule.source.name
|
||||
elif col == 2:
|
||||
return rule.target.name
|
||||
elif col == 3:
|
||||
return rule.tclass.name
|
||||
elif col == 4:
|
||||
try:
|
||||
if rule.extended:
|
||||
return f"{rule.xperm_type}: {rule.perms:,}" # type: ignore
|
||||
else:
|
||||
return ", ".join(sorted(rule.perms)) # type: ignore
|
||||
except RuleUseError:
|
||||
return rule.default.name # type: ignore
|
||||
elif col == 5:
|
||||
with suppress(RuleNotConditional):
|
||||
return str(rule.conditional)
|
||||
elif col == 6:
|
||||
with suppress(RuleNotConditional):
|
||||
return str(rule.conditional_block)
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return rule.ruletype.name
|
||||
case 1:
|
||||
return rule.source.name
|
||||
case 2:
|
||||
return rule.target.name
|
||||
case 3:
|
||||
return rule.tclass.name
|
||||
case 4:
|
||||
try:
|
||||
if rule.extended:
|
||||
return f"{rule.xperm_type}: {rule.perms:,}" # type: ignore
|
||||
else:
|
||||
return ", ".join(sorted(rule.perms)) # type: ignore
|
||||
except RuleUseError:
|
||||
return rule.default.name # type: ignore
|
||||
case 5:
|
||||
with suppress(RuleNotConditional):
|
||||
return str(rule.conditional)
|
||||
case 6:
|
||||
with suppress(RuleNotConditional):
|
||||
return str(rule.conditional_block)
|
||||
|
||||
return None
|
||||
return None
|
||||
|
||||
elif role == modelroles.ContextMenuRole:
|
||||
if col == 1:
|
||||
return (details.type_or_attr_detail_action(rule.source), )
|
||||
elif col == 2:
|
||||
return (details.type_or_attr_detail_action(rule.target), )
|
||||
elif col == 3:
|
||||
return (details.objclass_detail_action(rule.tclass), )
|
||||
elif col == 4:
|
||||
with suppress(RuleUseError):
|
||||
return (details.type_detail_action(rule.default), )
|
||||
case modelroles.ContextMenuRole:
|
||||
match col:
|
||||
case 1:
|
||||
return (details.type_or_attr_detail_action(rule.source), )
|
||||
case 2:
|
||||
return (details.type_or_attr_detail_action(rule.target), )
|
||||
case 3:
|
||||
return (details.objclass_detail_action(rule.tclass), )
|
||||
case 4:
|
||||
with suppress(RuleUseError):
|
||||
return (details.type_detail_action(rule.default), )
|
||||
|
||||
return ()
|
||||
case QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
match col:
|
||||
case 1:
|
||||
return details.type_or_attr_tooltip(rule.source)
|
||||
case 2:
|
||||
return details.type_or_attr_tooltip(rule.target)
|
||||
case 3:
|
||||
return details.objclass_tooltip(rule.tclass)
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.ToolTipRole:
|
||||
if col in (1, 2):
|
||||
if col == 1:
|
||||
return details.type_or_attr_tooltip(rule.source)
|
||||
else:
|
||||
return details.type_or_attr_tooltip(rule.target)
|
||||
elif col == 3:
|
||||
return details.objclass_tooltip(rule.tclass)
|
||||
case QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
match col:
|
||||
case 0:
|
||||
column_whatsthis = \
|
||||
f"""
|
||||
<p>The Rule Type column is the type of the rule; it is one of:</p>
|
||||
<ul>
|
||||
{"".join(f"<li>{t.name}</li>" for t in setools.TERuletype)}
|
||||
</ul>
|
||||
"""
|
||||
case 1:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This is the source type or type attribute (subject) in the rule.</p>
|
||||
"""
|
||||
case 2:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This is the target type or type attribute (object) in the rule.</p>
|
||||
"""
|
||||
case 3:
|
||||
column_whatsthis = "<p>This is the object class of the rule.</p>"
|
||||
case 4:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>Permissions/Default Type: The value of this depends on the rule
|
||||
type:</p>
|
||||
<ul>
|
||||
<li>Allow and allow-like rules: These are the permissions set in the
|
||||
rule.</li>
|
||||
<li>type_* rules: This the the default type specified in the rule.</li>
|
||||
</ul>
|
||||
</li>
|
||||
"""
|
||||
case 5:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This is the conditional expression that enables/disables
|
||||
this rule. If this is blank, the rule is unconditional.</p>
|
||||
"""
|
||||
case 6:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This contains the conditional branch that that rule resides in.
|
||||
"True" means the rule is enabled when the conditional expression is
|
||||
true; also known as the "if" block. "False" means the rule is enabled
|
||||
when the conditional expression is false; also known as the "else"
|
||||
block. If this is blank, the rule is unconditional.</p>
|
||||
"""
|
||||
case _:
|
||||
column_whatsthis = ""
|
||||
|
||||
return None
|
||||
|
||||
elif role == QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
if col == 0:
|
||||
column_whatsthis = \
|
||||
return \
|
||||
f"""
|
||||
<p>The Rule Type column is the type of the rule; it is one of:</p>
|
||||
<ul>
|
||||
{"".join(f"<li>{t.name}</li>" for t in TERuletype)}
|
||||
</ul>
|
||||
"""
|
||||
elif col == 1:
|
||||
column_whatsthis = \
|
||||
"<p>This is the source type or type attribute (subject) in the rule.</p>"
|
||||
elif col == 2:
|
||||
column_whatsthis = \
|
||||
"<p>This is the target type or type attribute (object) in the rule.</p>"
|
||||
elif col == 3:
|
||||
column_whatsthis = "<p>This is the object class of the rule.</p>"
|
||||
elif col == 4:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>Permissions/Default Type: The value of this depends on the rule type:</p>
|
||||
<ul>
|
||||
<li>Allow and allow-like rules: These are the permissions set in the rule.
|
||||
</li>
|
||||
<li>type_* rules: This the the default type specified in the rule.</li>
|
||||
</ul>
|
||||
</li>
|
||||
"""
|
||||
elif col == 5:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This is the conditional expression that enables/disables
|
||||
this rule. If this is blank, the rule is unconditional.</p>
|
||||
"""
|
||||
elif col == 6:
|
||||
column_whatsthis = \
|
||||
"""
|
||||
<p>This contains the conditional branch that that rule resides in.
|
||||
"True" means the rule is enabled when the conditional expression is true;
|
||||
also known as the "if" block. "False" means the rule is enabled when the
|
||||
conditional expression is false; also known as the "else" block. If this
|
||||
is blank, the rule is unconditional.</p>
|
||||
"""
|
||||
<b><p>Table Representation of Type Enforcement Rules</p></b>
|
||||
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of Type Enforcement Rules</p></b>
|
||||
<p>Each part of the rule is represented as a column in the table.</p>
|
||||
|
||||
<p>Each part of the rule is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
{column_whatsthis}
|
||||
"""
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,32 +3,67 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .. import details
|
||||
from . import modelroles
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class TypeTableModel(SEToolsTableModel):
|
||||
class TypeTable(SEToolsTableModel[setools.Type]):
|
||||
|
||||
"""Table-based model for types."""
|
||||
|
||||
headers = ["Name", "Attributes", "Aliases", "Permissive"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.name
|
||||
elif col == 1:
|
||||
return ", ".join(sorted(a.name for a in item.attributes()))
|
||||
elif col == 2:
|
||||
return ", ".join(sorted(a for a in item.aliases()))
|
||||
elif col == 3 and item.ispermissive:
|
||||
return "Permissive"
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return item
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return item.name
|
||||
case 1:
|
||||
return ", ".join(sorted(a.name for a in item.attributes()))
|
||||
case 2:
|
||||
return ", ".join(sorted(a for a in item.aliases()))
|
||||
case 3:
|
||||
return "Permissive" if item.ispermissive else None
|
||||
|
||||
case modelroles.ContextMenuRole:
|
||||
if col == 1:
|
||||
return (details.typeattr_detail_action(ta) for ta in sorted(item.attributes()))
|
||||
|
||||
case QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
match col:
|
||||
case 0:
|
||||
column_whatsthis = "<p>This is the name of the type.</p>"
|
||||
case 1:
|
||||
column_whatsthis = \
|
||||
"<p>This is the list of attributes this type belongs to.</p>"
|
||||
case 2:
|
||||
column_whatsthis = \
|
||||
"<p>This is the list of alias names for this type.</p>"
|
||||
case 3:
|
||||
column_whatsthis = \
|
||||
"<p>This indicates whether the type is permissive.</p>"
|
||||
case _:
|
||||
column_whatsthis = ""
|
||||
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of SELinux Types</p></b>
|
||||
|
||||
<p>Each part of the declaration is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,31 +3,57 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QPalette, QTextCursor
|
||||
|
||||
from setools.exception import MLSDisabled
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .. import details
|
||||
from . import modelroles
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
class TypeAttributeTableModel(SEToolsTableModel):
|
||||
class TypeAttributeTable(SEToolsTableModel[setools.TypeAttribute]):
|
||||
|
||||
"""Table-based model for roles."""
|
||||
|
||||
headers = ["Name", "Types"]
|
||||
|
||||
def data(self, index, role):
|
||||
if self.item_list and index.isValid():
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
item = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
if col == 0:
|
||||
return item.name
|
||||
elif col == 1:
|
||||
return ", ".join(sorted(t.name for t in item.expand()))
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
attr = self.item_list[row]
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return item
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return attr.name
|
||||
case 1:
|
||||
return ", ".join(sorted(a.name for a in sorted(attr.expand())))
|
||||
|
||||
case modelroles.ContextMenuRole:
|
||||
if col == 1:
|
||||
return (details.type_detail_action(t) for t in sorted(attr.expand()))
|
||||
|
||||
case QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
match col:
|
||||
case 0:
|
||||
column_whatsthis = "<p>This is the name of the type attribute.</p>"
|
||||
case 1:
|
||||
column_whatsthis = \
|
||||
"<p>This is the list of types associated with the attribute.</p>"
|
||||
case _:
|
||||
column_whatsthis = ""
|
||||
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of SELinux users</p></b>
|
||||
|
||||
<p>Each part of the declaration is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -3,78 +3,74 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-only
|
||||
#
|
||||
#
|
||||
from PyQt5.QtCore import Qt, QModelIndex
|
||||
from setools.exception import MLSDisabled
|
||||
import typing
|
||||
|
||||
from .details import DetailsPopup
|
||||
from PyQt5 import QtCore
|
||||
import setools
|
||||
|
||||
from .. import details
|
||||
from . import modelroles
|
||||
from .table import SEToolsTableModel
|
||||
|
||||
|
||||
def user_detail(parent, user):
|
||||
"""
|
||||
Create a dialog box for user details.
|
||||
|
||||
Parameters:
|
||||
parent The parent Qt Widget
|
||||
user The user
|
||||
"""
|
||||
|
||||
detail = DetailsPopup(parent, "User detail: {0}".format(user))
|
||||
|
||||
roles = sorted(user.roles)
|
||||
detail.append_header("Roles ({0}):".format(len(roles)))
|
||||
|
||||
for role in roles:
|
||||
detail.append(" {0}".format(role))
|
||||
|
||||
try:
|
||||
level = user.mls_level
|
||||
range_ = user.mls_range
|
||||
except MLSDisabled:
|
||||
pass
|
||||
else:
|
||||
detail.append_header("\nDefault MLS Level:")
|
||||
detail.append(" {0}".format(level))
|
||||
detail.append_header("\nMLS Range:")
|
||||
detail.append(" {0}".format(range_))
|
||||
|
||||
detail.show()
|
||||
|
||||
|
||||
class UserTableModel(SEToolsTableModel):
|
||||
class UserTable(SEToolsTableModel[setools.User]):
|
||||
|
||||
"""Table-based model for users."""
|
||||
|
||||
headers = ["Name", "Roles", "Default Level", "Range"]
|
||||
|
||||
def __init__(self, parent, mls):
|
||||
super(UserTableModel, self).__init__(parent)
|
||||
self.col_count = 4 if mls else 2
|
||||
def __init__(self, mls: bool = False, parent: QtCore.QObject | None = None):
|
||||
super().__init__(parent)
|
||||
self.mls: typing.Final[bool] = mls
|
||||
|
||||
def columnCount(self, parent=QModelIndex()):
|
||||
return self.col_count
|
||||
def columnCount(self, parent=QtCore.QModelIndex()) -> int:
|
||||
return 4 if self.mls else 2
|
||||
|
||||
def data(self, index, role):
|
||||
if self.resultlist and index.isValid():
|
||||
if role == Qt.ItemDataRole.DisplayRole:
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
user = self.item_list[row]
|
||||
def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.ItemDataRole.DisplayRole):
|
||||
if not self.item_list or not index.isValid():
|
||||
return None
|
||||
|
||||
if col == 0:
|
||||
return user.name
|
||||
elif col == 1:
|
||||
return ", ".join(sorted(r.name for r in user.roles))
|
||||
elif col == 2:
|
||||
try:
|
||||
row = index.row()
|
||||
col = index.column()
|
||||
user = self.item_list[row]
|
||||
|
||||
match role:
|
||||
case QtCore.Qt.ItemDataRole.DisplayRole:
|
||||
match col:
|
||||
case 0:
|
||||
return user.name
|
||||
case 1:
|
||||
return ", ".join(sorted(r.name for r in user.roles))
|
||||
case 2:
|
||||
return str(user.mls_level)
|
||||
except MLSDisabled:
|
||||
return None
|
||||
elif col == 3:
|
||||
try:
|
||||
case 3:
|
||||
return str(user.mls_range)
|
||||
except MLSDisabled:
|
||||
return None
|
||||
|
||||
elif role == Qt.ItemDataRole.UserRole:
|
||||
return user
|
||||
case modelroles.ContextMenuRole:
|
||||
if col == 1:
|
||||
return (details.role_detail_action(r) for r in sorted(user.roles))
|
||||
|
||||
case QtCore.Qt.ItemDataRole.WhatsThisRole:
|
||||
match col:
|
||||
case 0:
|
||||
column_whatsthis = "<p>This is the name of the user.</p>"
|
||||
case 1:
|
||||
column_whatsthis = \
|
||||
"<p>This is the list of roles associated with the user.</p>"
|
||||
case 2:
|
||||
column_whatsthis = "<p>This is the default MLS level of the user.</p>"
|
||||
case 3:
|
||||
column_whatsthis = "<p>This is allowed range for the user.</p>"
|
||||
case _:
|
||||
column_whatsthis = ""
|
||||
|
||||
return \
|
||||
f"""
|
||||
<b><p>Table Representation of SELinux users</p></b>
|
||||
|
||||
<p>Each part of the declaration is represented as a column in the table.</p>
|
||||
|
||||
{column_whatsthis}
|
||||
"""
|
||||
|
||||
return super().data(index, role)
|
||||
|
@ -6,8 +6,7 @@ from typing import TYPE_CHECKING
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
import setools
|
||||
|
||||
from . import criteria, tab
|
||||
from .models.rbacrule import RBACRuleTableModel
|
||||
from . import criteria, models, tab
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional
|
||||
@ -118,7 +117,7 @@ class RBACRuleQueryTab(tab.TableResultTabWidget):
|
||||
self.criteria = (rt, src, dst, tclass, dflt)
|
||||
|
||||
# Set result table's model
|
||||
self.table_results_model = RBACRuleTableModel(self.table_results)
|
||||
self.table_results_model = models.RBACRuleTable(self.table_results)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -6,8 +6,7 @@ from typing import TYPE_CHECKING
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
import setools
|
||||
|
||||
from . import criteria, tab
|
||||
from .models.terule import TERuleTableModel
|
||||
from . import criteria, models, tab
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Optional
|
||||
@ -165,7 +164,7 @@ class TERuleQueryTab(tab.TableResultTabWidget):
|
||||
self.criteria = (rt, src, dst, tclass, perms, dflt, bools)
|
||||
|
||||
# Set result table's model
|
||||
self.table_results_model = TERuleTableModel(self.table_results)
|
||||
self.table_results_model = models.TERuleTable(self.table_results)
|
||||
|
||||
# Connect signals
|
||||
tclass.selectionChanged.connect(perms.set_classes)
|
||||
|
Loading…
Reference in New Issue
Block a user