This repository has no description
1.5 kB
57 lines
1package xrpc
2
3import (
4 "net/http"
5 "strings"
6
7 "golang.org/x/crypto/ssh"
8 "tangled.org/core/api/tangled"
9 "tangled.org/core/rbac"
10 xrpcerr "tangled.org/core/xrpc/errors"
11)
12
13func (x *Xrpc) CheckPushAllowed(w http.ResponseWriter, r *http.Request) {
14 repo := strings.TrimSpace(r.URL.Query().Get("repo"))
15 keyStr := r.URL.Query().Get("key")
16
17 if !strings.HasPrefix(repo, "did:") || keyStr == "" {
18 writeError(w, xrpcerr.NewXrpcError(
19 xrpcerr.WithTag("InvalidRequest"),
20 xrpcerr.WithMessage("repo (a repo DID) and key are required"),
21 ), http.StatusBadRequest)
22 return
23 }
24
25 offered, _, _, _, err := ssh.ParseAuthorizedKey([]byte(keyStr))
26 if err != nil {
27 writeError(w, xrpcerr.NewXrpcError(
28 xrpcerr.WithTag("InvalidRequest"),
29 xrpcerr.WithMessage("malformed public key"),
30 ), http.StatusBadRequest)
31 return
32 }
33
34 did, ok, err := x.Db.DidForPublicKey(offered)
35 if err != nil {
36 x.Logger.Error("failed to look up public key", "error", err)
37 x.writeJson(w, tangled.RepoCheckPushAllowed_Output{Allowed: false})
38 return
39 }
40 if !ok {
41 // unknown key, not an error, just not allowed
42 x.writeJson(w, tangled.RepoCheckPushAllowed_Output{Allowed: false})
43 return
44 }
45
46 didStr := did.String()
47
48 allowed, err := x.Enforcer.IsPushAllowed(didStr, rbac.ThisServer, repo)
49 if err != nil {
50 x.Logger.Error("enforcer error", "did", didStr, "repo", repo, "error", err)
51 allowed = false
52 }
53
54 out := tangled.RepoCheckPushAllowed_Output{Allowed: allowed}
55 out.Did = &didStr
56 x.writeJson(w, out)
57}