Chromium Code Reviews| Index: impl/memory/user.go |
| diff --git a/impl/memory/user.go b/impl/memory/user.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2917b2395cee21927033bdbeafc1dfe7126c516e |
| --- /dev/null |
| +++ b/impl/memory/user.go |
| @@ -0,0 +1,114 @@ |
| +// Copyright 2015 The Chromium 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 memory |
| + |
| +import ( |
| + "crypto/sha256" |
| + "encoding/hex" |
| + "fmt" |
| + "net/url" |
| + "strings" |
| + "sync" |
| + |
| + "golang.org/x/net/context" |
| + |
| + "github.com/luci/gae/service/user" |
| +) |
| + |
| +type userData struct { |
| + sync.RWMutex |
| + user *user.User |
| +} |
| + |
| +// userImpl is a contextual pointer to the current userData. |
| +type userImpl struct { |
| + data *userData |
| +} |
| + |
| +var _ user.Interface = (*userImpl)(nil) |
| + |
| +// useUser adds a user.Interface implementation to context, accessible |
| +// by user.Get(c) |
| +func useUser(c context.Context) context.Context { |
| + data := &userData{} |
| + |
| + return user.SetFactory(c, func(ic context.Context) user.Interface { |
| + return &userImpl{data} |
| + }) |
| +} |
| + |
| +func (u *userImpl) Current() *user.User { |
| + u.data.RLock() |
| + defer u.data.RUnlock() |
| + return u.data.user |
|
Vadim Sh.
2015/12/13 21:20:48
return nil if user.ClientID != "" (to mimic behavi
iannucci
2015/12/14 08:49:01
done
|
| +} |
| + |
| +func (u *userImpl) CurrentOAuth(scopes ...string) (*user.User, error) { |
| + // TODO(riannucci): something more clever in the Testing interface here? |
| + u.data.RLock() |
| + defer u.data.RUnlock() |
| + return u.data.user, nil |
|
Vadim Sh.
2015/12/13 21:20:48
return nil if user.ClientID == "" (to mimic behavi
iannucci
2015/12/14 08:49:01
done
|
| +} |
| + |
| +func (u *userImpl) IsAdmin() bool { |
| + u.data.RLock() |
| + defer u.data.RUnlock() |
| + return u.data.user.Admin |
| +} |
| + |
| +func (u *userImpl) LoginURL(dest string) (string, error) { |
| + // TODO(riannucci): something more clever? |
| + return "https://fakeapp.example.com/_ah/login?redirect=" + url.QueryEscape(dest), nil |
| +} |
| + |
| +func (u *userImpl) LoginURLFederated(dest, identity string) (string, error) { |
| + return "", fmt.Errorf("OpenID is deprecated") |
| +} |
| + |
| +func (u *userImpl) LogoutURL(dest string) (string, error) { |
| + // TODO(riannucci): something more clever? |
| + return "https://fakeapp.example.com/_ah/logout?redirect=" + url.QueryEscape(dest), nil |
| +} |
| + |
| +func (u *userImpl) OAuthConsumerKey() (string, error) { |
|
Vadim Sh.
2015/12/13 21:20:48
I think this thing is also deprecated (as the rest
iannucci
2015/12/14 08:49:01
made it return an error, since we don't know how t
|
| + // TODO(riannucci): something more clever? |
| + u.data.RLock() |
| + defer u.data.RUnlock() |
| + return "consumer_key:" + u.data.user.Email, nil |
| +} |
| + |
| +func (u *userImpl) Testing() user.Testing { |
| + return u |
| +} |
| + |
| +func (u *userImpl) SetUser(user *user.User) { |
| + u.data.Lock() |
| + defer u.data.Unlock() |
| + u.data.user = user |
| +} |
| + |
| +func (u *userImpl) Login(email string, admin bool) { |
| + parts := strings.SplitN(email, "@", 2) |
| + if len(parts) != 2 { |
| + panic(fmt.Errorf("%q doesn't seem to be a valid email", email)) |
| + } |
| + |
| + // TODO(riannucci): something more clever? |
| + id := sha256.Sum256([]byte("ID:" + email)) |
| + clientID := sha256.Sum256([]byte("ClientID:" + email)) |
| + |
| + u.SetUser(&user.User{ |
| + Email: email, |
| + AuthDomain: parts[1], |
| + Admin: admin, |
| + |
| + ID: hex.EncodeToString(id[:]), |
|
Vadim Sh.
2015/12/13 21:20:48
in real life it is usually int64 (as a string)
iannucci
2015/12/14 08:49:01
done
|
| + ClientID: hex.EncodeToString(clientID[:]), |
|
Vadim Sh.
2015/12/13 21:20:48
in real life this is set only for return value of
|
| + }) |
| +} |
| + |
| +func (u *userImpl) Logout() { |
| + u.SetUser(nil) |
| +} |