Commit 7fec26e6 authored by ale's avatar ale

Allow enabling keystore on a group basis

Using the new configuration variable 'keystore_enable_groups'.
parent bad3b6bd
Pipeline #1568 passed with stages
in 1 minute and 29 seconds
......@@ -38,6 +38,7 @@ type Config struct {
URLPrefix string `yaml:"url_path_prefix"`
DeviceManager *device.Config `yaml:"device_manager"`
KeyStore *clientutil.BackendConfig `yaml:"keystore"`
KeyStoreEnableGroups []string `yaml:"keystore_enable_groups"`
allowedServicesRx []*regexp.Regexp
}
......
......@@ -4,6 +4,7 @@ package server
//go:generate go-bindata --nocompress --pkg server static/... templates/...
import (
"context"
"encoding/gob"
"encoding/json"
"fmt"
......@@ -88,6 +89,7 @@ type Server struct {
loginHandler *loginHandler
loginService *LoginService
keystore ksclient.Client
keystoreGroups []string
csrfSecret []byte
tpl *template.Template
urlPrefix string
......@@ -134,6 +136,7 @@ func New(loginService *LoginService, authClient authclient.Client, config *Confi
}
log.Printf("keystore client enabled")
s.keystore = ks
s.keystoreGroups = config.KeyStoreEnableGroups
}
devMgr, err := device.New(config.DeviceManager)
......@@ -145,25 +148,51 @@ func New(loginService *LoginService, authClient authclient.Client, config *Confi
return s, nil
}
func inAnyGroups(groups, ref []string) bool {
for _, rr := range ref {
for _, gg := range groups {
if gg == rr {
return true
}
}
}
return false
}
// We unlock the keystore if the following conditions are met:
// keystore_enable_groups is set, userinfo is not nil, and the groups match.
func (h *Server) maybeUnlockKeystore(ctx context.Context, username, password string, userinfo *auth.UserInfo) (bool, error) {
if h.keystore == nil {
return false, nil
}
var shard string
if len(h.keystoreGroups) > 0 {
if userinfo == nil {
return false, nil
}
if !inAnyGroups(userinfo.Groups, h.keystoreGroups) {
return false, nil
}
shard = userinfo.Shard
}
return true, h.keystore.Open(ctx, shard, username, password, int(h.authSessionLifetime.Seconds()))
}
func (h *Server) loginCallback(w http.ResponseWriter, req *http.Request, username, password string, userinfo *auth.UserInfo) error {
// Open the keystore for this user with the password used to
// authenticate. Set the TTL to the duration of the
// authenticated session.
var kmsg string
if h.keystore != nil {
var shard string
if userinfo != nil {
shard = userinfo.Shard
kmsg = fmt.Sprintf(" (unlocked key on shard %s)", shard)
} else {
kmsg = " (unlocked key)"
}
if err := h.keystore.Open(req.Context(), shard, username, password, int(h.authSessionLifetime.Seconds())); err != nil {
log.Printf("failed to unlock keystore for user %s: %v", username, err)
return err
}
decrypted, err := h.maybeUnlockKeystore(req.Context(), username, password, userinfo)
if err != nil {
log.Printf("failed to unlock keystore for user %s: %v", username, err)
return err
}
var kmsg string
if decrypted {
kmsg = " (key unlocked)"
}
log.Printf("successful login for user %s%s", username, kmsg)
// Create cookie-based session for the authenticated user.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment