You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.5 KiB
Go
104 lines
2.5 KiB
Go
9 years ago
|
package auth
|
||
9 years ago
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"io"
|
||
|
)
|
||
|
|
||
9 years ago
|
// BasicAuther is the interface an object must support to return basic auth information.
|
||
9 years ago
|
type BasicAuther interface {
|
||
|
BasicAuth() (string, string, bool)
|
||
|
}
|
||
|
|
||
9 years ago
|
// Credential represents authentication and authorization configuration for a single user.
|
||
9 years ago
|
type Credential struct {
|
||
9 years ago
|
Username string `json:"username,omitempty"`
|
||
|
Password string `json:"password,omitempty"`
|
||
9 years ago
|
Perms []string `json:"perms,omitempty"`
|
||
9 years ago
|
}
|
||
|
|
||
9 years ago
|
// CredentialStore stores authentication and authorization information for all users.
|
||
9 years ago
|
type CredentialsStore struct {
|
||
|
store map[string]string
|
||
9 years ago
|
perms map[string]map[string]bool
|
||
9 years ago
|
}
|
||
|
|
||
9 years ago
|
// NewCredentialsStore returns a new instance of a CredentialStore.
|
||
9 years ago
|
func NewCredentialsStore() *CredentialsStore {
|
||
|
return &CredentialsStore{
|
||
|
store: make(map[string]string),
|
||
9 years ago
|
perms: make(map[string]map[string]bool),
|
||
9 years ago
|
}
|
||
|
}
|
||
|
|
||
9 years ago
|
// Load loads credential information from a reader.
|
||
9 years ago
|
func (c *CredentialsStore) Load(r io.Reader) error {
|
||
|
dec := json.NewDecoder(r)
|
||
|
// Read open bracket
|
||
|
_, err := dec.Token()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
var cred Credential
|
||
|
for dec.More() {
|
||
|
err := dec.Decode(&cred)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
c.store[cred.Username] = cred.Password
|
||
9 years ago
|
c.perms[cred.Username] = make(map[string]bool, len(cred.Perms))
|
||
|
for _, p := range cred.Perms {
|
||
|
c.perms[cred.Username][p] = true
|
||
|
}
|
||
9 years ago
|
}
|
||
|
|
||
|
// Read closing bracket
|
||
|
_, err = dec.Token()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
9 years ago
|
// Check returns true if the password is correct for the given username.
|
||
9 years ago
|
func (c *CredentialsStore) Check(username, password string) bool {
|
||
|
pw, ok := c.store[username]
|
||
|
return ok && password == pw
|
||
|
}
|
||
9 years ago
|
|
||
9 years ago
|
// CheckRequest returns true if b contains a valid username and password.
|
||
9 years ago
|
func (c *CredentialsStore) CheckRequest(b BasicAuther) bool {
|
||
|
username, password, ok := b.BasicAuth()
|
||
|
if !ok || !c.Check(username, password) {
|
||
|
return false
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
9 years ago
|
|
||
9 years ago
|
// HasPerm returns true if username has the given perm. It does not
|
||
|
// perform any password checking.
|
||
9 years ago
|
func (c *CredentialsStore) HasPerm(username string, perm string) bool {
|
||
|
m, ok := c.perms[username]
|
||
|
if !ok {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
if _, ok := m[perm]; !ok {
|
||
|
return false
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
9 years ago
|
|
||
|
// HasPermRequest returns true if username returned by b has the givem perm.
|
||
9 years ago
|
// It does not perform any password checking, but if there is no username
|
||
|
// in the request, it returns false.
|
||
9 years ago
|
func (c *CredentialsStore) HasPermRequest(b BasicAuther, perm string) bool {
|
||
|
username, _, ok := b.BasicAuth()
|
||
|
if !ok {
|
||
|
return false
|
||
|
}
|
||
|
return c.HasPerm(username, perm)
|
||
|
}
|