diff --git a/acceptance/claim_test.go b/acceptance/claim_test.go index 9bc7ae1..ccf4121 100644 --- a/acceptance/claim_test.go +++ b/acceptance/claim_test.go @@ -103,6 +103,26 @@ var _ = Describe("Claim model tests", func() { sampleClaim2, )) }) + + It("should return all claims for the given source digest", func() { + sourceClaimsUrl, err := url.JoinPath(baseUrl, "/api/v1/source", uriDigest3, "claims") + Expect(err).To(BeNil()) + + resp, err := doRequest(http.MethodGet, sourceClaimsUrl, nil) + Expect(err).To(BeNil()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + var claims []api.Claim + err = json.NewDecoder(resp.Body).Decode(&claims) + Expect(err).To(BeNil()) + Expect(len(claims)).To(BeNumerically(">=", 2)) + + Expect(claims).To(ContainElements( + sampleClaim1, + sampleClaim2, + )) + }) }) When("GET request is sent to retrieve a single claim by digest", func() { diff --git a/acceptance/proof_test.go b/acceptance/proof_test.go index 86f35ac..d973ac4 100644 --- a/acceptance/proof_test.go +++ b/acceptance/proof_test.go @@ -137,6 +137,22 @@ var _ = Describe("Proof model tests", func() { Expect(p.UriDigest).To(Equal(proof1Digest)) Expect(p).To(Equal(sampleProof1)) }) + + It("should return all proofs for the given claim digest", func() { + claimProofsUrl, err := url.JoinPath(baseUrl, "/api/v1/claim", claim3Digest, "proofs") + Expect(err).To(BeNil()) + + resp, err := doRequest(http.MethodGet, claimProofsUrl, nil) + Expect(err).To(BeNil()) + defer resp.Body.Close() + Expect(resp.StatusCode).To(Equal(http.StatusOK)) + + var proofs []api.Proof + err = json.NewDecoder(resp.Body).Decode(&proofs) + Expect(err).To(BeNil()) + Expect(len(proofs)).To(BeNumerically(">=", 2)) + Expect(proofs).To(ContainElements(sampleProof1, sampleProof2)) + }) }) When("PATCH request is sent to update a proof", func() { @@ -180,7 +196,6 @@ var _ = Describe("Proof model tests", func() { Expect(err).To(BeNil()) addCommonHeaders(req) - resp, err := client.Do(req) Expect(err).To(BeNil()) defer resp.Body.Close() @@ -329,7 +344,6 @@ var _ = Describe("Proof model tests", func() { Expect(err).To(BeNil()) addCommonHeaders(req) - resp, err := client.Do(req) Expect(err).To(BeNil()) defer resp.Body.Close() diff --git a/api/source-score.yaml b/api/source-score.yaml index d1959b6..62cccff 100644 --- a/api/source-score.yaml +++ b/api/source-score.yaml @@ -137,6 +137,31 @@ paths: 404: description: Source not found + /api/v1/source/{uriDigest}/claims: + get: + summary: Get all the claims made by a source + description: Retrieves a list of all the claims made by a given source + tags: + - claims + - source + operationId: getClaimsBySourceDigest + parameters: + - in: path + name: uriDigest + required: true + description: SHA-256 hash of the source URI + schema: + type: string + responses: + 200: + description: List of claims retrieved successfully + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Claim' + /api/v1/claims: get: summary: Get all claims @@ -285,6 +310,31 @@ paths: 404: description: Claim not found + /api/v1/claim/{uriDigest}/proofs: + get: + summary: Get all the proofs provided for a claim + description: Retrieves a list of all the proofs stored for a given claim + tags: + - proofs + - claim + operationId: getProofsByClaimDigest + parameters: + - in: path + name: uriDigest + required: true + description: SHA-256 hash of the claim URI + schema: + type: string + responses: + 200: + description: List of proofs retrieved successfully + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Proof' + /api/v1/proofs: get: summary: Get all proofs diff --git a/pkg/api/server.gen.go b/pkg/api/server.gen.go index 2499732..ba4fbcd 100644 --- a/pkg/api/server.gen.go +++ b/pkg/api/server.gen.go @@ -200,6 +200,9 @@ type ServerInterface interface { // Verify a single claim // (POST /api/v1/claim/{uriDigest}) VerifyClaim(c *gin.Context, uriDigest string) + // Get all the proofs provided for a claim + // (GET /api/v1/claim/{uriDigest}/proofs) + GetProofsByClaimDigest(c *gin.Context, uriDigest string) // Get all claims // (GET /api/v1/claims) GetClaims(c *gin.Context) @@ -233,6 +236,9 @@ type ServerInterface interface { // Update source fields // (PATCH /api/v1/source/{uriDigest}) PatchSource(c *gin.Context, uriDigest string) + // Get all the claims made by a source + // (GET /api/v1/source/{uriDigest}/claims) + GetClaimsBySourceDigest(c *gin.Context, uriDigest string) // Get all sources // (GET /api/v1/sources) GetSources(c *gin.Context) @@ -369,6 +375,32 @@ func (siw *ServerInterfaceWrapper) VerifyClaim(c *gin.Context) { siw.Handler.VerifyClaim(c, uriDigest) } +// GetProofsByClaimDigest operation middleware +func (siw *ServerInterfaceWrapper) GetProofsByClaimDigest(c *gin.Context) { + + var err error + + // ------------- Path parameter "uriDigest" ------------- + var uriDigest string + + err = runtime.BindStyledParameterWithOptions("simple", "uriDigest", c.Param("uriDigest"), &uriDigest, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter uriDigest: %w", err), http.StatusBadRequest) + return + } + + c.Set(ApiKeyAuthScopes, []string{}) + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetProofsByClaimDigest(c, uriDigest) +} + // GetClaims operation middleware func (siw *ServerInterfaceWrapper) GetClaims(c *gin.Context) { @@ -600,6 +632,32 @@ func (siw *ServerInterfaceWrapper) PatchSource(c *gin.Context) { siw.Handler.PatchSource(c, uriDigest) } +// GetClaimsBySourceDigest operation middleware +func (siw *ServerInterfaceWrapper) GetClaimsBySourceDigest(c *gin.Context) { + + var err error + + // ------------- Path parameter "uriDigest" ------------- + var uriDigest string + + err = runtime.BindStyledParameterWithOptions("simple", "uriDigest", c.Param("uriDigest"), &uriDigest, runtime.BindStyledParameterOptions{Explode: false, Required: true}) + if err != nil { + siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter uriDigest: %w", err), http.StatusBadRequest) + return + } + + c.Set(ApiKeyAuthScopes, []string{}) + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + if c.IsAborted() { + return + } + } + + siw.Handler.GetClaimsBySourceDigest(c, uriDigest) +} + // GetSources operation middleware func (siw *ServerInterfaceWrapper) GetSources(c *gin.Context) { @@ -662,6 +720,7 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options router.GET(options.BaseURL+"/api/v1/claim/:uriDigest", wrapper.GetClaim) router.PATCH(options.BaseURL+"/api/v1/claim/:uriDigest", wrapper.PatchClaim) router.POST(options.BaseURL+"/api/v1/claim/:uriDigest", wrapper.VerifyClaim) + router.GET(options.BaseURL+"/api/v1/claim/:uriDigest/proofs", wrapper.GetProofsByClaimDigest) router.GET(options.BaseURL+"/api/v1/claims", wrapper.GetClaims) router.POST(options.BaseURL+"/api/v1/claims/verify", wrapper.VerifyAllClaims) router.POST(options.BaseURL+"/api/v1/proof", wrapper.PostProof) @@ -673,6 +732,7 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options router.DELETE(options.BaseURL+"/api/v1/source/:uriDigest", wrapper.DeleteSource) router.GET(options.BaseURL+"/api/v1/source/:uriDigest", wrapper.GetSource) router.PATCH(options.BaseURL+"/api/v1/source/:uriDigest", wrapper.PatchSource) + router.GET(options.BaseURL+"/api/v1/source/:uriDigest/claims", wrapper.GetClaimsBySourceDigest) router.GET(options.BaseURL+"/api/v1/sources", wrapper.GetSources) router.POST(options.BaseURL+"/api/v1/sources/scores", wrapper.UpdateAllScores) } diff --git a/pkg/domain/claim/claim_repository.go b/pkg/domain/claim/claim_repository.go index 442507a..d36967d 100644 --- a/pkg/domain/claim/claim_repository.go +++ b/pkg/domain/claim/claim_repository.go @@ -22,6 +22,7 @@ type ClaimRepository interface { VerifyClaimByUriDigest(ctx context.Context, claimVerification *api.ClaimVerification, uriDigest string) error VerifyAllClaims(ctx context.Context, updatedClaims []api.Claim) error GetCheckedClaimsBySources(ctx context.Context) (map[string][]api.Claim, error) + GetClaimsBySourceDigest(ctx context.Context, sourceDigest string) ([]api.Claim, error) } type claimRepository struct { @@ -179,3 +180,15 @@ func (cr *claimRepository) GetCheckedClaimsBySources(ctx context.Context) (map[s return srcsClaims, nil } + +func (cr *claimRepository) GetClaimsBySourceDigest(ctx context.Context, sourceDigest string) ([]api.Claim, error) { + var claims []api.Claim + result := cr.client.DB.WithContext(ctx).Where("source_uri_digest = ?", sourceDigest).Find(&claims) + + if result.Error != nil { + return nil, result.Error + } + slog.InfoContext(ctx, fmt.Sprintf("returned %d claims", len(claims))) + + return claims, nil +} diff --git a/pkg/domain/claim/claim_repository_test.go b/pkg/domain/claim/claim_repository_test.go index 9980c1f..d459f25 100644 --- a/pkg/domain/claim/claim_repository_test.go +++ b/pkg/domain/claim/claim_repository_test.go @@ -64,6 +64,19 @@ var _ = Describe("Claim repository layer unit tests", func() { }) }) + When("Retrieving claims by source uri digest", func() { + It("Should return all claims associated with the source digest", func() { + claims, err := claimRepo.GetClaimsBySourceDigest(context.TODO(), sampleSource.UriDigest) + Expect(err).ToNot(HaveOccurred()) + Expect(len(claims)).To(Equal(2)) + + Expect(claims).To(ContainElements( + sampleClaim1, + sampleClaim2, + )) + }) + }) + When("Patching a claim by its uri digest", func() { It("Should update the correct claim record in the DB", func() { newSummary := "Updated claim summary" diff --git a/pkg/domain/claim/claim_service.go b/pkg/domain/claim/claim_service.go index 1e1f77d..09b4b36 100644 --- a/pkg/domain/claim/claim_service.go +++ b/pkg/domain/claim/claim_service.go @@ -24,6 +24,7 @@ type ClaimService interface { PatchClaimByUriDigest(ctx context.Context, claimInput *api.ClaimPatchInput, uriDigest string) error VerifyClaimByUriDigest(ctx context.Context, claimVerification *api.ClaimVerification, uriDigest string) error VerifyAllClaims(ctx context.Context) error + GetClaimsBySourceDigest(ctx context.Context, sourceDigest string) ([]api.Claim, error) } type claimService struct { @@ -187,3 +188,7 @@ func (svc *claimService) VerifyAllClaims(ctx context.Context) error { return nil } + +func (svc *claimService) GetClaimsBySourceDigest(ctx context.Context, digest string) ([]api.Claim, error) { + return svc.claimRepo.GetClaimsBySourceDigest(ctx, digest) +} diff --git a/pkg/domain/claim/claim_service_test.go b/pkg/domain/claim/claim_service_test.go index adbd589..ce7c1f1 100644 --- a/pkg/domain/claim/claim_service_test.go +++ b/pkg/domain/claim/claim_service_test.go @@ -86,6 +86,21 @@ var _ = Describe("Claim model service layer unit tests", Ordered, func() { }) }) + When("Retrieving claims by source uri digest", func() { + It("Should return all claims associated with the source digest", func() { + expected := []api.Claim{sampleClaim1, sampleClaim2} + fakeClaimRepo.GetClaimsBySourceDigestReturnsOnCall(0, expected, nil) + + claims, err := claimSvc.GetClaimsBySourceDigest(context.TODO(), sampleSource.UriDigest) + Expect(err).ToNot(HaveOccurred()) + Expect(len(claims)).To(Equal(2)) + Expect(claims).To(ContainElements(expected)) + Expect(fakeClaimRepo.GetClaimsBySourceDigestCallCount()).To(Equal(1)) + _, arg := fakeClaimRepo.GetClaimsBySourceDigestArgsForCall(0) + Expect(arg).To(Equal(sampleSource.UriDigest)) + }) + }) + When("Deleting a claim by its uri digest", func() { It("Should delete the correct claim record via repository", func() { fakeClaimRepo.GetClaimByUriDigestReturnsOnCall(1, &sampleClaim1, nil) diff --git a/pkg/domain/claim/claimfakes/fake_claim_repository.go b/pkg/domain/claim/claimfakes/fake_claim_repository.go index 390b5df..b6303c1 100644 --- a/pkg/domain/claim/claimfakes/fake_claim_repository.go +++ b/pkg/domain/claim/claimfakes/fake_claim_repository.go @@ -61,6 +61,20 @@ type FakeClaimRepository struct { result1 []api.Claim result2 error } + GetClaimsBySourceDigestStub func(context.Context, string) ([]api.Claim, error) + getClaimsBySourceDigestMutex sync.RWMutex + getClaimsBySourceDigestArgsForCall []struct { + arg1 context.Context + arg2 string + } + getClaimsBySourceDigestReturns struct { + result1 []api.Claim + result2 error + } + getClaimsBySourceDigestReturnsOnCall map[int]struct { + result1 []api.Claim + result2 error + } PatchClaimByUriDigestStub func(context.Context, *api.ClaimPatchInput, string) error patchClaimByUriDigestMutex sync.RWMutex patchClaimByUriDigestArgsForCall []struct { @@ -372,6 +386,71 @@ func (fake *FakeClaimRepository) GetClaimsReturnsOnCall(i int, result1 []api.Cla }{result1, result2} } +func (fake *FakeClaimRepository) GetClaimsBySourceDigest(arg1 context.Context, arg2 string) ([]api.Claim, error) { + fake.getClaimsBySourceDigestMutex.Lock() + ret, specificReturn := fake.getClaimsBySourceDigestReturnsOnCall[len(fake.getClaimsBySourceDigestArgsForCall)] + fake.getClaimsBySourceDigestArgsForCall = append(fake.getClaimsBySourceDigestArgsForCall, struct { + arg1 context.Context + arg2 string + }{arg1, arg2}) + stub := fake.GetClaimsBySourceDigestStub + fakeReturns := fake.getClaimsBySourceDigestReturns + fake.recordInvocation("GetClaimsBySourceDigest", []interface{}{arg1, arg2}) + fake.getClaimsBySourceDigestMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeClaimRepository) GetClaimsBySourceDigestCallCount() int { + fake.getClaimsBySourceDigestMutex.RLock() + defer fake.getClaimsBySourceDigestMutex.RUnlock() + return len(fake.getClaimsBySourceDigestArgsForCall) +} + +func (fake *FakeClaimRepository) GetClaimsBySourceDigestCalls(stub func(context.Context, string) ([]api.Claim, error)) { + fake.getClaimsBySourceDigestMutex.Lock() + defer fake.getClaimsBySourceDigestMutex.Unlock() + fake.GetClaimsBySourceDigestStub = stub +} + +func (fake *FakeClaimRepository) GetClaimsBySourceDigestArgsForCall(i int) (context.Context, string) { + fake.getClaimsBySourceDigestMutex.RLock() + defer fake.getClaimsBySourceDigestMutex.RUnlock() + argsForCall := fake.getClaimsBySourceDigestArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeClaimRepository) GetClaimsBySourceDigestReturns(result1 []api.Claim, result2 error) { + fake.getClaimsBySourceDigestMutex.Lock() + defer fake.getClaimsBySourceDigestMutex.Unlock() + fake.GetClaimsBySourceDigestStub = nil + fake.getClaimsBySourceDigestReturns = struct { + result1 []api.Claim + result2 error + }{result1, result2} +} + +func (fake *FakeClaimRepository) GetClaimsBySourceDigestReturnsOnCall(i int, result1 []api.Claim, result2 error) { + fake.getClaimsBySourceDigestMutex.Lock() + defer fake.getClaimsBySourceDigestMutex.Unlock() + fake.GetClaimsBySourceDigestStub = nil + if fake.getClaimsBySourceDigestReturnsOnCall == nil { + fake.getClaimsBySourceDigestReturnsOnCall = make(map[int]struct { + result1 []api.Claim + result2 error + }) + } + fake.getClaimsBySourceDigestReturnsOnCall[i] = struct { + result1 []api.Claim + result2 error + }{result1, result2} +} + func (fake *FakeClaimRepository) PatchClaimByUriDigest(arg1 context.Context, arg2 *api.ClaimPatchInput, arg3 string) error { fake.patchClaimByUriDigestMutex.Lock() ret, specificReturn := fake.patchClaimByUriDigestReturnsOnCall[len(fake.patchClaimByUriDigestArgsForCall)] diff --git a/pkg/domain/claim/claimfakes/fake_claim_service.go b/pkg/domain/claim/claimfakes/fake_claim_service.go index df6e61e..07d3158 100644 --- a/pkg/domain/claim/claimfakes/fake_claim_service.go +++ b/pkg/domain/claim/claimfakes/fake_claim_service.go @@ -48,6 +48,20 @@ type FakeClaimService struct { result1 []api.Claim result2 error } + GetClaimsBySourceDigestStub func(context.Context, string) ([]api.Claim, error) + getClaimsBySourceDigestMutex sync.RWMutex + getClaimsBySourceDigestArgsForCall []struct { + arg1 context.Context + arg2 string + } + getClaimsBySourceDigestReturns struct { + result1 []api.Claim + result2 error + } + getClaimsBySourceDigestReturnsOnCall map[int]struct { + result1 []api.Claim + result2 error + } PatchClaimByUriDigestStub func(context.Context, *api.ClaimPatchInput, string) error patchClaimByUriDigestMutex sync.RWMutex patchClaimByUriDigestArgsForCall []struct { @@ -294,6 +308,71 @@ func (fake *FakeClaimService) GetClaimsReturnsOnCall(i int, result1 []api.Claim, }{result1, result2} } +func (fake *FakeClaimService) GetClaimsBySourceDigest(arg1 context.Context, arg2 string) ([]api.Claim, error) { + fake.getClaimsBySourceDigestMutex.Lock() + ret, specificReturn := fake.getClaimsBySourceDigestReturnsOnCall[len(fake.getClaimsBySourceDigestArgsForCall)] + fake.getClaimsBySourceDigestArgsForCall = append(fake.getClaimsBySourceDigestArgsForCall, struct { + arg1 context.Context + arg2 string + }{arg1, arg2}) + stub := fake.GetClaimsBySourceDigestStub + fakeReturns := fake.getClaimsBySourceDigestReturns + fake.recordInvocation("GetClaimsBySourceDigest", []interface{}{arg1, arg2}) + fake.getClaimsBySourceDigestMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeClaimService) GetClaimsBySourceDigestCallCount() int { + fake.getClaimsBySourceDigestMutex.RLock() + defer fake.getClaimsBySourceDigestMutex.RUnlock() + return len(fake.getClaimsBySourceDigestArgsForCall) +} + +func (fake *FakeClaimService) GetClaimsBySourceDigestCalls(stub func(context.Context, string) ([]api.Claim, error)) { + fake.getClaimsBySourceDigestMutex.Lock() + defer fake.getClaimsBySourceDigestMutex.Unlock() + fake.GetClaimsBySourceDigestStub = stub +} + +func (fake *FakeClaimService) GetClaimsBySourceDigestArgsForCall(i int) (context.Context, string) { + fake.getClaimsBySourceDigestMutex.RLock() + defer fake.getClaimsBySourceDigestMutex.RUnlock() + argsForCall := fake.getClaimsBySourceDigestArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeClaimService) GetClaimsBySourceDigestReturns(result1 []api.Claim, result2 error) { + fake.getClaimsBySourceDigestMutex.Lock() + defer fake.getClaimsBySourceDigestMutex.Unlock() + fake.GetClaimsBySourceDigestStub = nil + fake.getClaimsBySourceDigestReturns = struct { + result1 []api.Claim + result2 error + }{result1, result2} +} + +func (fake *FakeClaimService) GetClaimsBySourceDigestReturnsOnCall(i int, result1 []api.Claim, result2 error) { + fake.getClaimsBySourceDigestMutex.Lock() + defer fake.getClaimsBySourceDigestMutex.Unlock() + fake.GetClaimsBySourceDigestStub = nil + if fake.getClaimsBySourceDigestReturnsOnCall == nil { + fake.getClaimsBySourceDigestReturnsOnCall = make(map[int]struct { + result1 []api.Claim + result2 error + }) + } + fake.getClaimsBySourceDigestReturnsOnCall[i] = struct { + result1 []api.Claim + result2 error + }{result1, result2} +} + func (fake *FakeClaimService) PatchClaimByUriDigest(arg1 context.Context, arg2 *api.ClaimPatchInput, arg3 string) error { fake.patchClaimByUriDigestMutex.Lock() ret, specificReturn := fake.patchClaimByUriDigestReturnsOnCall[len(fake.patchClaimByUriDigestArgsForCall)] diff --git a/pkg/domain/proof/proof_repository.go b/pkg/domain/proof/proof_repository.go index a8f884d..7eca23e 100644 --- a/pkg/domain/proof/proof_repository.go +++ b/pkg/domain/proof/proof_repository.go @@ -18,6 +18,7 @@ type ProofRepository interface { GetProofByUriDigest(ctx context.Context, uriDigest string) (*api.Proof, error) DeleteProofByUriDigest(ctx context.Context, proof *api.Proof) error PatchProofByUriDigest(ctx context.Context, proofInput *api.ProofPatchInput, uriDigest string) error + GetProofsByClaimDigest(ctx context.Context, digest string) ([]api.Proof, error) } type proofRepository struct { @@ -107,3 +108,16 @@ func (pr *proofRepository) PatchProofByUriDigest(ctx context.Context, proofInput return result.Error } + +func (pr *proofRepository) GetProofsByClaimDigest(ctx context.Context, digest string) ([]api.Proof, error) { + var proofs []api.Proof + result := pr.client.DB.WithContext(ctx).Where("claim_uri_digest = ?", digest).Find(&proofs) + + if result.Error != nil { + return nil, result.Error + } + + slog.InfoContext(ctx, fmt.Sprintf("returned %d proofs", len(proofs))) + + return proofs, nil +} diff --git a/pkg/domain/proof/proof_repository_test.go b/pkg/domain/proof/proof_repository_test.go index e02b725..334a42b 100644 --- a/pkg/domain/proof/proof_repository_test.go +++ b/pkg/domain/proof/proof_repository_test.go @@ -53,6 +53,19 @@ var _ = Describe("Proof repository layer unit tests", Ordered, func() { }) }) + When("Retrieving proofs by claim uri digest", func() { + It("Should return all proofs associated with the claim digest", func() { + proofs, err := proofRepo.GetProofsByClaimDigest(context.TODO(), claimDigest) + Expect(err).ToNot(HaveOccurred()) + Expect(len(proofs)).To(Equal(2)) + + Expect(proofs).To(ContainElements( + sampleProof1, + sampleProof2, + )) + }) + }) + When("Retrieving a single proof by uri digest", func() { It("Should return the matching proof record", func() { p, err := proofRepo.GetProofByUriDigest(context.TODO(), proof1Digest) diff --git a/pkg/domain/proof/proof_service.go b/pkg/domain/proof/proof_service.go index 25260d6..8397aec 100644 --- a/pkg/domain/proof/proof_service.go +++ b/pkg/domain/proof/proof_service.go @@ -21,6 +21,7 @@ type ProofService interface { DeleteProofByUriDigest(ctx context.Context, uriDigest string) error PatchProofByUriDigest(ctx context.Context, proofInput *api.ProofPatchInput, uriDigest string) error GetProofsByClaims(ctx context.Context) (map[string][]api.Proof, error) + GetProofsByClaimDigest(ctx context.Context, digest string) ([]api.Proof, error) } type proofService struct { @@ -125,3 +126,7 @@ func (svc *proofService) GetProofsByClaims(ctx context.Context) (map[string][]ap return claimsProofs, nil } + +func (svc *proofService) GetProofsByClaimDigest(ctx context.Context, digest string) ([]api.Proof, error) { + return svc.proofRepo.GetProofsByClaimDigest(ctx, digest) +} diff --git a/pkg/domain/proof/proof_service_test.go b/pkg/domain/proof/proof_service_test.go index 7dea11a..96ff858 100644 --- a/pkg/domain/proof/proof_service_test.go +++ b/pkg/domain/proof/proof_service_test.go @@ -146,6 +146,21 @@ var _ = Describe("Proof model service layer unit tests", Ordered, func() { Expect(proofs2[0]).To(Equal(proof3)) }) }) + + When("Retrieving proofs by claim uri digest", func() { + It("Should return the matching proofs from repository", func() { + expected := []api.Proof{sampleProof1, sampleProof2} + fakeProofRepo.GetProofsByClaimDigestReturnsOnCall(0, expected, nil) + + proofs, err := proofSvc.GetProofsByClaimDigest(context.TODO(), claimDigest) + Expect(err).ToNot(HaveOccurred()) + Expect(len(proofs)).To(Equal(2)) + Expect(proofs).To(ContainElements(expected)) + Expect(fakeProofRepo.GetProofsByClaimDigestCallCount()).To(Equal(1)) + _, arg := fakeProofRepo.GetProofsByClaimDigestArgsForCall(0) + Expect(arg).To(Equal(claimDigest)) + }) + }) }) Context("Proof POST validation tests", func() { diff --git a/pkg/domain/proof/prooffakes/fake_proof_repository.go b/pkg/domain/proof/prooffakes/fake_proof_repository.go index 897040c..482e440 100644 --- a/pkg/domain/proof/prooffakes/fake_proof_repository.go +++ b/pkg/domain/proof/prooffakes/fake_proof_repository.go @@ -48,6 +48,20 @@ type FakeProofRepository struct { result1 []api.Proof result2 error } + GetProofsByClaimDigestStub func(context.Context, string) ([]api.Proof, error) + getProofsByClaimDigestMutex sync.RWMutex + getProofsByClaimDigestArgsForCall []struct { + arg1 context.Context + arg2 string + } + getProofsByClaimDigestReturns struct { + result1 []api.Proof + result2 error + } + getProofsByClaimDigestReturnsOnCall map[int]struct { + result1 []api.Proof + result2 error + } PatchProofByUriDigestStub func(context.Context, *api.ProofPatchInput, string) error patchProofByUriDigestMutex sync.RWMutex patchProofByUriDigestArgsForCall []struct { @@ -270,6 +284,71 @@ func (fake *FakeProofRepository) GetProofsReturnsOnCall(i int, result1 []api.Pro }{result1, result2} } +func (fake *FakeProofRepository) GetProofsByClaimDigest(arg1 context.Context, arg2 string) ([]api.Proof, error) { + fake.getProofsByClaimDigestMutex.Lock() + ret, specificReturn := fake.getProofsByClaimDigestReturnsOnCall[len(fake.getProofsByClaimDigestArgsForCall)] + fake.getProofsByClaimDigestArgsForCall = append(fake.getProofsByClaimDigestArgsForCall, struct { + arg1 context.Context + arg2 string + }{arg1, arg2}) + stub := fake.GetProofsByClaimDigestStub + fakeReturns := fake.getProofsByClaimDigestReturns + fake.recordInvocation("GetProofsByClaimDigest", []interface{}{arg1, arg2}) + fake.getProofsByClaimDigestMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeProofRepository) GetProofsByClaimDigestCallCount() int { + fake.getProofsByClaimDigestMutex.RLock() + defer fake.getProofsByClaimDigestMutex.RUnlock() + return len(fake.getProofsByClaimDigestArgsForCall) +} + +func (fake *FakeProofRepository) GetProofsByClaimDigestCalls(stub func(context.Context, string) ([]api.Proof, error)) { + fake.getProofsByClaimDigestMutex.Lock() + defer fake.getProofsByClaimDigestMutex.Unlock() + fake.GetProofsByClaimDigestStub = stub +} + +func (fake *FakeProofRepository) GetProofsByClaimDigestArgsForCall(i int) (context.Context, string) { + fake.getProofsByClaimDigestMutex.RLock() + defer fake.getProofsByClaimDigestMutex.RUnlock() + argsForCall := fake.getProofsByClaimDigestArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeProofRepository) GetProofsByClaimDigestReturns(result1 []api.Proof, result2 error) { + fake.getProofsByClaimDigestMutex.Lock() + defer fake.getProofsByClaimDigestMutex.Unlock() + fake.GetProofsByClaimDigestStub = nil + fake.getProofsByClaimDigestReturns = struct { + result1 []api.Proof + result2 error + }{result1, result2} +} + +func (fake *FakeProofRepository) GetProofsByClaimDigestReturnsOnCall(i int, result1 []api.Proof, result2 error) { + fake.getProofsByClaimDigestMutex.Lock() + defer fake.getProofsByClaimDigestMutex.Unlock() + fake.GetProofsByClaimDigestStub = nil + if fake.getProofsByClaimDigestReturnsOnCall == nil { + fake.getProofsByClaimDigestReturnsOnCall = make(map[int]struct { + result1 []api.Proof + result2 error + }) + } + fake.getProofsByClaimDigestReturnsOnCall[i] = struct { + result1 []api.Proof + result2 error + }{result1, result2} +} + func (fake *FakeProofRepository) PatchProofByUriDigest(arg1 context.Context, arg2 *api.ProofPatchInput, arg3 string) error { fake.patchProofByUriDigestMutex.Lock() ret, specificReturn := fake.patchProofByUriDigestReturnsOnCall[len(fake.patchProofByUriDigestArgsForCall)] diff --git a/pkg/domain/proof/prooffakes/fake_proof_service.go b/pkg/domain/proof/prooffakes/fake_proof_service.go index 54598bb..4ab18fd 100644 --- a/pkg/domain/proof/prooffakes/fake_proof_service.go +++ b/pkg/domain/proof/prooffakes/fake_proof_service.go @@ -48,6 +48,20 @@ type FakeProofService struct { result1 []api.Proof result2 error } + GetProofsByClaimDigestStub func(context.Context, string) ([]api.Proof, error) + getProofsByClaimDigestMutex sync.RWMutex + getProofsByClaimDigestArgsForCall []struct { + arg1 context.Context + arg2 string + } + getProofsByClaimDigestReturns struct { + result1 []api.Proof + result2 error + } + getProofsByClaimDigestReturnsOnCall map[int]struct { + result1 []api.Proof + result2 error + } GetProofsByClaimsStub func(context.Context) (map[string][]api.Proof, error) getProofsByClaimsMutex sync.RWMutex getProofsByClaimsArgsForCall []struct { @@ -283,6 +297,71 @@ func (fake *FakeProofService) GetProofsReturnsOnCall(i int, result1 []api.Proof, }{result1, result2} } +func (fake *FakeProofService) GetProofsByClaimDigest(arg1 context.Context, arg2 string) ([]api.Proof, error) { + fake.getProofsByClaimDigestMutex.Lock() + ret, specificReturn := fake.getProofsByClaimDigestReturnsOnCall[len(fake.getProofsByClaimDigestArgsForCall)] + fake.getProofsByClaimDigestArgsForCall = append(fake.getProofsByClaimDigestArgsForCall, struct { + arg1 context.Context + arg2 string + }{arg1, arg2}) + stub := fake.GetProofsByClaimDigestStub + fakeReturns := fake.getProofsByClaimDigestReturns + fake.recordInvocation("GetProofsByClaimDigest", []interface{}{arg1, arg2}) + fake.getProofsByClaimDigestMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeProofService) GetProofsByClaimDigestCallCount() int { + fake.getProofsByClaimDigestMutex.RLock() + defer fake.getProofsByClaimDigestMutex.RUnlock() + return len(fake.getProofsByClaimDigestArgsForCall) +} + +func (fake *FakeProofService) GetProofsByClaimDigestCalls(stub func(context.Context, string) ([]api.Proof, error)) { + fake.getProofsByClaimDigestMutex.Lock() + defer fake.getProofsByClaimDigestMutex.Unlock() + fake.GetProofsByClaimDigestStub = stub +} + +func (fake *FakeProofService) GetProofsByClaimDigestArgsForCall(i int) (context.Context, string) { + fake.getProofsByClaimDigestMutex.RLock() + defer fake.getProofsByClaimDigestMutex.RUnlock() + argsForCall := fake.getProofsByClaimDigestArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeProofService) GetProofsByClaimDigestReturns(result1 []api.Proof, result2 error) { + fake.getProofsByClaimDigestMutex.Lock() + defer fake.getProofsByClaimDigestMutex.Unlock() + fake.GetProofsByClaimDigestStub = nil + fake.getProofsByClaimDigestReturns = struct { + result1 []api.Proof + result2 error + }{result1, result2} +} + +func (fake *FakeProofService) GetProofsByClaimDigestReturnsOnCall(i int, result1 []api.Proof, result2 error) { + fake.getProofsByClaimDigestMutex.Lock() + defer fake.getProofsByClaimDigestMutex.Unlock() + fake.GetProofsByClaimDigestStub = nil + if fake.getProofsByClaimDigestReturnsOnCall == nil { + fake.getProofsByClaimDigestReturnsOnCall = make(map[int]struct { + result1 []api.Proof + result2 error + }) + } + fake.getProofsByClaimDigestReturnsOnCall[i] = struct { + result1 []api.Proof + result2 error + }{result1, result2} +} + func (fake *FakeProofService) GetProofsByClaims(arg1 context.Context) (map[string][]api.Proof, error) { fake.getProofsByClaimsMutex.Lock() ret, specificReturn := fake.getProofsByClaimsReturnsOnCall[len(fake.getProofsByClaimsArgsForCall)] diff --git a/pkg/handlers/claim.go b/pkg/handlers/claim.go index 1c6fd6d..0d3115f 100644 --- a/pkg/handlers/claim.go +++ b/pkg/handlers/claim.go @@ -206,3 +206,20 @@ func (ch *ClaimHandler) VerifyAllClaims(ctx *gin.Context) { ctx.Status(http.StatusConflict) } + +func (ch *ClaimHandler) GetClaimsBySourceDigest(ctx *gin.Context, sourceDigest string) { + claims, err := ch.claimSvc.GetClaimsBySourceDigest(ctx, sourceDigest) + if err != nil { + slog.Error("failed to get claims by source digest", "error", err, "sourceDigest", sourceDigest) + ctx.JSON( + http.StatusInternalServerError, + gin.H{"error": "internal server error"}, + ) + return + } + + ctx.JSON( + http.StatusOK, + claims, + ) +} diff --git a/pkg/handlers/proof.go b/pkg/handlers/proof.go index fd87720..32769ad 100644 --- a/pkg/handlers/proof.go +++ b/pkg/handlers/proof.go @@ -109,3 +109,14 @@ func (ph *ProofHandler) PatchProofByUriDigest(ctx *gin.Context, uriDigest string ctx.Status(http.StatusNoContent) } + +func (ph *ProofHandler) GetProofsByClaimDigest(ctx *gin.Context, claimDigest string) { + proofs, err := ph.proofSvc.GetProofsByClaimDigest(ctx, claimDigest) + if err != nil { + slog.Error("failed to get proofs by claim digest", "error", err, "claimDigest", claimDigest) + ctx.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"}) + return + } + + ctx.JSON(http.StatusOK, proofs) +} diff --git a/pkg/http/router.go b/pkg/http/router.go index 7d64512..02c9ccb 100644 --- a/pkg/http/router.go +++ b/pkg/http/router.go @@ -103,3 +103,11 @@ func (r *router) PatchProof(ctx *gin.Context, uriDigest string) { func (r *router) UpdateAllScores(ctx *gin.Context) { r.srcHandler.UpdateAllScores(ctx) } + +func (r *router) GetClaimsBySourceDigest(ctx *gin.Context, sourceDigest string) { + r.claimHandler.GetClaimsBySourceDigest(ctx, sourceDigest) +} + +func (r *router) GetProofsByClaimDigest(ctx *gin.Context, claimDigest string) { + r.proofHandler.GetProofsByClaimDigest(ctx, claimDigest) +}