-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathloader.go
More file actions
111 lines (93 loc) · 2.31 KB
/
loader.go
File metadata and controls
111 lines (93 loc) · 2.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package auth
import (
"fmt"
"net/http"
log "git.sr.ht/~mariusor/lw"
vocab "github.com/go-ap/activitypub"
"github.com/go-ap/filters"
"github.com/openshift/osin"
)
// readStore
type readStore interface {
// Load returns an Item or an ItemCollection from an IRI
Load(vocab.IRI, ...filters.Check) (vocab.Item, error)
}
type oauthStore interface {
readStore
LoadAccess(string) (*osin.AccessData, error)
}
type ActivityPubClient interface {
Do(r *http.Request) (*http.Response, error)
LoadIRI(id vocab.IRI) (vocab.Item, error)
}
type config struct {
c ActivityPubClient
st oauthStore
l log.Logger
}
// actorResolver is a used for resolving actors either in local storage or remotely
type actorResolver config
func Config(initFns ...InitFn) config {
c := config{l: log.Nil()}
for _, fn := range initFns {
fn(&c)
}
return c
}
type InitFn = func(*config)
func WithLogger(l log.Logger) InitFn {
return func(conf *config) {
conf.l = l
}
}
func WithStorage(s oauthStore) InitFn {
return func(conf *config) {
conf.st = s
}
}
func WithClient(cl ActivityPubClient) InitFn {
return func(c *config) {
c.c = cl
}
}
func Verifier(initFns ...InitFn) actorResolver {
return actorResolver(Config(initFns...))
}
// Verify reads the Authorization header of an HTTP request and tries to decode it either
// an OAuth2 or HTTP Signatures:
//
// * For OAuth2 it tries to load the matching local actor and use it further in the processing logic.
// * For HTTP Signatures it tries to load the federated actor and use it further in the processing logic.
func (a actorResolver) Verify(r *http.Request) (vocab.Actor, error) {
if a.st == nil {
return AnonymousActor, errInvalidStorage
}
if r == nil {
return AnonymousActor, nil
}
logCtx := log.Ctx{}
logCtx["req"] = fmt.Sprintf("%s:%s", r.Method, r.URL.RequestURI())
var header string
var typ string
var auth string
if auth = r.Header.Get("Signature"); auth != "" {
typ = "Signature"
header = auth
} else if auth = r.Header.Get("Authorization"); auth != "" {
header = auth
typ, auth = getAuthorization(header)
}
switch typ {
case "Bearer":
ol := oauthVerifier{st: a.st}
return ol.Verify(r)
case "Signature":
kl := httpSigVerifier{
loader: &localRemoteLoader{c: a.c, st: a.st},
l: a.l,
}
return kl.Verify(r)
default:
return AnonymousActor, nil
}
}