this repo has no description
1package auth
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "log"
8 "net/http"
9 "time"
10
11 comatproto "github.com/bluesky-social/indigo/api/atproto"
12 "github.com/bluesky-social/indigo/atproto/identity"
13 "github.com/bluesky-social/indigo/atproto/syntax"
14 "github.com/bluesky-social/indigo/xrpc"
15 "github.com/gorilla/sessions"
16)
17
18type Auth struct {
19 store sessions.Store
20}
21
22type AtSessionCreate struct {
23 comatproto.ServerCreateSession_Output
24 PDSEndpoint string
25}
26
27type AtSessionRefresh struct {
28 comatproto.ServerRefreshSession_Output
29 PDSEndpoint string
30}
31
32func Make() (*Auth, error) {
33 store := sessions.NewCookieStore([]byte("TODO_CHANGE_ME"))
34 return &Auth{store}, nil
35}
36
37func ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) {
38 id, err := syntax.ParseAtIdentifier(arg)
39 if err != nil {
40 return nil, err
41 }
42
43 dir := identity.DefaultDirectory()
44 return dir.Lookup(ctx, *id)
45}
46
47func (a *Auth) CreateInitialSession(ctx context.Context, username, appPassword string) (*comatproto.ServerCreateSession_Output, error) {
48 resolved, err := ResolveIdent(ctx, username)
49 if err != nil {
50 return nil, fmt.Errorf("invalid handle: %s", err)
51 }
52
53 pdsUrl := resolved.PDSEndpoint()
54 client := xrpc.Client{
55 Host: pdsUrl,
56 }
57
58 atSession, err := comatproto.ServerCreateSession(ctx, &client, &comatproto.ServerCreateSession_Input{
59 Identifier: resolved.DID.String(),
60 Password: appPassword,
61 })
62 if err != nil {
63 return nil, fmt.Errorf("invalid app password")
64 }
65
66 return atSession, nil
67}
68
69func (a *Auth) StoreSession(r *http.Request, w http.ResponseWriter, atSession *comatproto.ServerCreateSession_Output) error {
70 var didDoc identity.DIDDocument
71
72 bytes, _ := json.Marshal(atSession.DidDoc)
73 err := json.Unmarshal(bytes, &didDoc)
74 if err != nil {
75 log.Printf("did: %+v", *atSession.DidDoc)
76 return fmt.Errorf("invalid did document for session")
77 }
78
79 identity := identity.ParseIdentity(&didDoc)
80 pdsEndpoint := identity.PDSEndpoint()
81
82 if pdsEndpoint == "" {
83 return fmt.Errorf("no pds endpoint found")
84 }
85
86 clientSession, _ := a.store.Get(r, "appview-session")
87 clientSession.Values["handle"] = atSession.Handle
88 clientSession.Values["did"] = atSession.Did
89 clientSession.Values["pds"] = pdsEndpoint
90 clientSession.Values["accessJwt"] = atSession.AccessJwt
91 clientSession.Values["refreshJwt"] = atSession.RefreshJwt
92 clientSession.Values["expiry"] = time.Now().Add(time.Hour).String()
93 clientSession.Values["authenticated"] = true
94
95 return clientSession.Save(r, w)
96}