Skip to content

Commit

Permalink
feat(api): adding custom stamp framework (#673)
Browse files Browse the repository at this point in the history
* feat(api): adding custom stamp framework

* feat(api): added custom stamps api, refined models

* fixes

* updated help text

* fix: error related to using model reference in async context

* fixing migration merge

* fix: decoding credential name in URL

---------

Co-authored-by: Gerald Iakobinyi-Pich <gerald@gitcoin.co>
  • Loading branch information
lucianHymer and Gerald Iakobinyi-Pich authored Sep 17, 2024
1 parent 431f541 commit 310d718
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 29 deletions.
33 changes: 29 additions & 4 deletions api/account/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
AddressListMember,
AllowList,
Community,
CustomGithubStamp,
CustomCredential,
CustomCredentialRuleset,
Customization,
CustomPlatform,
IncludedChainId,
)

Expand Down Expand Up @@ -220,16 +222,20 @@ class IncludedChainIdInline(admin.TabularInline):
extra = 0


class CustomGithubStampInline(admin.TabularInline):
model = CustomGithubStamp
class CustomCredentialInline(admin.TabularInline):
model = CustomCredential
extra = 0


@admin.register(Customization)
class CustomizationAdmin(ScorerModelAdmin):
form = CustomizationForm
raw_id_fields = ["scorer"]
inlines = [AllowListInline, CustomGithubStampInline, IncludedChainIdInline]
inlines = [
AllowListInline,
CustomCredentialInline,
IncludedChainIdInline,
]
fieldsets = [
(
None,
Expand Down Expand Up @@ -359,3 +365,22 @@ def import_csv(self, request):
form = AddressListCsvImportForm()
payload = {"form": form}
return render(request, "account/address_list_csv_import_form.html", payload)


@admin.register(CustomPlatform)
class CustomPlatformAdmin(admin.ModelAdmin):
list_display = ["name", "display_name", "description"]
search_display = ["name", "display_name", "description"]


@admin.register(CustomCredentialRuleset)
class CustomCredentialRulesetAdmin(admin.ModelAdmin):
list_display = ["name", "provider_id", "credential_type"]
search_fields = ["name", "provider_id", "credential_type"]

def get_readonly_fields(self, request, obj=None):
# This makes name read-only after creation, but editable during creation
if obj:
return ["credential_type", "definition", "provider_id", "name"]
else:
return ["provider_id", "name"]
12 changes: 12 additions & 0 deletions api/account/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
AddressList,
AddressListMember,
Community,
CustomCredentialRuleset,
Customization,
Nonce,
)
Expand Down Expand Up @@ -596,6 +597,16 @@ def update_community_scorers(request, community_id, payload: ScorerId):
return {"ok": True}


@api.get("/customization/credential/{provider_id}", auth=None)
def get_credential_definition(request, provider_id: str):
decoded_provider_id = provider_id.replace("%23", "#")
return {
"ruleset": get_object_or_404(
CustomCredentialRuleset, provider_id=decoded_provider_id
).definition
}


@api.get("/customization/{dashboard_path}/", auth=None)
def get_account_customization(request, dashboard_path: str):
try:
Expand Down Expand Up @@ -657,6 +668,7 @@ def get_account_customization(request, dashboard_path: str):
},
includedChainIds=included_chain_ids,
showExplanationPanel=customization.show_explanation_panel,
customStamps=customization.get_custom_stamps(),
)

except Customization.DoesNotExist:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Generated by Django 4.2.6 on 2024-09-11 22:11

import django.db.models.deletion
from django.db import migrations, models

import account.models


class Migration(migrations.Migration):
dependencies = [
("account", "0034_customgithubstamp"),
]

operations = [
migrations.CreateModel(
name="CustomCredential",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"weight",
models.DecimalField(decimal_places=4, default=0.0, max_digits=7),
),
("display_name", models.CharField(max_length=64)),
(
"description",
models.CharField(blank=True, max_length=256, null=True),
),
(
"customization",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="custom_credentials",
to="account.customization",
),
),
],
),
migrations.CreateModel(
name="CustomCredentialRuleset",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"credential_type",
models.CharField(
choices=[("DEVEL", "Developer List")], max_length=5
),
),
(
"definition",
models.JSONField(
validators=[
account.models.validate_custom_stamp_ruleset_definition
]
),
),
("name", models.CharField(max_length=64)),
("provider_id", models.CharField(max_length=256, unique=True)),
],
),
migrations.CreateModel(
name="CustomPlatform",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"platform_type",
models.CharField(
choices=[("DEVEL", "Developer List")], max_length=5
),
),
(
"name",
models.CharField(
help_text="Internal name", max_length=64, unique=True
),
),
(
"display_name",
models.CharField(
blank=True,
help_text="This and all remaining fields are optional, there are defaults defined for each platform type",
max_length=64,
null=True,
),
),
(
"icon_url",
models.CharField(
blank=True,
help_text="e.g. ./assets/icon.svg",
max_length=64,
null=True,
),
),
(
"description",
models.CharField(blank=True, max_length=256, null=True),
),
(
"banner_heading",
models.CharField(blank=True, max_length=64, null=True),
),
(
"banner_content",
models.CharField(blank=True, max_length=256, null=True),
),
(
"banner_cta_text",
models.CharField(
blank=True,
help_text="If either CTA field is set, both must be set",
max_length=256,
null=True,
),
),
(
"banner_cta_url",
models.CharField(blank=True, max_length=256, null=True),
),
],
),
migrations.AlterField(
model_name="includedchainid",
name="chain_id",
field=models.CharField(
help_text="Chain ID in hex format (0x1)! You can find this on for example on: https://chainlist.org",
max_length=200,
validators=[account.models.hex_number_validator],
),
),
migrations.DeleteModel(
name="CustomGithubStamp",
),
migrations.AddField(
model_name="customcredential",
name="platform",
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT, to="account.customplatform"
),
),
migrations.AddField(
model_name="customcredential",
name="ruleset",
field=models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
to="account.customcredentialruleset",
),
),
]
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Generated by Django 4.2.6 on 2024-09-11 20:07
# Generated by Django 4.2.6 on 2024-09-16 23:13

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("account", "0034_customgithubstamp"),
("account", "0035_customcredential_customcredentialruleset_and_more"),
]

operations = [
Expand Down
Loading

0 comments on commit 310d718

Please sign in to comment.