tinyrelayfile
tinyrelay/protocol/auth/grasp08.go/

protocol/auth/grasp08.go raw
1package auth
2
3import (
4 "errors"
5 "net/url"
6 "strings"
7
8 "github.com/FelineStateMachine/tinyrelay/protocol/nostr"
9)
10
11// ErrGRASP08Unauthorized is the detail-free GRASP-08 authentication error
12// returned for every failed repository proof.
13var ErrGRASP08Unauthorized = errors.New("auth-required:")
14
15// VerifyGRASP08 validates a reusable kind 27235 GET proof for the repository
16// root named by a GRASP-08 Smart HTTP request. The proof remains valid for
17// one minute across the repository's supported Git requests.
18func (v *Validator) VerifyGRASP08(header, rawURL string) (nostr.Event, error) {
19 e, err := decodeToken(header, "GRASP-08")
20 if err != nil {
21 return nostr.Event{}, ErrGRASP08Unauthorized
22 }
23 if err := nostr.Validate(e); err != nil || e.Kind != 27235 {
24 return nostr.Event{}, ErrGRASP08Unauthorized
25 }
26 now := v.now()
27 if e.CreatedAt < now.Unix()-60 || e.CreatedAt > now.Unix()+60 {
28 return nostr.Event{}, ErrGRASP08Unauthorized
29 }
30 if nostr.Tag(e, "method") != "GET" {
31 return nostr.Event{}, ErrGRASP08Unauthorized
32 }
33 root, ok := GRASP08RepositoryRoot(rawURL)
34 if !ok || sameRequestURL(nostr.Tag(e, "u"), root) != nil {
35 return nostr.Event{}, ErrGRASP08Unauthorized
36 }
37 return e, nil
38}
39
40// GRASP08RepositoryRoot returns the canonical repository URL for a supported
41// Smart HTTP request beneath a .git path.
42func GRASP08RepositoryRoot(raw string) (string, bool) {
43 u, err := url.Parse(raw)
44 if err != nil || (u.Scheme != "http" && u.Scheme != "https") || u.Host == "" || u.User != nil {
45 return "", false
46 }
47 // Keep the client's percent-encoding so the root compares equal to the
48 // signed u tag, which is also kept as sent.
49 path := u.EscapedPath()
50 i := strings.LastIndex(path, ".git")
51 if i < 0 || (i+4 < len(path) && path[i+4] != '/') {
52 return "", false
53 }
54 rootPath := path[:i+4]
55 suffix := path[i+4:]
56 if suffix != "" && suffix != "/info/refs" && suffix != "/git-upload-pack" && suffix != "/git-receive-pack" {
57 return "", false
58 }
59 if strings.HasSuffix(rootPath, "/") {
60 return "", false
61 }
62 unescaped, err := url.PathUnescape(rootPath)
63 if err != nil {
64 return "", false
65 }
66 u.Path, u.RawPath, u.RawQuery, u.Fragment = unescaped, rootPath, "", ""
67 return u.String(), true
68}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs