/
session.go
101 lines (81 loc) · 2.63 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
// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"time"
"upspin.io/cache"
"upspin.io/upspin"
)
// Session contains information about the connection and the authenticated user, if any.
type Session interface {
// User returns the user name present in the session. It may be empty. Note: user, even when present,
// might not be authenticated.
User() upspin.UserName
// Err reports the status of the session.
Err() error
// Expires returns the expiration time of the session, in UTC.
Expires() time.Time
// ProxiedEndpoint returns the endpoint for which this session is a proxy.
// If we aren't proxying it returns an Unassigned endpoint.
ProxiedEndpoint() upspin.Endpoint
}
// sessionCacheSize is the max number of sessions to remember. Small values will limit parallelism and
// very large values will allow authToken collisions, either accidentally or by brute-force attacks.
const sessionCacheSize = 1000
var sessionCache *cache.LRU // Caches <authToken, Session> Thread safe.
// NewSession creates a new session with the given contents.
func NewSession(user upspin.UserName, expiration time.Time, authToken string, proxyFor *upspin.Endpoint, err error) Session {
session := &sessionImpl{
user: user,
expires: expiration,
authToken: authToken,
err: err,
endpoint: *proxyFor,
}
sessionCache.Add(authToken, session)
return session
}
// GetSession returns a session associated with an auth token, if one has been cached or nil otherwise.
func GetSession(authToken string) Session {
session, ok := sessionCache.Get(authToken)
if !ok {
return nil
}
return session.(Session)
}
// ClearSession removes a session associated with a given auth token from the cache.
func ClearSession(authToken string) {
sessionCache.Remove(authToken)
}
// resetSessions creates a new session cache. It is not thread safe. To be used for testing only.
func resetSessions() {
sessionCache = cache.NewLRU(sessionCacheSize)
}
type sessionImpl struct {
user upspin.UserName
authToken string
err error
expires time.Time
endpoint upspin.Endpoint
}
var _ Session = (*sessionImpl)(nil)
// User implements Session.
func (s *sessionImpl) User() upspin.UserName {
return s.user
}
// Err implements Session.
func (s *sessionImpl) Err() error {
return s.err
}
// Expires implements Session.
func (s *sessionImpl) Expires() time.Time {
return s.expires
}
// ProxiedEndpoint implements Session.
func (s *sessionImpl) ProxiedEndpoint() upspin.Endpoint {
return s.endpoint
}
func init() {
resetSessions()
}