Chromium Code Reviews| Index: services/vanadium/security/principal_service.go |
| diff --git a/services/vanadium/security/principal_service.go b/services/vanadium/security/principal_service.go |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..98ef23a22c521b8d33c7f0fc537e3f7f895a9cf7 |
| --- /dev/null |
| +++ b/services/vanadium/security/principal_service.go |
| @@ -0,0 +1,127 @@ |
| +// 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 main |
| + |
| +import ( |
| + "fmt" |
| + "log" |
| + "sync" |
| + |
| + "mojo/public/go/application" |
| + "mojo/public/go/bindings" |
| + "mojo/public/go/system" |
| + auth "mojo/services/authentication/public/interfaces/authentication" |
| + "mojo/services/vanadium/security/public/interfaces/principal" |
| +) |
| + |
| +//#include "mojo/public/c/system/types.h" |
| +import "C" |
| + |
| +type PrincipalServiceImpl struct { |
| + app principal.AppInstanceName |
| + psd *PrincipalServiceDelegate |
| + } |
| + |
| +func (pImpl *PrincipalServiceImpl) Login() (b *principal.Blessing, err error) { |
| + authReq, authPtr := auth.CreateMessagePipeForAuthenticationService() |
| + pImpl.psd.Ctx.ConnectToApplication("mojo:authentication").ConnectToService(&authReq) |
| + authProxy := auth.NewAuthenticationServiceProxy(authPtr, bindings.GetAsyncWaiter()) |
| + name, errString, _ := authProxy.SelectAccount(false /*return_last_selected*/) |
| + if name != nil { |
| + cert := []principal.Certificate{principal.Certificate{Extension: *name}} |
|
ashankar
2015/08/19 05:50:38
What about the public key? It seems that we're ret
gautham
2015/08/19 17:45:51
Yes. Key management to follow.
|
| + b = &principal.Blessing{cert} |
| + pImpl.psd.AddUserBlessing(pImpl.app, b) |
| + } else { |
| + err = fmt.Errorf("Failed to authenticate user:%s", errString) |
| + } |
| + return |
| +} |
| + |
| +func (pImpl *PrincipalServiceImpl) Logout() (err error) { |
| + pImpl.psd.DeleteUserBlessing(pImpl.app) |
| + return |
| +} |
| + |
| +func (pImpl *PrincipalServiceImpl) GetUserBlessing(app principal.AppInstanceName) (*principal.Blessing, error) { |
| + b := pImpl.psd.GetUserBlessing(app) |
|
ashankar
2015/08/19 05:50:38
Optional:
return pImpl.psd.GetUserBlessing(app), n
gautham
2015/08/19 17:45:51
Done.
|
| + return b, nil |
| +} |
| + |
| +func (pImpl *PrincipalServiceImpl) Create(req principal.PrincipalService_Request) { |
| + stub := principal.NewPrincipalServiceStub(req, pImpl, bindings.GetAsyncWaiter()) |
| + pImpl.psd.AddStubForCleanup(stub) |
| + go func() { |
| + for { |
| + if err := stub.ServeRequest(); err != nil { |
| + connectionError, ok := err.(*bindings.ConnectionError) |
| + if !ok || !connectionError.Closed() { |
| + log.Println(err) |
| + } |
| + break |
| + } |
| + } |
| + }() |
| +} |
| + |
| +type PrincipalServiceDelegate struct { |
| + sync.Mutex |
|
ashankar
2015/08/19 05:50:38
Instead of embedding a Mutex I would recommend mak
gautham
2015/08/19 17:45:51
Done.
|
| + Ctx application.Context |
| + bMap map[principal.AppInstanceName]*principal.Blessing |
| + stubs []*bindings.Stub |
| +} |
| + |
| +func (psd *PrincipalServiceDelegate) Initialize(context application.Context) { |
| + psd.bMap = make(map[principal.AppInstanceName]*principal.Blessing) |
| + psd.Ctx = context |
| +} |
| + |
| +func (psd *PrincipalServiceDelegate) AcceptConnection(connection *application.Connection) { |
| + app := principal.AppInstanceName{ |
| + Url: connection.RequestorURL(), |
| + Qualifier: nil, |
| + } |
| + connection.ProvideServices(&principal.PrincipalService_ServiceFactory{&PrincipalServiceImpl{app, psd}}) |
|
ashankar
2015/08/19 05:50:38
gofmt?
gautham
2015/08/19 17:45:51
Done.
|
| +} |
| + |
| +func (psd *PrincipalServiceDelegate) AddStubForCleanup(stub *bindings.Stub) { |
| + psd.Lock() |
| + defer psd.Unlock() |
| + psd.stubs = append(psd.stubs, stub) |
| +} |
| + |
| +func (psd *PrincipalServiceDelegate) AddUserBlessing(app principal.AppInstanceName, b *principal.Blessing) { |
|
ashankar
2015/08/19 05:50:38
Do these methods need to be exported?
gautham
2015/08/19 17:45:51
Done.
|
| + psd.Lock() |
| + defer psd.Unlock() |
| + psd.bMap[app] = b |
| +} |
| + |
| +func (psd *PrincipalServiceDelegate) GetUserBlessing(app principal.AppInstanceName) *principal.Blessing { |
| + psd.Lock() |
| + defer psd.Unlock() |
| + return psd.bMap[app] |
| +} |
| + |
| +func (psd *PrincipalServiceDelegate) DeleteUserBlessing(app principal.AppInstanceName) { |
| + psd.Lock() |
| + defer psd.Unlock() |
| + delete(psd.bMap, app) |
| +} |
| + |
| +func (psd *PrincipalServiceDelegate) Quit() { |
| + psd.Lock() |
| + defer psd.Unlock() |
| + for _, stub := range psd.stubs { |
| + stub.Close() |
| + } |
| +} |
| + |
| +//export MojoMain |
| +func MojoMain(handle C.MojoHandle) C.MojoResult { |
| + application.Run(&PrincipalServiceDelegate{}, system.MojoHandle(handle)) |
| + return C.MOJO_RESULT_OK |
| +} |
| + |
| +func main() { |
| +} |