Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/external passport #26

Merged
merged 14 commits into from
Jul 29, 2024
Merged
34 changes: 17 additions & 17 deletions .github/workflows/actions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@ on:

jobs:
converge:
name: Converge
runs-on: ubuntu-latest
steps:

name: Skaffold Build To Github
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Install werf
uses: werf/actions/[email protected]

- name: Log in to registry
# This is where you will update the personal access token to GITHUB_TOKEN
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin

- name: Run echo
run: |
werf version
docker version
echo $GITHUB_REPOSITORY
echo $GITHUB_SHA
- name: Run Build
run: |
. $(werf ci-env github --as-file)
werf export service --tag ghcr.io/$GITHUB_REPOSITORY:$GITHUB_SHA
- name: Cache layers
uses: actions/cache@v3
with:
path: "${{ github.workspace }}/.skaffold/cache"
key: skaffold-${{ hashFiles('**/cache') }}
restore-keys: |
skaffold-

- name: Run Skaffold pipeline as command
uses: hiberbee/github-action-skaffold@latest
id: build
with:
command: build --tag ${{ github.sha }}
repository: ghcr.io/${{ github.repository_owner }}
34 changes: 17 additions & 17 deletions .github/workflows/tag.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ on:

jobs:
converge:
name: Converge
runs-on: ubuntu-latest
steps:

name: Skaffold Build To Github
runs-on: ubuntu-22.04
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Install werf
uses: werf/actions/[email protected]

- name: Log in to registry
# This is where you will update the personal access token to GITHUB_TOKEN
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin

- name: Run echo
run: |
werf version
docker version
echo $GITHUB_REPOSITORY
echo $GITHUB_REF_NAME
- name: Run Build
run: |
. $(werf ci-env github --as-file)
werf export service --tag ghcr.io/$GITHUB_REPOSITORY:$GITHUB_REF_NAME
- name: Cache layers
uses: actions/cache@v3
with:
path: "${{ github.workspace }}/.skaffold/cache"
key: skaffold-${{ hashFiles('**/cache') }}
restore-keys: |
skaffold-

- name: Run Skaffold pipeline as command
uses: hiberbee/github-action-skaffold@latest
id: build
with:
command: build --tag ${{ github.ref_name }}
repository: ghcr.io/${{ github.repository_owner }}
19 changes: 11 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
FROM golang:1.22-alpine as buildbase

RUN apk add git build-base
RUN apk add git build-base ca-certificates

WORKDIR /go/src/github.com/rarimo/geo-points-svc
COPY vendor .
COPY . .
RUN go mod tidy && go mod vendor
RUN CGO_ENABLED=1 GO111MODULE=on GOOS=linux go build -o /usr/local/bin/geo-points-svc /go/src/github.com/rarimo/geo-points-svc

RUN GOOS=linux go build -o /usr/local/bin/geo-points-svc /go/src/github.com/rarimo/geo-points-svc


FROM alpine:3.9
FROM scratch
COPY --from=alpine:3.9 /bin/sh /bin/sh
COPY --from=alpine:3.9 /usr /usr
COPY --from=alpine:3.9 /lib /lib

COPY --from=buildbase /usr/local/bin/geo-points-svc /usr/local/bin/geo-points-svc
RUN apk add --no-cache ca-certificates
COPY --from=buildbase /go/src/github.com/rarimo/geo-points-svc/proof_keys/passport.json /proof_keys/passport.json
COPY --from=buildbase /go/src/github.com/rarimo/geo-points-svc/proof_keys/poll.json /proof_keys/poll.json
COPY --from=buildbase /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

ENTRYPOINT ["geo-points-svc"]
ENTRYPOINT ["geo-points-svc"]
20 changes: 20 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ event_types:
action_url: https://...
logo: https://...
auto_claim: true
- name: external_passport_scan
reward: 5
# there are default and localized configurations of texts
title: Points for external passport scan
description: Get points for scan passport and share data
short_description: Short description
localized:
en-UK:
title: Points for external passport scan
description: Get points for scan passport and share data
short_description: Short description
en-US:
title: Points for external passport scan
description: Get points for scan passport and share data
short_description: Short description
frequency: one-time
action_url: https://...
logo: https://...
auto_claim: true
- name: free_weekly
title: Free weekly points
reward: 1
Expand Down Expand Up @@ -66,6 +85,7 @@ event_types:
qr_code_value: "qr_code_base64_string"

levels:
downgradeable: false
levels:
- lvl: 1
threshold: 0
Expand Down
4 changes: 4 additions & 0 deletions docs/spec/components/schemas/VerifyPassport.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ allOf:
type: string
description: Unique identifier of the passport.
example: "2bd3a2532096fee10a45a40e444a11b4d00a707f3459376087747de05996fbf5"
shared_hash:
type: string
description: Unique identifier for linking internal and external passports
example: "12345678901234567890"
proof:
type: object
format: types.ZKProof
Expand Down
3 changes: 3 additions & 0 deletions docs/spec/components/securitySchemes/BearerAuth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type: http
scheme: bearer
bearerFormat: JWT
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
post:
tags:
- Points balance
summary: Verify external passport
description: |
Verify passport to unlock event claiming and get reward.
One passport can't be verified twice.

In body must be specified anonymous_id and shared_hash

