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