Skip to content

fix(files-access): flag mixed file restrictions for curation - #631

Open
zzacharo wants to merge 1 commit into
masterfrom
fix-mixed-file-restrictions
Open

zzacharo wants to merge 1 commit into
masterfrom
fix-mixed-file-restrictions

Conversation

@zzacharo

@zzacharo zzacharo commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

closes #627


if specific_file_restrictions == "restricted":
# https://cds.cern.ch/admin/webaccess/webaccessadmin.py/showroledetails?id_role=69
groups.add("cern-personnel")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be handled better for future abstraction

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you mean?

@kpsherva kpsherva Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, this we settled needs to be changed to cern-accounts-primary (to be double checked)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was a self-note :) currently in the codebase we handle the "restricted" case only for HR.... I will update it in an upcoming PR because I want to get a better look in the code.

Comment on lines +210 to +223
elif specific_file_restrictions in group_mappings:
# last resort: a simple keyword mapped to CERN e-group(s)
groups.update(group_mappings[specific_file_restrictions])
else:
raise ManualImportRequired(
message="Unexpected permission format.",
field="access",
subfield="subject.id",
stage="load",
recid=self.record.recid,
priority="critical",
value=specific_file_restrictions,
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is new code to handle restrictions based on the CDS_ACCESS_MAPPING config or fail if unknown

self.files = self.compute_files()
self.access = self.compute_access()
if self.representative_file is not None:
self.publication_date = arrow.get(

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was moved to the transform_versions file and passed down.

# statuses — can't be represented, so hard-stop for manual review.
recid = str(file["recid"])
distinct_statuses = {f["status"] for f in self.own_file_dumps}
if len(distinct_statuses) > 1:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important addition: if we have any mixed file restriction e.g public/restricted or even restrictedA/restrictedB on the same version we fail

@zubeydecivelek zubeydecivelek Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case EP records will fail, because in the normal workflow it should separate the restricted and public files in the load, and we're failing in transform, see all my ep records for LHCf are failing
Screenshot 2026-10-08 at 15 38 15

{
"message": "Record has individual file restrictions",
"value": file["status"],
"value": status,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is based now on the combined file statuses. We can handle now only one uniformed value.

@zzacharo
zzacharo force-pushed the fix-mixed-file-restrictions branch 2 times, most recently from 29bc0a1 to bdd3079 Compare October 7, 2026 14:27
@zzacharo
zzacharo marked this pull request as ready for review October 7, 2026 14:28
# public and some restricted, and/or several distinct restriction
# statuses — can't be represented, so hard-stop for manual review.
recid = str(file["recid"])
distinct_statuses = {f["status"] for f in self.own_file_dumps}

@kpsherva kpsherva Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line might be a bit unclear when reading, I think own_file_dumps might have been a bad name choice earlier during the refactoring

# firerole, bare [CERN] e-group, ...) is RecordParent.resolve_grants()'s
# job at load time; it hard-raises on anything it can't resolve. Here we
# only decide public-vs-restricted and carry the raw status as `meta`.
status = distinct_statuses.pop()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if there is no statuses? or status is empty string? how will it populate?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I will check that and add a test too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it seems that all files have the status field and is `` if there is no value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes that is the case, but I am wondering what comes out in terms of grants. I guess there will be none created and file will be public?

return {
"access_obj": {"record": record_access, "files": "restricted"},
"meta": file["status"],
"meta": status,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this pass original status from the legacy or massaged one? I am asking because we store this in the metadata at the end for clarity and it would be great if the metadata status on the file is preserved as it was in legacy

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this level, the status comes from the file_dump from legacy.

@zzacharo
zzacharo force-pushed the fix-mixed-file-restrictions branch from bdd3079 to cba9fbf Compare October 7, 2026 15:25
Comment on lines +192 to +209
elif any(
kw in specific_file_restrictions
for kw in ("firerole: allow group", "allow email")
):
meta_str = specific_file_restrictions.replace("\r\n", "\n")

# Parse groups
group_matches = re.search(r'allow group\s+((?:"[^"]+",?\s*)+)', meta_str)
if group_matches:
group_values = re.findall(r'"([^"]+)"', group_matches.group(1))
for g in group_values:
groups.add(self._normalize_group_name(g))

# Parse emails
email_matches = re.search(r'allow email\s+((?:"[^"]+",?\s*)+)', meta_str)
if email_matches:
email_values = re.findall(r'"([^"]+)"', email_matches.group(1))
emails.update(email_values)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should also raise if it doesnt match with group or email, since there is a restriction but it doesnt match

def build(self):
"""Populate ``files``/``access``/``publication_date``; return this version's dict."""
"""Populate ``files``/``access``; return this version's dict."""
self.files = self.compute_files()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also realized compute_access() only looks at each version’s new files, then copies earlier files into later versions without checking access.
So if v1 has a restricted file and v2 adds a new public file, v2 ends up with both files but marked as public

@zzacharo
zzacharo force-pushed the fix-mixed-file-restrictions branch from cba9fbf to b682c75 Compare October 8, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File-level access restrictions silently dropped when records have multiple files

3 participants