Some events will be automatically claimed in case if balance is active.
operationId: verifyExternalPassport
parameters:
- $ref: '#/components/parameters/pathNullifier'
- in: header
name: Signature
description: Signature of the request
required: true
schema:
type: string
pattern: '^[a-f0-9]{64}$'
security:
- BearerAuth: []
requestBody:
required: true
content:
application/vnd.api+json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/VerifyPassport'
responses:
200:
description: Success
content:
application/vnd.api+json:
schema:
type: object
required:
- data
properties:
data:
$ref: '#/components/schemas/EventClaimingState'
400:
$ref: '#/components/responses/invalidParameter'
401:
$ref: '#/components/responses/invalidAuth'
403:
description: Invalid signature
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/Errors'
404:
description: Balance not exists
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/Errors'
409:
description: Passport already verified or anonymous ID exists
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/Errors'
500:
$ref: '#/components/responses/internalError'
10 changes: 10 additions & 0 deletions internal/assets/migrations/003_external_join_program.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- +migrate Up
ALTER TABLE balances RENAME COLUMN anonymous_id TO internal_aid;
ALTER TABLE balances ADD COLUMN external_aid TEXT UNIQUE;
ALTER TABLE balances DROP COLUMN is_verified;

-- +migrate Down
ALTER TABLE balances RENAME COLUMN internal_aid TO anonymous_id;
ALTER TABLE balances DROP COLUMN external_aid;
ALTER TABLE balances ADD COLUMN is_verified BOOLEAN NOT NULL default FALSE;
UPDATE balances SET is_verified = TRUE WHERE anonymous_id IS NOT NULL;
8 changes: 7 additions & 1 deletion internal/cli/workers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/rarimo/geo-points-svc/internal/data/evtypes"
"github.com/rarimo/geo-points-svc/internal/service"
"github.com/rarimo/geo-points-svc/internal/service/workers/expirywatch"
"github.com/rarimo/geo-points-svc/internal/service/workers/leveljustice"
"github.com/rarimo/geo-points-svc/internal/service/workers/nooneisforgotten"
"github.com/rarimo/geo-points-svc/internal/service/workers/reopener"
)
Expand All @@ -20,6 +21,7 @@ func runServices(ctx context.Context, cfg config.Config, wg *sync.WaitGroup) {
expiryWatchSig = make(chan struct{})
evTypesSig = make(chan struct{})
noOneIsForgottenSig = make(chan struct{})
levelJustice = make(chan struct{})
)

run := func(f func()) {
Expand All @@ -42,8 +44,12 @@ func runServices(ctx context.Context, cfg config.Config, wg *sync.WaitGroup) {
<-reopenerSig
run(func() { nooneisforgotten.Run(cfg, noOneIsForgottenSig) })

// depends on noOneIsForgoten, because this worker can claim events and change balance
<-noOneIsForgottenSig
run(func() { leveljustice.Run(cfg, levelJustice) })

// service depends on all the workers for good UX
<-expiryWatchSig
<-noOneIsForgottenSig
<-levelJustice
run(func() { service.Run(ctx, cfg) })
}
73 changes: 52 additions & 21 deletions internal/config/levels.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@ type Level struct {
Infinity bool `fig:"infinity"`
}

type Levels map[int]Level
type Levels struct {
levels map[int]Level
Downgradeable bool
}

func (c *config) Levels() Levels {
func (c *config) Levels() *Levels {
return c.levels.Do(func() interface{} {
var cfg struct {
Lvls []Level `fig:"levels,required"`
Downgradeable bool `fig:"downgradeable"`
Lvls []Level `fig:"levels,required"`
}

err := figure.Out(&cfg).
Expand All @@ -35,44 +39,71 @@ func (c *config) Levels() Levels {
panic(errors.New("no levels provided in config"))
}

res := make(Levels, len(cfg.Lvls))
res := make(map[int]Level, len(cfg.Lvls))
for _, v := range cfg.Lvls {
res[v.Level] = v
}

return res
}).(Levels)
return &Levels{
levels: res,
Downgradeable: cfg.Downgradeable,
}
}).(*Levels)
}

// LvlUp Calculates new lvl. New lvl always greater then current level
func (l Levels) LvlUp(currentLevel int, totalAmount int64) (refCoundToAdd int, newLevel int) {
lvls := make([]int, 0, len(l))
for k, v := range l {
if k <= currentLevel {
continue
}
if int64(v.Threshold) > totalAmount {
continue
func (l *Levels) LvlChange(currentLevel int, totalAmount int64) (refCoundToAdd *int, newLevel int) {
var downgrade bool
if l.Downgradeable && l.levels[currentLevel].Threshold > int(totalAmount) {
downgrade = true
}
lvls := make([]int, 0, len(l.levels))
refCoundToAdd = new(int)

if downgrade {
for k, v := range l.levels {
if k > currentLevel {
continue
}
if int64(v.Threshold) <= totalAmount {
continue
}

*refCoundToAdd -= v.Referrals
lvls = append(lvls, k)
}
} else {
for k, v := range l.levels {
if k <= currentLevel {
continue
}
if int64(v.Threshold) > totalAmount {
continue
}

refCoundToAdd += v.Referrals
lvls = append(lvls, k)
*refCoundToAdd += v.Referrals
lvls = append(lvls, k)
}
}

if len(lvls) == 0 {
return 0, currentLevel
return refCoundToAdd, currentLevel
}

newLevel = slices.Max(lvls)
if l[newLevel].Infinity {
refCoundToAdd = -1
if downgrade {
newLevel = slices.Min(lvls) - 1
}

if l.levels[newLevel].Infinity {
return nil, newLevel
}
return
}

func (l Levels) MinLvl() int {
lvls := make([]int, 0, len(l))
for k := range l {
lvls := make([]int, 0, len(l.levels))
for k := range l.levels {
lvls = append(lvls, k)
}

Expand Down
Loading
Loading