Skip to content

Feat/public share with revoke#1551

Open
mr-naveenseven wants to merge 7 commits intostagingfrom
feat/public-share-with-revoke
Open

Feat/public share with revoke#1551
mr-naveenseven wants to merge 7 commits intostagingfrom
feat/public-share-with-revoke

Conversation

@mr-naveenseven
Copy link

Changes

Added public share with revoking feature

Fixes

Tests

Tasks to complete before merging PR:

  • Ensure system tests are passing. If not Run them manually to check for any regressions 📋
  • Do any new system tests need added to test this change? do any existing system tests need updated? If so create a PR at 0chain/system_test
  • Merge your system tests PR to master AFTER merging this PR

Associated PRs (Link as appropriate):

  • 0chain:
  • gosdk:
  • system_test:
  • zboxcli:
  • zwalletcli:
  • Other: ...

- Add public share check endpoint: GET /v1/marketplace/shareinfo/public/check/{allocation}
- Add public share recipients endpoint: GET /v1/marketplace/shareinfo/public/recipients/{allocation}
- Add public share recipient removal endpoint: DELETE /v1/marketplace/shareinfo/public/recipient/{allocation}
- Add public share revoke endpoint: DELETE /v1/marketplace/shareinfo/public/{allocation}

Security & Features:
- Owner-scoped recipient queries (prevents cross-owner data access)
- Allocation ownership verification for all operations
- Support for both private and public share types
- Auth ticket validation and signature verification
- Comprehensive error handling and validation
- Rate limiting and connection management

Database Operations:
- CheckPublicShareExists: Verify public share existence
- GetPublicShareRecipients: Get all recipients (owner-scoped)
- RemovePublicShareRecipient: Remove specific recipient
- RevokePublicShare: Remove all recipients for a file

API Endpoints:
- GET /v1/marketplace/shareinfo/public/check/{allocation} - Check existence
- GET /v1/marketplace/shareinfo/public/recipients/{allocation} - List recipients
- DELETE /v1/marketplace/shareinfo/public/recipient/{allocation} - Remove recipient
- DELETE /v1/marketplace/shareinfo/public/{allocation} - Revoke share

Security Fix: Added owner_id filtering to prevent cross-owner data access
@RokibulHasan7 RokibulHasan7 force-pushed the feat/public-share-with-revoke branch 28 times, most recently from d3b1995 to 1d6f879 Compare January 2, 2026 17:35
@RokibulHasan7 RokibulHasan7 force-pushed the feat/public-share-with-revoke branch 5 times, most recently from 355f2dd to ef2bb38 Compare January 2, 2026 18:28
@RokibulHasan7 RokibulHasan7 force-pushed the feat/public-share-with-revoke branch from ef2bb38 to 8b4e77f Compare January 2, 2026 18:30
…ublic share handlers

B-C1 — DeletePublicShareInfo revokes private shares
Add `AND client_id = ''` to the WHERE clause so revoking a public share
does not also revoke private (targeted) shares on the same file path.
Public shares are identified by client_id = '', set by the owner inside
their cryptographically signed auth ticket.

B-C2 — GORM zero-value silently drops revoked = false from WHERE
GORM v2 ignores zero-value struct fields in Where(&ShareInfo{}).  Since
bool false is Go's zero value, the revoked = false predicate was omitted
from the generated SQL, causing already-revoked rows to be re-matched.
Replace struct-based WHERE conditions with explicit string predicates and
use map[string]interface{} for Updates across DeleteShareInfo,
RemovePublicShareRecipient, and DeletePublicShareInfo.

B-H1 — Ownership check ordered after file-path DB lookup
GetLimitedRefFieldsByLookupHash was called before the clientID ownership
assertion in all five share handlers, leaking whether a file path exists
to non-owners via different error messages.  Move the ownership check to
immediately after signature verification in RevokeShare, RevokePublicShare,
RemovePublicShareRecipient, CheckPublicShareExists, and GetPublicShareRecipients.

B-H2 — CheckPublicShareExists counts private shares
Missing client_id = '' filter caused the function to return true whenever
any share (public or private) existed for the path, producing false
positives for owners who had only shared a file privately.

B-H3 — GetPublicShareRecipients returns private recipients and key material
Missing client_id = '' filter allowed private recipients to appear in the
public listing.  Additionally, the implicit SELECT * returned re_encryption_key
and client_encryption_public_key — sensitive proxy re-encryption key
material — over a public-facing endpoint.  Add the client_id filter and
restrict the SELECT to non-sensitive identity and timing columns only.
…revocation

- Add share_type to ShareInfo (reference/shareinfo.go):
  - Constants ShareTypePrivate, ShareTypePublic.
  - ShareInfo.ShareType field; default "private" when empty.
  - GetShareInfoByType(ownerID, filePathHash, shareType) for type-scoped lookups.
  - GetAnyActiveShare(ownerID, filePathHash) for download/auth (any type).
  - AddShareInfo / DeleteShareInfo use share_type; DeleteShareInfo filters by owner, client, file_path_hash, share_type.
  - CheckPublicShareExists, GetPublicShareRecipients, RemovePublicShareRecipient, RevokePublicShare scoped by share_type where applicable.

- Migration (goose/migrations/1742500000_share_type.sql):
  - Add column share_type VARCHAR(16) NOT NULL DEFAULT 'private' to marketplace_share_info.
  - Indexes: (owner_id, file_path_hash, share_type), (client_id, file_path_hash, share_type).

- Handlers (handler/handler.go):
  - InsertShare: read share_type from form; upsert by (owner, client, file_path_hash, share_type).
  - RevokeShare: pass ShareTypePrivate for private revoke.
  - Public share endpoints (RevokePublicShare, RemovePublicShareRecipient, CheckPublicShareExists, GetPublicShareRecipients) use ShareTypePublic and owner scoping.

- Download/auth (authticket.go, object_operation_handler.go, storage_handler.go):
  - Use GetAnyActiveShare so either a public or private share allows access; no special client_id semantics.

Aligns blobber with 0box per-recipient model and enables revoking only public or only private when the same user has both.
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.

2 participants