| Index: impl/memory/user.go
|
| diff --git a/impl/memory/user.go b/impl/memory/user.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1813d41f9b465c197219ecf97ff09daa90463e92
|
| --- /dev/null
|
| +++ b/impl/memory/user.go
|
| @@ -0,0 +1,115 @@
|
| +// 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/binary"
|
| + "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()
|
| + if u.data.user != nil && u.data.user.ClientID == "" {
|
| + ret := *u.data.user
|
| + return &ret
|
| + }
|
| + return nil
|
| +}
|
| +
|
| +func (u *userImpl) CurrentOAuth(scopes ...string) (*user.User, error) {
|
| + // TODO(riannucci): something more clever in the Testable interface here?
|
| + u.data.RLock()
|
| + defer u.data.RUnlock()
|
| + if u.data.user != nil && u.data.user.ClientID != "" {
|
| + ret := *u.data.user
|
| + return &ret, nil
|
| + }
|
| + return nil, nil
|
| +}
|
| +
|
| +func (u *userImpl) IsAdmin() bool {
|
| + u.data.RLock()
|
| + defer u.data.RUnlock()
|
| + return u.data.user != nil && u.data.user.Admin
|
| +}
|
| +
|
| +func (u *userImpl) LoginURL(dest string) (string, error) {
|
| + return "https://fakeapp.example.com/_ah/login?redirect=" + url.QueryEscape(dest), nil
|
| +}
|
| +
|
| +func (u *userImpl) LogoutURL(dest string) (string, error) {
|
| + return "https://fakeapp.example.com/_ah/logout?redirect=" + url.QueryEscape(dest), nil
|
| +}
|
| +
|
| +func (u *userImpl) LoginURLFederated(dest, identity string) (string, error) {
|
| + return "", fmt.Errorf("LoginURLFederated is deprecated")
|
| +}
|
| +
|
| +func (u *userImpl) OAuthConsumerKey() (string, error) {
|
| + return "", fmt.Errorf("OAuthConsumerKey is deprecated")
|
| +}
|
| +
|
| +func (u *userImpl) Testable() user.Testable {
|
| + 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, clientID string, admin bool) {
|
| + parts := strings.Split(email, "@")
|
| + if len(parts) != 2 {
|
| + panic(fmt.Errorf("%q doesn't seem to be a valid email", email))
|
| + }
|
| +
|
| + id := sha256.Sum256([]byte("ID:" + email))
|
| +
|
| + u.SetUser(&user.User{
|
| + Email: email,
|
| + AuthDomain: parts[1],
|
| + Admin: admin,
|
| +
|
| + ID: fmt.Sprint(binary.LittleEndian.Uint64(id[:])),
|
| + ClientID: clientID,
|
| + })
|
| +}
|
| +
|
| +func (u *userImpl) Logout() {
|
| + u.SetUser(nil)
|
| +}
|
|
|