Skip to content

Commit

Permalink
feat(api): add get endpoint for cached stamps (#68)
Browse files Browse the repository at this point in the history
* feat(db-cache): updating readme

* feat(api): add get endpoint for cached stamps

* fix(api): remove api key

* fix(api): remove api key from tests

* Switched json parameter type from string to Any

* fix(api): remove outdated token test

* feat(db_cache): adding admin for ceramic cache

* feat(db_cache): fixing test failures + adding code that was lost in merge

---------

Co-authored-by: nutrina <nutrina9@gmail.com>
Co-authored-by: Lucian Hymer <lucian.hymer@gmail.com>
  • Loading branch information
3 people authored Feb 3, 2023
1 parent 237c903 commit 14a4541
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 41 deletions.
18 changes: 17 additions & 1 deletion api/ceramic_cache/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
"""
Admin for the ceramic cache app
"""
from django.contrib import admin

# Register your models here.
from .models import CeramicCache


class CeramicCacheAdmin(admin.ModelAdmin):
list_display = ("id", "address", "provider", "deleted_at")
search_fields = ("address", "provider")


class AccountAPIKeyAdmin(admin.ModelAdmin):
list_display = ("id", "name", "prefix", "created", "expiry_date", "revoked")
search_fields = ("id", "name", "prefix")


admin.site.register(CeramicCache, CeramicCacheAdmin)
49 changes: 31 additions & 18 deletions api/ceramic_cache/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@

import logging
from datetime import datetime, timedelta
from typing import Dict, List, cast
from typing import Any, Dict, List

import requests
from account.views import TokenObtainPairOutSchema
from django.conf import settings
from ninja import Router, Schema
from ninja.security import APIKeyHeader
from ninja_extra import status
from ninja_extra.exceptions import APIException
from ninja_jwt.tokens import AccessToken, RefreshToken
from ninja_jwt.tokens import RefreshToken

from .exceptions import InvalidDeleteCacheRequestException
from .models import CeramicCache
Expand All @@ -25,18 +24,10 @@ def get_utc_time():
return datetime.utcnow()


class AuthAPIKey(APIKeyHeader):
param_name = "X-API-Key"

def authenticate(self, request, key):
if key == settings.CERAMIC_CACHE_API_KEY and key != "":
return key


class CacheStampPayload(Schema):
address: str
provider: str
stamp: str
stamp: Any


class DeleteStampPayload(Schema):
Expand All @@ -53,15 +44,19 @@ class DeleteStampResponse(Schema):
class CachedStampResponse(Schema):
address: str
provider: str
stamp: str
stamp: Any


class GetStampResponse(Schema):
success: bool
stamps: List[CachedStampResponse]


@router.post(
"stamp",
auth=AuthAPIKey(),
response={201: CachedStampResponse},
)
def cache_stamp(request, payload: CacheStampPayload):
def cache_stamp(_, payload: CacheStampPayload):
try:
stamp, created = CeramicCache.objects.update_or_create(
address=payload.address,
Expand All @@ -78,10 +73,9 @@ def cache_stamp(request, payload: CacheStampPayload):

@router.delete(
"stamp",
auth=AuthAPIKey(),
response=DeleteStampResponse,
)
def soft_delete_stamp(request, payload: DeleteStampPayload):
def soft_delete_stamp(_, payload: DeleteStampPayload):
try:
stamp = CeramicCache.objects.get(
address=payload.address,
Expand All @@ -99,6 +93,26 @@ def soft_delete_stamp(request, payload: DeleteStampPayload):
raise InvalidDeleteCacheRequestException()


@router.get(
"stamp",
response=GetStampResponse,
)
def get_stamps(_, address):
try:
stamps = CeramicCache.objects.filter(deleted_at=None, address=address)
return GetStampResponse(
success=True,
stamps=[
CachedStampResponse(
address=stamp.address, provider=stamp.provider, stamp=stamp.stamp
)
for stamp in stamps
],
)
except Exception as e:
raise e


class CacaoVerifySubmit(Schema):
issuer: str
signatures: List[Dict]
Expand All @@ -119,7 +133,6 @@ class DbCacheToken(RefreshToken):


class AcessTokenResponse(Schema):

access: str


Expand Down
68 changes: 68 additions & 0 deletions api/ceramic_cache/test/test_get_stamps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import pytest
from django.test import Client
from ceramic_cache.models import CeramicCache
from datetime import datetime

pytestmark = pytest.mark.django_db

client = Client()


class TestGetStamp:
def test_succesfully_get_stamp(
self, sample_provider, sample_address, verifiable_credential
):
CeramicCache.objects.create(
address=sample_address,
provider=sample_provider,
stamp=verifiable_credential,
)

response = client.get(
f"/ceramic-cache/stamp?address={sample_address}",
)

first_stamp = response.json()["stamps"][0]

assert response.status_code is 200
assert first_stamp["address"] == sample_address.lower()
assert first_stamp["provider"] == sample_provider
assert first_stamp["stamp"] == verifiable_credential

def test_get_stamp_returns_empty_list_if_no_stamps_exist(self, sample_address):
response = client.get(
f"/ceramic-cache/stamp?address={sample_address}",
)

assert response.status_code is 200
assert response.json()["stamps"] == []

def test_deleted_stamps_are_not_returned(
self, sample_address, sample_provider, verifiable_credential
):
CeramicCache.objects.create(
address=sample_address,
provider=sample_provider,
stamp=verifiable_credential,
)
CeramicCache.objects.create(
address=sample_address,
provider="Google",
stamp=verifiable_credential,
deleted_at=datetime.now(),
)

response = client.get(
f"/ceramic-cache/stamp?address={sample_address}",
)

assert response.status_code is 200
assert len(response.json()["stamps"]) is 1
assert response.json()["stamps"][0]["provider"] == sample_provider

def test_get_stamp_returns_422_if_address_is_not_provided(self):
response = client.get(
"/ceramic-cache/stamp",
)

assert response.status_code == 422
19 changes: 0 additions & 19 deletions api/ceramic_cache/test/test_submit_stamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from ceramic_cache.models import CeramicCache
from django.test import Client
from datetime import datetime
from ceramic_cache.api import get_utc_time

pytestmark = pytest.mark.django_db

Expand Down Expand Up @@ -60,24 +59,6 @@ def test_updated_stamp_is_saved_to_address_provider_record(
assert responses[1].status_code == 201
assert responses[1].json()["stamp"] == '{"stamp": 2}'

def test_bad_bearer_token_returns_401(
self, verifiable_credential, sample_provider, sample_address
):
params = {
"address": sample_address,
"provider": sample_provider,
"stamp": verifiable_credential,
}

cache_stamp_response = client.post(
"/ceramic-cache/stamp",
json.dumps(params),
content_type="application/json",
HTTP_AUTHORIZATION=f"Bearer notsecret",
)

assert cache_stamp_response.status_code == 401

def test_soft_delete_stamp(
self, mocker, sample_provider, sample_address, verifiable_credential
):
Expand Down
4 changes: 2 additions & 2 deletions api/registry/test/test_score_passport.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from unittest.mock import patch

from account.models import Account, Community
from django.conf import settings
from django.contrib.auth.models import User
from django.test import Client, TransactionTestCase
from registry.exceptions import NoPassportException
from registry.models import Passport, Score
from registry.tasks import score_passport
from web3 import Web3
from django.conf import settings

my_mnemonic = settings.TEST_MNEMONIC
web3 = Web3()
Expand Down Expand Up @@ -52,7 +52,7 @@ def setUp(self):

def test_no_passport(self):

with patch("registry.tasks.score_passport", side_effect=NoPassportException):
with patch("registry.tasks.get_passport", return_value=None):
score_passport(self.community.id, self.account.address)

passport = Passport.objects.get(
Expand Down
8 changes: 7 additions & 1 deletion verifier/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@ curl -X POST http://localhost:8001/verify \
-d @test.json
```

With curl to api:
```bash
curl -X POST http://localhost:8000/ceramic-cache/authenticate \
-H 'Content-Type: application/json' \
-d @test.json
```


```bash
curl -X POST https://api.scorer.dpopp.gitcoin.co/ceramic-cache/authenticate \
-H 'Content-Type: application/json' \
-d @test.json
```bash

0 comments on commit 14a4541

Please sign in to comment.