Harden mail profile validation
This commit is contained in:
@@ -285,11 +285,15 @@ def _legacy_tenant_settings(session: Session, tenant_id: str) -> dict[str, Any]
|
|||||||
return _json_object(row[0]) if row else None
|
return _json_object(row[0]) if row else None
|
||||||
|
|
||||||
|
|
||||||
def _legacy_subject_policy(session: Session, *, table_name: str, tenant_id: str, scope_id: str) -> dict[str, Any] | None:
|
def _legacy_subject_policy(session: Session, *, subject_type: str, tenant_id: str, scope_id: str) -> dict[str, Any] | None:
|
||||||
if table_name not in {"access_users", "access_groups"}:
|
if subject_type == "user":
|
||||||
|
statement = text("select mail_profile_policy from access_users where id = :scope_id and tenant_id = :tenant_id")
|
||||||
|
elif subject_type == "group":
|
||||||
|
statement = text("select mail_profile_policy from access_groups where id = :scope_id and tenant_id = :tenant_id")
|
||||||
|
else:
|
||||||
raise MailProfileError("Unsupported mail policy subject")
|
raise MailProfileError("Unsupported mail policy subject")
|
||||||
row = session.execute(
|
row = session.execute(
|
||||||
text(f"select mail_profile_policy from {table_name} where id = :scope_id and tenant_id = :tenant_id"),
|
statement,
|
||||||
{"scope_id": scope_id, "tenant_id": tenant_id},
|
{"scope_id": scope_id, "tenant_id": tenant_id},
|
||||||
).first()
|
).first()
|
||||||
return _json_object(row[0]) if row else None
|
return _json_object(row[0]) if row else None
|
||||||
@@ -304,7 +308,7 @@ def _user_exists(session: Session, *, tenant_id: str, user_id: str) -> bool:
|
|||||||
if directory is not None:
|
if directory is not None:
|
||||||
user = directory.get_user(user_id)
|
user = directory.get_user(user_id)
|
||||||
return bool(user and user.tenant_id == tenant_id and user.status == "active")
|
return bool(user and user.tenant_id == tenant_id and user.status == "active")
|
||||||
return _legacy_subject_policy(session, table_name="access_users", tenant_id=tenant_id, scope_id=user_id) is not None
|
return _legacy_subject_policy(session, subject_type="user", tenant_id=tenant_id, scope_id=user_id) is not None
|
||||||
|
|
||||||
|
|
||||||
def _group_exists(session: Session, *, tenant_id: str, group_id: str) -> bool:
|
def _group_exists(session: Session, *, tenant_id: str, group_id: str) -> bool:
|
||||||
@@ -312,7 +316,7 @@ def _group_exists(session: Session, *, tenant_id: str, group_id: str) -> bool:
|
|||||||
if directory is not None:
|
if directory is not None:
|
||||||
group = directory.get_group(group_id)
|
group = directory.get_group(group_id)
|
||||||
return bool(group and group.tenant_id == tenant_id and group.status == "active")
|
return bool(group and group.tenant_id == tenant_id and group.status == "active")
|
||||||
return _legacy_subject_policy(session, table_name="access_groups", tenant_id=tenant_id, scope_id=group_id) is not None
|
return _legacy_subject_policy(session, subject_type="group", tenant_id=tenant_id, scope_id=group_id) is not None
|
||||||
|
|
||||||
|
|
||||||
def _policy_scope_key(*, tenant_id: str, scope_type: str, scope_id: str | None) -> tuple[str | None, str, str | None]:
|
def _policy_scope_key(*, tenant_id: str, scope_type: str, scope_id: str | None) -> tuple[str | None, str, str | None]:
|
||||||
@@ -356,10 +360,10 @@ def _legacy_mail_profile_policy(
|
|||||||
if not scope_id:
|
if not scope_id:
|
||||||
return None
|
return None
|
||||||
if clean_scope == "user":
|
if clean_scope == "user":
|
||||||
legacy = _legacy_subject_policy(session, table_name="access_users", tenant_id=tenant_id, scope_id=scope_id)
|
legacy = _legacy_subject_policy(session, subject_type="user", tenant_id=tenant_id, scope_id=scope_id)
|
||||||
return _policy_from_attr(legacy) if legacy is not None else None
|
return _policy_from_attr(legacy) if legacy is not None else None
|
||||||
if clean_scope == "group":
|
if clean_scope == "group":
|
||||||
legacy = _legacy_subject_policy(session, table_name="access_groups", tenant_id=tenant_id, scope_id=scope_id)
|
legacy = _legacy_subject_policy(session, subject_type="group", tenant_id=tenant_id, scope_id=scope_id)
|
||||||
return _policy_from_attr(legacy) if legacy is not None else None
|
return _policy_from_attr(legacy) if legacy is not None else None
|
||||||
try:
|
try:
|
||||||
context = _campaign_policy_context(session, tenant_id=tenant_id, campaign_id=scope_id)
|
context = _campaign_policy_context(session, tenant_id=tenant_id, campaign_id=scope_id)
|
||||||
|
|||||||
@@ -88,10 +88,39 @@ export function wildcardPatternMatches(pattern: string, rawValue: string): boole
|
|||||||
const normalizedPattern = pattern.trim();
|
const normalizedPattern = pattern.trim();
|
||||||
const value = rawValue.trim();
|
const value = rawValue.trim();
|
||||||
if (!normalizedPattern || !value) return false;
|
if (!normalizedPattern || !value) return false;
|
||||||
if (normalizedPattern === "*") return true;
|
return wildcardMatch(normalizedPattern.toLowerCase(), value.toLowerCase());
|
||||||
const escaped = normalizedPattern.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
}
|
||||||
const regex = `^${escaped.replace(/\*/g, ".*").replace(/\?/g, ".")}$`;
|
|
||||||
return new RegExp(regex, "i").test(value);
|
function wildcardMatch(pattern: string, value: string): boolean {
|
||||||
|
let patternIndex = 0;
|
||||||
|
let valueIndex = 0;
|
||||||
|
let starIndex = -1;
|
||||||
|
let valueRetryIndex = 0;
|
||||||
|
|
||||||
|
while (valueIndex < value.length) {
|
||||||
|
const token = pattern[patternIndex];
|
||||||
|
if (token === "?" || token === value[valueIndex]) {
|
||||||
|
patternIndex += 1;
|
||||||
|
valueIndex += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (token === "*") {
|
||||||
|
starIndex = patternIndex;
|
||||||
|
valueRetryIndex = valueIndex;
|
||||||
|
patternIndex += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (starIndex !== -1) {
|
||||||
|
patternIndex = starIndex + 1;
|
||||||
|
valueRetryIndex += 1;
|
||||||
|
valueIndex = valueRetryIndex;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pattern[patternIndex] === "*") patternIndex += 1;
|
||||||
|
return patternIndex === pattern.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function patternsFor(
|
function patternsFor(
|
||||||
|
|||||||
Reference in New Issue
Block a user