-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
session.go
153 lines (127 loc) · 3.17 KB
/
session.go
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.
package libkb
import (
"time"
keybase1 "github.com/keybase/client/go/protocol/keybase1"
)
type Session struct {
Contextified
token string
csrf string
deviceID keybase1.DeviceID
valid bool
uid keybase1.UID
username *NormalizedUsername
mtime time.Time
checked bool
}
func newSession(g *GlobalContext) *Session {
return &Session{Contextified: Contextified{g}}
}
// NewSessionThin creates a minimal (thin) session of just the uid and username.
// Clients of the daemon that use the session protocol need this.
func NewSessionThin(uid keybase1.UID, username NormalizedUsername, token string) *Session {
// XXX should this set valid to true? daemon won't return a
// session unless valid is true, so...
return &Session{uid: uid, username: &username, token: token, valid: true}
}
func (s *Session) IsLoggedIn() bool {
return s.valid
}
func (s *Session) Clone() *Session {
if s == nil {
return nil
}
ret := *s
if ret.username != nil {
un := *ret.username
ret.username = &un
}
return &ret
}
func (s *Session) GetUsername() *NormalizedUsername {
return s.username
}
func (s *Session) GetUID() keybase1.UID {
return s.uid
}
func (s *Session) GetDeviceID() keybase1.DeviceID {
return s.deviceID
}
func (s *Session) GetToken() string {
return s.token
}
func (s *Session) GetCsrf() string {
return s.csrf
}
func (s *Session) APIArgs() (token, csrf string) {
return s.token, s.csrf
}
func (s *Session) SetUsername(username NormalizedUsername) {
s.username = &username
}
func (s *Session) SetLoggedIn(sessionID, csrfToken string, username NormalizedUsername, uid keybase1.UID, deviceID keybase1.DeviceID) error {
s.valid = true
s.uid = uid
s.username = &username
s.token = sessionID
s.csrf = csrfToken
s.deviceID = deviceID
s.mtime = time.Now()
return nil
}
func (s *Session) SetDeviceProvisioned(devid keybase1.DeviceID) error {
s.G().Log.Debug("Local Session: setting provisioned device id: %s", devid)
s.deviceID = devid
return nil
}
func (s *Session) IsRecent() bool {
if s.mtime.IsZero() {
return false
}
return time.Since(s.mtime) < time.Hour
}
// Invalidate marks the session as invalid and posts a logout
// notification.
func (s *Session) Invalidate() {
s.G().Log.Debug("invalidating session")
s.valid = false
s.mtime = time.Time{}
s.token = ""
s.csrf = ""
s.checked = false
}
func (s *Session) HasSessionToken() bool {
return len(s.token) > 0
}
func (s *Session) IsValid() bool {
return s.valid
}
type SessionTokener struct {
session, csrf string
}
func (s *SessionTokener) Tokens() (session, csrf string) {
return s.session, s.csrf
}
func NewSessionTokener(mctx MetaContext) (*SessionTokener, error) {
resp, err := mctx.G().API.Post(mctx, APIArg{
Endpoint: "new_session",
SessionType: APISessionTypeREQUIRED,
})
if err != nil {
return nil, err
}
session, err := resp.Body.AtKey("session").GetString()
if err != nil {
return nil, err
}
csrf, err := resp.Body.AtKey("csrf_token").GetString()
if err != nil {
return nil, err
}
return &SessionTokener{
session: session,
csrf: csrf,
}, nil
}