OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
4 | 4 |
5 package server | 5 package server |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "strconv" | 9 "strconv" |
10 "strings" | 10 "strings" |
11 "time" | 11 "time" |
12 | 12 |
13 "golang.org/x/net/context" | 13 "golang.org/x/net/context" |
14 | 14 |
15 ds "github.com/luci/gae/service/datastore" | 15 ds "github.com/luci/gae/service/datastore" |
16 "github.com/luci/gae/service/info" | 16 "github.com/luci/gae/service/info" |
17 "github.com/luci/luci-go/common/clock" | 17 "github.com/luci/luci-go/common/clock" |
18 "github.com/luci/luci-go/common/errors" | |
19 "github.com/luci/luci-go/common/logging" | 18 "github.com/luci/luci-go/common/logging" |
| 19 "github.com/luci/luci-go/common/retry" |
20 "github.com/luci/luci-go/server/auth" | 20 "github.com/luci/luci-go/server/auth" |
21 "github.com/luci/luci-go/server/auth/identity" | 21 "github.com/luci/luci-go/server/auth/identity" |
22 ) | 22 ) |
23 | 23 |
24 // SessionStore stores auth sessions in the datastore (always in the default | 24 // SessionStore stores auth sessions in the datastore (always in the default |
25 // namespace). It implements auth.SessionStore. | 25 // namespace). It implements auth.SessionStore. |
26 type SessionStore struct { | 26 type SessionStore struct { |
27 Prefix string // used as prefix for datastore keys | 27 Prefix string // used as prefix for datastore keys |
28 } | 28 } |
29 | 29 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 80 } |
81 if err = ds.Put(c, &userEnt, &sessionEnt); err != nil { | 81 if err = ds.Put(c, &userEnt, &sessionEnt); err != nil { |
82 return err | 82 return err |
83 } | 83 } |
84 | 84 |
85 sessionID = fmt.Sprintf("%s/%s/%d", s.Prefix, userID, sessionEnt
.ID) | 85 sessionID = fmt.Sprintf("%s/%s/%d", s.Prefix, userID, sessionEnt
.ID) |
86 return nil | 86 return nil |
87 }, nil) | 87 }, nil) |
88 | 88 |
89 if err != nil { | 89 if err != nil { |
90 » » return "", errors.WrapTransient(err) | 90 » » return "", retry.Tag.Apply(err) |
91 } | 91 } |
92 return sessionID, nil | 92 return sessionID, nil |
93 } | 93 } |
94 | 94 |
95 // CloseSession closes a session given its ID. Does nothing if session is | 95 // CloseSession closes a session given its ID. Does nothing if session is |
96 // already closed or doesn't exist. Returns only transient errors. | 96 // already closed or doesn't exist. Returns only transient errors. |
97 func (s *SessionStore) CloseSession(c context.Context, sessionID string) error { | 97 func (s *SessionStore) CloseSession(c context.Context, sessionID string) error { |
98 c = defaultNS(c) | 98 c = defaultNS(c) |
99 ent, err := s.fetchSession(c, sessionID) | 99 ent, err := s.fetchSession(c, sessionID) |
100 switch { | 100 switch { |
101 case err != nil: | 101 case err != nil: |
102 return err | 102 return err |
103 case ent == nil: | 103 case ent == nil: |
104 return nil | 104 return nil |
105 default: | 105 default: |
106 ent.IsClosed = true | 106 ent.IsClosed = true |
107 ent.Closed = clock.Now(c).UTC() | 107 ent.Closed = clock.Now(c).UTC() |
108 » » return errors.WrapTransient(ds.Put(ds.WithoutTransaction(c), ent
)) | 108 » » return retry.Tag.Apply(ds.Put(ds.WithoutTransaction(c), ent)) |
109 } | 109 } |
110 } | 110 } |
111 | 111 |
112 // GetSession returns existing non-expired session given its ID. Returns nil | 112 // GetSession returns existing non-expired session given its ID. Returns nil |
113 // if session doesn't exist, closed or expired. Returns only transient errors. | 113 // if session doesn't exist, closed or expired. Returns only transient errors. |
114 func (s *SessionStore) GetSession(c context.Context, sessionID string) (*auth.Se
ssion, error) { | 114 func (s *SessionStore) GetSession(c context.Context, sessionID string) (*auth.Se
ssion, error) { |
115 c = defaultNS(c) | 115 c = defaultNS(c) |
116 ent, err := s.fetchSession(c, sessionID) | 116 ent, err := s.fetchSession(c, sessionID) |
117 if ent == nil { | 117 if ent == nil { |
118 return nil, err | 118 return nil, err |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 } | 154 } |
155 switch err = ds.Get(c, &sessionEnt); err { | 155 switch err = ds.Get(c, &sessionEnt); err { |
156 case nil: | 156 case nil: |
157 if sessionEnt.IsClosed || clock.Now(c).After(sessionEnt.Expirati
on) { | 157 if sessionEnt.IsClosed || clock.Now(c).After(sessionEnt.Expirati
on) { |
158 return nil, nil | 158 return nil, nil |
159 } | 159 } |
160 return &sessionEnt, nil | 160 return &sessionEnt, nil |
161 case ds.ErrNoSuchEntity: | 161 case ds.ErrNoSuchEntity: |
162 return nil, nil | 162 return nil, nil |
163 default: | 163 default: |
164 » » return nil, errors.WrapTransient(err) | 164 » » return nil, retry.Tag.Apply(err) |
165 } | 165 } |
166 } | 166 } |
167 | 167 |
168 //// | 168 //// |
169 | 169 |
170 // profile is used in both userEntity and sessionEntity. It holds information | 170 // profile is used in both userEntity and sessionEntity. It holds information |
171 // about a user extracted from user.User struct. | 171 // about a user extracted from user.User struct. |
172 type profile struct { | 172 type profile struct { |
173 Identity string | 173 Identity string |
174 Superuser bool `gae:",noindex"` | 174 Superuser bool `gae:",noindex"` |
(...skipping 28 matching lines...) Expand all Loading... |
203 ID int64 `gae:"$id"` | 203 ID int64 `gae:"$id"` |
204 Parent *ds.Key `gae:"$parent"` | 204 Parent *ds.Key `gae:"$parent"` |
205 | 205 |
206 Profile profile | 206 Profile profile |
207 Created time.Time // when this session was created | 207 Created time.Time // when this session was created |
208 Expiration time.Time // when this session expires | 208 Expiration time.Time // when this session expires |
209 | 209 |
210 IsClosed bool // if true, the session was closed by CloseSession() | 210 IsClosed bool // if true, the session was closed by CloseSession() |
211 Closed time.Time // when the session was closed by CloseSession() | 211 Closed time.Time // when the session was closed by CloseSession() |
212 } | 212 } |
OLD | NEW |