grim/hgkeeper

8098dd6d3587
move KeysDir to a private variable in users.go
package access
import (
"io"
"os"
"path/filepath"
"sync"
"github.com/go-yaml/yaml"
log "github.com/sirupsen/logrus"
_ "golang.org/x/crypto/ssh"
)
const (
// AccessFile is the base name of an access control file.
AccessFile = "access.yml"
)
const (
// Public is a reserved hgkeeper name and is not valid in the patterns
// or keys of an access file.
Public = "public"
)
var publicBytes = []byte(Public)
type (
groups map[string][]string
permissions [numPerms][]string
)
// Access represents a parsed access file.
type Access struct {
lock sync.RWMutex
repoPath string
Global Acl
groups map[string][]string
patterns map[string]Acl
// index ssh key fingerprint to users
fingerprintIndex map[string]string
}
func New(adminRepo string) *Access {
return &Access{
repoPath: adminRepo,
groups: map[string][]string{},
patterns: map[string]Acl{},
fingerprintIndex: map[string]string{},
}
}
func (a *Access) Reload() error {
path := filepath.Join(a.repoPath, AccessFile)
reader, err := os.Open(path)
if err != nil {
return err
}
defer reader.Close()
return a.load(reader)
}
// loadFile reads the config from r into the basic structure.
func (a *Access) loadFile(r io.Reader) error {
data := file{}
if err := yaml.NewDecoder(r).Decode(&data); err != nil {
return err
}
a.Global = data.Global
a.groups = data.Groups
a.patterns = data.Patterns
return nil
}
func (a *Access) findUsers() []string {
users := map[string]bool{}
for _, name := range a.Global.Users() {
// don't add groups to the users list
if _, found := a.groups[name]; found {
continue
}
users[name] = true
}
for _, groupUsers := range a.groups {
for _, name := range groupUsers {
// don't add groups to the users list
if _, found := a.groups[name]; found {
continue
}
users[name] = true
}
}
for _, acl := range a.patterns {
for _, name := range acl.Users() {
// don't add groups to the users list
if _, found := a.groups[name]; found {
continue
}
users[name] = true
}
}
slice := make([]string, len(users))
idx := 0
for name, _ := range users {
slice[idx] = name
idx++
}
return slice
}
// load will load the access from file and reindex everything.
func (a *Access) load(r io.Reader) error {
a.lock.Lock()
defer a.lock.Unlock()
if err := a.loadFile(r); err != nil {
return err
}
users := a.findUsers()
a.loadSshKeys(users)
log.Infof("keys: %#v", a.fingerprintIndex)
return nil
}