diff --git a/cmd/litcli/sessions.go b/cmd/litcli/sessions.go index e6d1c8f2b..667df3b6a 100644 --- a/cmd/litcli/sessions.go +++ b/cmd/litcli/sessions.go @@ -69,7 +69,7 @@ var addSessionCommand = cli.Command{ Usage: "The session type to be created which will " + "determine the permissions a user has when " + "connecting with the session; options " + - "include readonly|admin|account|custom.", + "include readonly|admin|custom.", Value: "readonly", }, cli.StringSliceFlag{ @@ -87,10 +87,8 @@ var addSessionCommand = cli.Command{ }, cli.StringFlag{ Name: "account_id", - Usage: "The account id that should be used for " + - "the account session. Note that this flag " + - "will only be used if the 'type' flag is " + - "set to 'account'.", + Usage: "An optional account ID to restrict the " + + "session macaroon to a specific account.", }, }, } @@ -146,8 +144,6 @@ func parseSessionType(sessionType string) (litrpc.SessionType, error) { return litrpc.SessionType_TYPE_MACAROON_ADMIN, nil case "readonly": return litrpc.SessionType_TYPE_MACAROON_READONLY, nil - case "account": - return litrpc.SessionType_TYPE_MACAROON_ACCOUNT, nil case "custom": return litrpc.SessionType_TYPE_MACAROON_CUSTOM, nil default: diff --git a/session_rpcserver.go b/session_rpcserver.go index 083852ee4..0cfed4b94 100644 --- a/session_rpcserver.go +++ b/session_rpcserver.go @@ -314,17 +314,13 @@ func (s *sessionRpcServer) AddSession(ctx context.Context, // the macaroons are baked correctly when creating the session. case session.TypeMacaroonAdmin, session.TypeMacaroonReadonly: - // For account based sessions we just add the account ID caveat, the - // permissions are added dynamically when creating the session. + // For account based sessions we require an account ID to be set. case session.TypeMacaroonAccount: - id, err := accounts.ParseAccountID(req.AccountId) - if err != nil { - return nil, fmt.Errorf("invalid account ID: %v", err) + if req.AccountId == "" { + return nil, fmt.Errorf("account_id must be set for " + + "the account session type") } - caveats = append(caveats, accounts.CaveatFromID(*id)) - accountID = fn.Some(*id) - // For the custom macaroon type, we use the custom permissions specified // in the request. For the time being, the caveats list will be empty // for this type. @@ -389,6 +385,18 @@ func (s *sessionRpcServer) AddSession(ctx context.Context, "using AddAutoPilotSession method") } + // If an account ID was provided, bind the macaroon to that account + // regardless of session type. + if req.AccountId != "" { + id, err := accounts.ParseAccountID(req.AccountId) + if err != nil { + return nil, fmt.Errorf("invalid account ID: %v", err) + } + + caveats = append(caveats, accounts.CaveatFromID(*id)) + accountID = fn.Some(*id) + } + // Collect the de-duped permissions. var uniquePermissions []bakery.Op for entity, actions := range permissions { @@ -473,8 +481,9 @@ func (s *sessionRpcServer) resumeSession(ctx context.Context, readOnly = sess.Type == session.TypeMacaroonReadonly ) switch sess.Type { - // For the default session types we use empty caveats and permissions, - // the macaroons are baked correctly when creating the session. + // For the default session types, permissions are baked correctly when + // creating the session. Any stored caveats (e.g. account binding) are + // applied below after the switch. case session.TypeMacaroonAdmin, session.TypeMacaroonReadonly: permissions = s.cfg.permMgr.ActivePermissions(readOnly) @@ -486,19 +495,15 @@ func (s *sessionRpcServer) resumeSession(ctx context.Context, "recipe to be set") } - caveats = sess.MacaroonRecipe.Caveats permissions = accounts.MacaroonPermissions // For custom session types, we use the caveats and permissions that // were persisted on session creation. case session.TypeMacaroonCustom, session.TypeAutopilot: - if sess.MacaroonRecipe == nil { - break + if sess.MacaroonRecipe != nil { + permissions = sess.MacaroonRecipe.Permissions } - permissions = sess.MacaroonRecipe.Permissions - caveats = append(caveats, sess.MacaroonRecipe.Caveats...) - // No other types are currently supported. default: log.Debugf("Not resuming session %x with type %d", pubKeyBytes, @@ -506,6 +511,11 @@ func (s *sessionRpcServer) resumeSession(ctx context.Context, return nil } + // Apply any stored caveats (e.g. account binding) for all session types. + if sess.MacaroonRecipe != nil { + caveats = append(caveats, sess.MacaroonRecipe.Caveats...) + } + // Add the session expiry as a macaroon caveat. macExpiry := checkers.TimeBeforeCaveat(sess.Expiry) caveats = append(caveats, macaroon.Caveat{