Skip to content

🕵️ Add sharereview support#2711

Draft
AndyScherzinger wants to merge 1 commit into
mainfrom
feat/noid/sharereview
Draft

🕵️ Add sharereview support#2711
AndyScherzinger wants to merge 1 commit into
mainfrom
feat/noid/sharereview

Conversation

@AndyScherzinger

@AndyScherzinger AndyScherzinger commented Jun 7, 2026

Copy link
Copy Markdown
Member

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔙 Backport requests are created or not needed: /backport to stableX.X
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

🤖 AI (if applicable)

  • The content of this PR was partly or fully generated using AI

@AndyScherzinger AndyScherzinger added this to the v2.3.0 milestone Jun 7, 2026
@AndyScherzinger AndyScherzinger added enhancement New feature or request 2. developing Work in progress AI assisted labels Jun 7, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/sharereview branch from a74331b to 411e1f7 Compare June 7, 2026 13:34
@AndyScherzinger
AndyScherzinger marked this pull request as ready for review June 7, 2026 18:35
@AndyScherzinger AndyScherzinger changed the title Add sharereview support 🕵️ Add sharereview support Jun 7, 2026
@AndyScherzinger AndyScherzinger added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Jun 7, 2026
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/sharereview branch 2 times, most recently from 569f563 to b35b188 Compare June 11, 2026 15:39
Comment thread lib/ShareReview/ShareReviewSource.php Outdated
Comment thread lib/ShareReview/ShareReviewSource.php
Comment thread lib/ShareReview/ShareReviewSource.php Outdated
Comment thread lib/ShareReview/ShareReviewSource.php Outdated
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/sharereview branch 5 times, most recently from d53e2d8 to d2e8862 Compare June 15, 2026 22:08

@enjeck enjeck left a comment

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.

To be sure, it's intentional to be able to delete shares from resources that you don't own/manage? And that usually-secret public share tokens are listed too?

Comment thread lib/ShareReview/ShareReviewSource.php Outdated
Comment on lines +25 to +28
private const SHARE_TABLE = 'tables_shares';
private const TABLES_TABLE = 'tables_tables';
private const VIEWS_TABLE = 'tables_views';
private const CONTEXTS_TABLE = 'tables_contexts_context';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I do not like that database resource names leak from their actual place, which are the mappers.

Alternative: make it a public class constant in the respective mapper.

Comment thread lib/ShareReview/ShareReviewSource.php Outdated
Comment on lines +103 to +123
/** @return list<array<string, mixed>> */
private function fetchAllShares(): array {
try {
$qb = $this->db->getQueryBuilder();
$qb->select(
'id', 'sender', 'receiver', 'receiver_type', 'node_id', 'node_type',
'token', 'password',
'permission_read', 'permission_create', 'permission_update',
'permission_delete', 'permission_manage',
'created_at', 'last_edit_at'
)->from(self::SHARE_TABLE)
->orderBy('id', 'ASC');
$result = $qb->executeQuery();
$rows = $result->fetchAll();
$result->closeCursor();
return $rows;
} catch (Exception $e) {
$this->logger->error('Tables ShareReview: failed to fetch shares: {message}', ['message' => $e->getMessage()]);
return [];
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Leaks responsibility, should be provided as a method on (Service and) Mapper level.

A think to consider: can be implemented as Generator (we do it to seldomly) for a smaller memory footprint. Especially since this one reads all shares. Think of big instances. In worst case (not sure it is likely, but depends) this can ran into a memory exhaustion – but also on the callee side if really everything is consumed at once.

Comment thread lib/ShareReview/ShareReviewSource.php Outdated
Comment on lines +167 to +179
$qb = $this->db->getQueryBuilder();
$qb->select('id', $nameColumn)
->from($table)
->where($qb->expr()->in('id', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY)));
$result = $qb->executeQuery();
$rows = $result->fetchAll();
$result->closeCursor();
foreach ($rows as $row) {
$map[(int)$row['id']] = (string)$row[$nameColumn];
}
} catch (Exception $e) {
$this->logger->error('Tables ShareReview: failed to fetch names from {table}: {message}', ['table' => $table, 'message' => $e->getMessage()]);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

as mentioned, database queries should be done in the respectives mappers and exposed perhaps/ideally via Service.

Comment thread lib/ShareReview/ShareReviewSource.php Outdated

$formatted = [];
foreach ($rawShares as $share) {
$formatted[] = [

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ideally this is not a random associated array, but a specific class (can be a DTO/data containers without further logic). This is way more maintainable and also has a better memory footprint.

A factory class or callback could be provided by the ShareReview app when calling, then you have it more formalized/API-like as well.

Comment thread lib/ShareReview/ShareReviewSource.php Outdated
return $this->l10n->t('%s (View)', [$viewNames[$nodeId] ?? $this->l10n->t('View %s', [$nodeId])]);
}
if ($nodeType === self::NODE_TYPE_CONTEXT) {
return $this->l10n->t('%s (Context)', [$contextNames[$nodeId] ?? $this->l10n->t('Context %s', [$nodeId])]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Application is the user facing term, Context is only the internal-technical name.

Comment thread lib/ShareReview/ShareReviewSource.php Outdated
try {
$this->contextNavigationMapper->deleteByShareId((int)$shareId);
} catch (Exception $e) {
$this->logger->error('Tables ShareReview: failed to clean up context navigation for share {id}: {message}', ['id' => $shareId, 'message' => $e->getMessage()]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This will be more rule than exception, as we can expect this being called for Tables and Views way more often than for Contexts. One or more entries will only be against shared contexts.

Hence it would result in confusing, at worst also spammy, log messages.

@AndyScherzinger AndyScherzinger added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Jun 19, 2026
@AndyScherzinger

Copy link
Copy Markdown
Member Author

@enjeck regarding:

To be sure, it's intentional to be able to delete shares from resources that you don't own/manage? And that usually-secret public share tokens are listed too?

Yes BUT I will change the implementation in the way that it uses an event mechanism like in other places with similar calling patterns, to ensure the user would have that permission as checked then by the share review app. SO I reset the PR to draft, to reflect the need for further improvements.

@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/sharereview branch 3 times, most recently from 15ceadf to b0444a4 Compare July 2, 2026 07:11
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/sharereview branch 4 times, most recently from 77c0ec2 to ad3985f Compare July 15, 2026 20:31
…review apps via OCP\Share\ShareReview

Implement IShareReviewSource listing all tables(table/view/context) shares
with their capabilities mapped to ShareReviewPermission entries, streaming
share rows from the database via a generator to keep the memory footprint
low on large instances, gate deletions behind the
ShareReviewAccessCheckEvent authorization check with share-delete activity
entries for auditability, and register the source via
RegisterShareReviewSourceEvent.

Assisted-by: Claude Code:claude-fable-5
Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
@AndyScherzinger
AndyScherzinger force-pushed the feat/noid/sharereview branch from ad3985f to 390d769 Compare July 15, 2026 23:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2. developing Work in progress AI assisted enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants