migrate users, add role per user

This commit is contained in:
Sasha Klizhentas 2016-12-16 11:25:17 -08:00
parent 4ce3a7992c
commit cedacb92aa
4 changed files with 88 additions and 11 deletions

View file

@ -255,6 +255,23 @@ func Init(cfg InitConfig, seedConfig bool) (*AuthServer, *Identity, error) {
}
}
// migrate old users to new users
users, err := asrv.GetUsers()
for _, user := range users {
_, err := asrv.GetRole(services.RoleNameForUser(user.GetName()))
if err == nil {
continue
}
if !trace.IsNotFound(err) {
return nil, nil, trace.Wrap(err)
}
log.Infof("migrating legacy user %v", user.GetName())
err = asrv.UpsertRole(services.RoleForUser(user))
if err != nil {
return nil, nil, trace.Wrap(err)
}
}
identity, err := initKeys(asrv, cfg.DataDir,
IdentityID{HostUUID: cfg.HostUUID, Role: teleport.RoleAdmin})
if err != nil {

View file

@ -140,7 +140,7 @@ func (s *AuthServer) CreateSignupU2FRegisterRequest(token string) (u2fRegisterRe
return nil, trace.Wrap(err)
}
lock := "signuptoken"+token
lock := "signuptoken" + token
err = s.AcquireLock(lock, time.Hour)
if err != nil {
@ -216,6 +216,11 @@ func (s *AuthServer) CreateUserWithToken(token, password, hotpToken string) (*Se
}
// apply user allowed logins
if err := s.UpsertRole(services.RoleForUser(&tokenData.User)); err != nil {
return nil, trace.Wrap(err)
}
// Allowed logins are not going to be used anymore
tokenData.User.AllowedLogins = nil
if err = s.UpsertUser(&tokenData.User); err != nil {
return nil, trace.Wrap(err)
}
@ -251,7 +256,7 @@ func (s *AuthServer) CreateUserWithU2FToken(token string, password string, respo
return nil, trace.Wrap(err)
}
lock := "signuptoken"+token
lock := "signuptoken" + token
err = s.AcquireLock(lock, time.Hour)
if err != nil {
@ -294,8 +299,11 @@ func (s *AuthServer) CreateUserWithU2FToken(token string, password string, respo
if err != nil {
return nil, trace.Wrap(err)
}
// apply user allowed logins
if err := s.UpsertRole(services.RoleForUser(&tokenData.User)); err != nil {
return nil, trace.Wrap(err)
}
// Allowed logins are not going to be used anymore
tokenData.User.AllowedLogins = nil
if err = s.UpsertUser(&tokenData.User); err != nil {
return nil, trace.Wrap(err)
}
@ -319,3 +327,17 @@ func (s *AuthServer) CreateUserWithU2FToken(token string, password string, respo
sess.WS.Priv = nil
return sess, nil
}
func (a *AuthServer) DeleteUser(user string) error {
role, err := a.Access.GetRole(services.RoleNameForUser(user))
if err != nil {
if !trace.IsNotFound(err) {
return trace.Wrap(err)
}
} else {
if err := a.Access.DeleteRole(role.GetMetadata().Name); err != nil {
return trace.Wrap(err)
}
}
return a.Identity.DeleteUser(user)
}

View file

@ -29,6 +29,28 @@ import (
"github.com/gravitational/trace"
)
// RoleForUser returns role name associated with user
func RoleNameForUser(name string) string {
return "user:" + name
}
// RoleForUser creates role using AllowedLogins parameter
func RoleForUser(u User) Role {
return &RoleResource{
Kind: KindRole,
Version: V1,
Metadata: Metadata{
Name: RoleNameForUser(u.GetName()),
Namespace: defaults.Namespace,
},
Spec: RoleSpec{
MaxSessionTTL: NewDuration(defaults.MaxCertDuration),
NodeLabels: map[string]string{Wildcard: Wildcard},
Namespaces: []string{defaults.Namespace},
},
}
}
// Access service manages roles and permissions
type Access interface {
// GetRoles returns a list of roles

View file

@ -94,8 +94,17 @@ type Config struct {
// Version is a current webapi version
const APIVersion = "v1"
type RewritingHandler struct {
http.Handler
handler *Handler
}
func (r *RewritingHandler) Close() error {
return r.handler.Close()
}
// NewHandler returns a new instance of web proxy handler
func NewHandler(cfg Config, opts ...HandlerOption) (*Handler, error) {
func NewHandler(cfg Config, opts ...HandlerOption) (*RewritingHandler, error) {
const apiPrefix = "/" + APIVersion
lauth, err := newSessionCache([]utils.NetAddr{cfg.AuthServers})
if err != nil {
@ -242,7 +251,15 @@ func NewHandler(cfg Config, opts ...HandlerOption) (*Handler, error) {
}
})
h.NotFound = routingHandler
return h, nil
return &RewritingHandler{
Handler: httplib.RewritePaths(h,
httplib.Rewrite("/webapi/sites/([^/]+)/sessions/(.*)", "/webapi/sites/$1/namespaces/default/sessions/$2/$3"),
httplib.Rewrite("/webapi/sites/([^/]+)/sessions", "/webapi/sites/$1/namespaces/default/sessions"),
httplib.Rewrite("/webapi/sites/([^/]+)/nodes", "/webapi/sites/$1/namespaces/default/nodes"),
httplib.Rewrite("/webapi/sites/([^/]+)/connect", "/webapi/sites/$1/namespaces/default/connect"),
),
handler: h,
}, nil
}
// Close closes associated session cache operations
@ -258,7 +275,7 @@ type oidcConnector struct {
type webSettings struct {
Auth struct {
OIDCConnectors []oidcConnector `json:"oidc_connectors"`
U2FAppID string `json:"u2f_appid"`
U2FAppID string `json:"u2f_appid"`
} `json:"auth"`
}
@ -594,7 +611,6 @@ func (m *Handler) renderUserInvite(w http.ResponseWriter, r *http.Request, p htt
}, nil
}
// u2fRegisterRequest is called to get a U2F challenge for registering a U2F key
//
// GET /webapi/u2f/signuptokens/:token
@ -645,7 +661,7 @@ func (m *Handler) u2fSignRequest(w http.ResponseWriter, r *http.Request, p httpr
// A request from the client to send the signature from the U2F key
type u2fSignResponseReq struct {
User string `json:"user"`
User string `json:"user"`
U2FSignResponse u2f.SignResponse `json:"u2f_sign_response"`
}
@ -717,8 +733,8 @@ func (m *Handler) createNewUser(w http.ResponseWriter, r *http.Request, p httpro
// A request to create a new user which uses U2F as the second factor
type createNewU2FUserReq struct {
InviteToken string `json:"invite_token"`
Pass string `json:"pass"`
InviteToken string `json:"invite_token"`
Pass string `json:"pass"`
U2FRegisterResponse u2f.RegisterResponse `json:"u2f_register_response"`
}