diff --git a/cmd/gen.go b/cmd/gen.go new file mode 100644 index 0000000..dea851c --- /dev/null +++ b/cmd/gen.go @@ -0,0 +1,22 @@ +package main + +import ( + shbild "github.com/icyphox/bild/api/bild" + cbg "github.com/whyrusleeping/cbor-gen" +) + +func main() { + + genCfg := cbg.Gen{ + MaxStringLength: 1_000_000, + } + + if err := genCfg.WriteMapEncodersToFile( + "api/bild/cbor_gen.go", + "bild", + shbild.PublicKey{}, + ); err != nil { + panic(err) + } + +} diff --git a/flake.nix b/flake.nix index cc3c7cb..01d3f29 100644 --- a/flake.nix +++ b/flake.nix @@ -49,6 +49,7 @@ pkgs.gopls pkgs.httpie pkgs.indigo-lexgen + pkgs.litecli ]; }; }); diff --git a/go.mod b/go.mod index a74bf6b..de617a8 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/gorilla/securecookie v1.1.2 // indirect github.com/gorilla/sessions v1.4.0 // indirect diff --git a/go.sum b/go.sum index 35dbf25..afc2eb7 100644 --- a/go.sum +++ b/go.sum @@ -80,6 +80,8 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= diff --git a/lexicon-build-config.json b/lexicon-build-config.json new file mode 100644 index 0000000..4916867 --- /dev/null +++ b/lexicon-build-config.json @@ -0,0 +1,9 @@ +[ + { + "package": "bild", + "prefix": "sh.bild", + "outdir": "api/bild", + "import": "github.com/icyphox/bild/api/bild", + "gen-server": true + } +] diff --git a/lexicons/publicKey.json b/lexicons/publicKey.json new file mode 100644 index 0000000..d6d2663 --- /dev/null +++ b/lexicons/publicKey.json @@ -0,0 +1,38 @@ +{ + "lexicon": 1, + "id": "sh.bild.publicKey", + "needsCbor": true, + "needsType": true, + "defs": { + "main": { + "type": "record", + "key": "tid", + "record": { + "type": "object", + "required": [ + "key", + "name", + "created" + ], + "properties": { + "key": { + "type": "string", + "maxLength": 4096, + "maxGraphemes": 4096, + "description": "public key contents" + }, + "name": { + "type": "string", + "format": "string", + "description": "human-readable name for this key" + }, + "created": { + "type": "string", + "format": "datetime", + "description": "key upload timestamp" + } + } + } + } + } +} diff --git a/routes/auth/auth.go b/routes/auth/auth.go index b33ca40..cf4eb3b 100644 --- a/routes/auth/auth.go +++ b/routes/auth/auth.go @@ -31,6 +31,30 @@ func resolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { return dir.Lookup(ctx, *id) } +func (a *Auth) AuthorizedClient(r *http.Request) (*xrpc.Client, error) { + clientSession, err := a.s.Get(r, "bild-session") + + if err != nil || clientSession.IsNew { + return nil, err + } + + did := clientSession.Values["did"].(string) + pdsUrl := clientSession.Values["pds"].(string) + accessJwt := clientSession.Values["accessJwt"].(string) + refreshJwt := clientSession.Values["refreshJwt"].(string) + + client := &xrpc.Client{ + Host: pdsUrl, + Auth: &xrpc.AuthInfo{ + AccessJwt: accessJwt, + RefreshJwt: refreshJwt, + Did: did, + }, + } + + return client, nil +} + func (a *Auth) CreateInitialSession(w http.ResponseWriter, r *http.Request, username, appPassword string) (AtSessionCreate, error) { ctx := r.Context() resolved, err := resolveIdent(ctx, username) diff --git a/routes/routes.go b/routes/routes.go index ce11102..24fc033 100644 --- a/routes/routes.go +++ b/routes/routes.go @@ -14,10 +14,14 @@ import ( "strings" "time" + comatproto "github.com/bluesky-social/indigo/api/atproto" + lexutil "github.com/bluesky-social/indigo/lex/util" "github.com/dustin/go-humanize" "github.com/go-chi/chi/v5" "github.com/go-git/go-git/v5/plumbing" + "github.com/google/uuid" "github.com/gorilla/sessions" + shbild "github.com/icyphox/bild/api/bild" "github.com/icyphox/bild/config" "github.com/icyphox/bild/db" "github.com/icyphox/bild/git" @@ -490,6 +494,7 @@ func (h *Handle) Keys(w http.ResponseWriter, r *http.Request) { case http.MethodPut: key := r.FormValue("key") name := r.FormValue("name") + client, _ := h.auth.AuthorizedClient(r) _, _, _, _, err := ssh.ParseAuthorizedKey([]byte(key)) if err != nil { @@ -504,6 +509,27 @@ func (h *Handle) Keys(w http.ResponseWriter, r *http.Request) { return } + // store in pds too + resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ + Collection: "sh.bild.publicKey", + Repo: did, + Rkey: uuid.New().String(), + Record: &lexutil.LexiconTypeDecoder{Val: &shbild.PublicKey{ + Created: time.Now().String(), + Key: key, + Name: name, + }}, + }) + + // invalid record + if err != nil { + h.WriteOOBNotice(w, "keys", "Invalid inputs. Check your formatting and try again.") + log.Printf("failed to create record: %s", err) + return + } + + log.Println("created atproto record: ", resp.Uri) + h.WriteOOBNotice(w, "keys", "Key added!") return }