sourcecode 3.1.1__py3-none-any.whl → 3.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sourcecode might be problematic. Click here for more details.
- sourcecode/__init__.py +1 -1
- sourcecode/chain_rules.py +49 -8
- sourcecode/cli.py +272 -185
- sourcecode/confidence_analyzer.py +10 -6
- sourcecode/deployment_prefix.py +85 -0
- sourcecode/detectors/java.py +10 -5
- sourcecode/facts/__init__.py +71 -0
- sourcecode/facts/registry.json +158 -0
- sourcecode/integration_coordinates.py +175 -0
- sourcecode/mcp/registry.py +4 -2
- sourcecode/mcp/server.py +6 -3
- sourcecode/metrics_analyzer.py +8 -5
- sourcecode/posture.py +78 -6
- sourcecode/prepare_context.py +44 -19
- sourcecode/reference_facts.py +307 -0
- sourcecode/repository_ir.py +25 -17
- sourcecode/retrieval/steps_graph.py +10 -8
- sourcecode/retrieval/steps_intf.py +23 -1
- sourcecode/security_posture.py +165 -19
- sourcecode/semantic_integration_engine.py +54 -2
- sourcecode/serializer.py +36 -9
- sourcecode/spring_impact.py +124 -7
- sourcecode/spring_profiles.py +93 -13
- sourcecode/spring_semantic.py +56 -4
- sourcecode/test_sources.py +178 -0
- {sourcecode-3.1.1.dist-info → sourcecode-3.2.1.dist-info}/METADATA +100 -10
- {sourcecode-3.1.1.dist-info → sourcecode-3.2.1.dist-info}/RECORD +30 -25
- {sourcecode-3.1.1.dist-info → sourcecode-3.2.1.dist-info}/WHEEL +0 -0
- {sourcecode-3.1.1.dist-info → sourcecode-3.2.1.dist-info}/entry_points.txt +0 -0
- {sourcecode-3.1.1.dist-info → sourcecode-3.2.1.dist-info}/licenses/LICENSE +0 -0
sourcecode/__init__.py
CHANGED
sourcecode/chain_rules.py
CHANGED
|
@@ -274,16 +274,57 @@ def rule_matches(rule: AccessRule, method: str, path: str) -> bool:
|
|
|
274
274
|
return any(ant_matches(pattern, path) for pattern in rule.patterns)
|
|
275
275
|
|
|
276
276
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
277
|
+
#: Matchers that see the DispatcherServlet path. An ant matcher matches the URL
|
|
278
|
+
#: the filter chain receives — servlet path included, servlet CONTEXT path never,
|
|
279
|
+
#: because the container has already stripped it. An mvc matcher matches the path
|
|
280
|
+
#: relative to the servlet mapping, so the servlet path is not part of it.
|
|
281
|
+
#: `requestMatchers` is either one depending on the Spring Security version and
|
|
282
|
+
#: what is on the classpath — undecidable from source, so both readings are tried
|
|
283
|
+
#: and the pattern is honoured if it covers the request under either.
|
|
284
|
+
_SERVLET_PATH_MATCHERS = ("antMatchers", "regexMatchers", "requestMatchers")
|
|
285
|
+
_SERVLET_RELATIVE_MATCHERS = ("mvcMatchers", "requestMatchers")
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def candidate_paths(rule: AccessRule, path: str, servlet_prefix: str = "") -> "tuple[str, ...]":
|
|
289
|
+
"""The path(s) `rule`'s matcher compares against a mapping-relative `path`.
|
|
290
|
+
|
|
291
|
+
Without a declared servlet path the two readings coincide and this is just
|
|
292
|
+
`(path,)` — which is every repository that never set `spring.mvc.servlet.path`.
|
|
293
|
+
"""
|
|
294
|
+
if not servlet_prefix or rule.is_any_request:
|
|
295
|
+
return (path,)
|
|
296
|
+
prefixed = f"{servlet_prefix.rstrip('/')}/{path.lstrip('/')}".rstrip("/") or "/"
|
|
297
|
+
out: list[str] = []
|
|
298
|
+
if rule.matcher in _SERVLET_PATH_MATCHERS:
|
|
299
|
+
out.append(prefixed)
|
|
300
|
+
if rule.matcher in _SERVLET_RELATIVE_MATCHERS or not out:
|
|
301
|
+
out.append(path)
|
|
302
|
+
return tuple(dict.fromkeys(out))
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def first_match(
|
|
306
|
+
rules: "list[AccessRule]", method: str, path: str, servlet_prefix: str = ""
|
|
307
|
+
) -> "tuple[Optional[AccessRule], str]":
|
|
308
|
+
"""`(rule Spring would apply, the path it matched)` — first declared wins.
|
|
309
|
+
|
|
310
|
+
The matched path is returned because with a servlet path declared it is not
|
|
311
|
+
the mapping-relative path the endpoint is keyed by, and a reader checking the
|
|
312
|
+
claim against the source line needs to see the URL the rule actually covers.
|
|
313
|
+
"""
|
|
281
314
|
for rule in rules:
|
|
282
315
|
if rule.paths_unknown:
|
|
283
316
|
# A rule whose paths could not be read may cover this request, and
|
|
284
317
|
# everything after it is only reachable if it does not. Stopping here
|
|
285
318
|
# is what keeps a later `permitAll` from being reported as the answer.
|
|
286
|
-
return rule
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
319
|
+
return rule, path
|
|
320
|
+
for candidate in candidate_paths(rule, path, servlet_prefix):
|
|
321
|
+
if rule_matches(rule, method, candidate):
|
|
322
|
+
return rule, candidate
|
|
323
|
+
return None, path
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def first_matching_rule(
|
|
327
|
+
rules: "list[AccessRule]", method: str, path: str, servlet_prefix: str = ""
|
|
328
|
+
) -> "Optional[AccessRule]":
|
|
329
|
+
"""The rule Spring would apply: the first declared one that matches."""
|
|
330
|
+
return first_match(rules, method, path, servlet_prefix)[0]
|