1// Copyright 2015 Keybase, Inc. All rights reserved. Use of 2// this source code is governed by the included BSD license. 3 4package libkb 5 6import ( 7 "time" 8 9 keybase1 "github.com/keybase/client/go/protocol/keybase1" 10) 11 12type Session struct { 13 Contextified 14 token string 15 csrf string 16 deviceID keybase1.DeviceID 17 valid bool 18 uid keybase1.UID 19 username *NormalizedUsername 20 mtime time.Time 21 checked bool 22} 23 24func newSession(g *GlobalContext) *Session { 25 return &Session{Contextified: Contextified{g}} 26} 27 28// NewSessionThin creates a minimal (thin) session of just the uid and username. 29// Clients of the daemon that use the session protocol need this. 30func NewSessionThin(uid keybase1.UID, username NormalizedUsername, token string) *Session { 31 // XXX should this set valid to true? daemon won't return a 32 // session unless valid is true, so... 33 return &Session{uid: uid, username: &username, token: token, valid: true} 34} 35 36func (s *Session) IsLoggedIn() bool { 37 return s.valid 38} 39 40func (s *Session) Clone() *Session { 41 if s == nil { 42 return nil 43 } 44 ret := *s 45 if ret.username != nil { 46 un := *ret.username 47 ret.username = &un 48 } 49 return &ret 50} 51 52func (s *Session) GetUsername() *NormalizedUsername { 53 return s.username 54} 55 56func (s *Session) GetUID() keybase1.UID { 57 return s.uid 58} 59 60func (s *Session) GetDeviceID() keybase1.DeviceID { 61 return s.deviceID 62} 63 64func (s *Session) GetToken() string { 65 return s.token 66} 67 68func (s *Session) GetCsrf() string { 69 return s.csrf 70} 71 72func (s *Session) APIArgs() (token, csrf string) { 73 return s.token, s.csrf 74} 75 76func (s *Session) SetUsername(username NormalizedUsername) { 77 s.username = &username 78} 79 80func (s *Session) SetLoggedIn(sessionID, csrfToken string, username NormalizedUsername, uid keybase1.UID, deviceID keybase1.DeviceID) error { 81 s.valid = true 82 s.uid = uid 83 s.username = &username 84 s.token = sessionID 85 s.csrf = csrfToken 86 s.deviceID = deviceID 87 s.mtime = time.Now() 88 return nil 89} 90 91func (s *Session) SetDeviceProvisioned(devid keybase1.DeviceID) error { 92 s.G().Log.Debug("Local Session: setting provisioned device id: %s", devid) 93 s.deviceID = devid 94 return nil 95} 96 97func (s *Session) IsRecent() bool { 98 if s.mtime.IsZero() { 99 return false 100 } 101 return time.Since(s.mtime) < time.Hour 102} 103 104// Invalidate marks the session as invalid and posts a logout 105// notification. 106func (s *Session) Invalidate() { 107 s.G().Log.Debug("invalidating session") 108 s.valid = false 109 s.mtime = time.Time{} 110 s.token = "" 111 s.csrf = "" 112 s.checked = false 113} 114 115func (s *Session) HasSessionToken() bool { 116 return len(s.token) > 0 117} 118 119func (s *Session) IsValid() bool { 120 return s.valid 121} 122 123type SessionTokener struct { 124 session, csrf string 125} 126 127func (s *SessionTokener) Tokens() (session, csrf string) { 128 return s.session, s.csrf 129} 130 131func NewSessionTokener(mctx MetaContext) (*SessionTokener, error) { 132 resp, err := mctx.G().API.Post(mctx, APIArg{ 133 Endpoint: "new_session", 134 SessionType: APISessionTypeREQUIRED, 135 }) 136 if err != nil { 137 return nil, err 138 } 139 140 session, err := resp.Body.AtKey("session").GetString() 141 if err != nil { 142 return nil, err 143 } 144 csrf, err := resp.Body.AtKey("csrf_token").GetString() 145 if err != nil { 146 return nil, err 147 } 148 149 return &SessionTokener{ 150 session: session, 151 csrf: csrf, 152 }, nil 153} 154