Skip to content

Commit 7b3bde1

Browse files
committed
Fixes #1285
1 parent ba2f188 commit 7b3bde1

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

doc/sonar-audit.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ sonar-audit --what projects -f projectsAudit.csv --csvSeparator ';'
121121
- More than `audit.projects.permissions.maxAdminGroups` groups with project admin permission (default 2)
122122
- `sonar-users` group with elevated project permissions
123123
- `Anyone` group with any project permissions
124+
- No projectKeyPattern for a template that is not a default
125+
- Suspicious projectKeyPattern (a pattern that is likely to not select more than 1 key) for instance:
126+
- `my_favorite_project` (no `.` in pattern)
127+
- `BUXXXX-*` (Likely confusion between wildcards and regexp)
124128
- DB Cleaner: (if `audit.globalSettings = yes`, default `yes`)
125129
- Delay to delete inactive short lived branches (7.9) or branches (8.0+) not between 10 and 60 days
126130
- Delay to delete closed issues not between 10 and 60 days

sonar/audit/rules.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@
1919
"type": "OPERATIONS",
2020
"message": "{} has no user or group with admin permission"
2121
},
22+
"TEMPLATE_WITH_NO_PATTERN": {
23+
"severity": "MEDIUM",
24+
"type": "OPERATIONS",
25+
"message": "{} is not a default and has no projectKetPattern defined, it will never be used"
26+
},
27+
"TEMPLATE_WITH_SUSPICIOUS_PATTERN": {
28+
"severity": "HIGH",
29+
"type": "OPERATIONS",
30+
"message": "{} has a suspicious projectKeyPattern '{}'. It should be a regexp that may match several keys"
31+
},
2232
"DUBIOUS_GLOBAL_SETTING": {
2333
"severity": "HIGH",
2434
"type": "BAD_PRACTICE",

sonar/audit/rules.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ class RuleId(enum.Enum):
163163

164164
GROUP_EMPTY = 5200
165165

166+
TEMPLATE_WITH_NO_PATTERN = 5300
167+
TEMPLATE_WITH_SUSPICIOUS_PATTERN = 5301
168+
166169
ERROR_IN_LOGS = 6000
167170
WARNING_IN_LOGS = 6001
168171
DEPRECATION_WARNINGS = 6002

sonar/permissions/permission_templates.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
from __future__ import annotations
2222

2323
import json
24+
import re
2425
from requests.exceptions import HTTPError
2526

2627
import sonar.logging as log
2728
from sonar.util import types
2829
from sonar import sqobject, utilities
2930
from sonar.permissions import template_permissions
3031
import sonar.platform as pf
32+
from sonar.audit.rules import get_rule, RuleId
3133
import sonar.audit.problem as pb
3234

3335
_OBJECTS = {}
@@ -176,9 +178,23 @@ def to_json(self, export_settings: types.ConfigSettings = None) -> types.ObjectJ
176178
json_data["lastUpdate"] = utilities.date_to_string(self.last_update)
177179
return utilities.remove_nones(utilities.filter_export(json_data, _IMPORTABLE_PROPERTIES, export_settings.get("FULL_EXPORT", False)))
178180

181+
def _audit_pattern(self, audit_settings: types.ConfigSettings) -> list[pb.Problem]:
182+
log.debug("Auditing %s projectKeyPattern ('%s')", str(self.project_key_pattern))
183+
if not self.project_key_pattern or self.project_key_pattern == "":
184+
if not (self.is_applications_default() or self.is_portfolios_default() or self.is_projects_default()):
185+
return [pb.Problem(get_rule(RuleId.TEMPLATE_WITH_NO_PATTERN), self, str(self))]
186+
else:
187+
# Inspect regexp to detect suspicious pattern - Can't determine all bad cases but do our best
188+
# Currently detecting:
189+
# - Absence of '.' in the regexp
190+
# - '*' not preceded by '.' (confusion between wildcard and regexp)
191+
if not re.search(r"(^|[^\\])\.", self.project_key_pattern) or re.search(r"(^|[^.])\*", self.project_key_pattern):
192+
return [pb.Problem(get_rule(RuleId.TEMPLATE_WITH_SUSPICIOUS_PATTERN), self, str(self), self.project_key_pattern)]
193+
return []
194+
179195
def audit(self, audit_settings: types.ConfigSettings) -> list[pb.Problem]:
180196
log.debug("Auditing %s", str(self))
181-
return self.permissions().audit(audit_settings)
197+
return self._audit_pattern(audit_settings) + self.permissions().audit(audit_settings)
182198

183199

184200
def get_object(endpoint: pf.Platform, name: str) -> PermissionTemplate:

0 commit comments

Comments
 (0)