1
0
Fork 0

Create standalone auth module

master
Philip O'Toole 9 years ago
parent f8bf802641
commit 4c36f8345c

@ -1,4 +1,4 @@
package http
package auth
import (
"encoding/json"

@ -1,4 +1,4 @@
package http
package auth
import (
"strings"

@ -23,6 +23,7 @@ import (
"runtime/pprof"
"strings"
"github.com/otoolep/rqlite/auth"
sql "github.com/otoolep/rqlite/db"
httpd "github.com/otoolep/rqlite/http"
"github.com/otoolep/rqlite/store"
@ -155,11 +156,23 @@ func main() {
log.Println("successfully joined node at", joinAddr)
}
// Load authentication information, if supplied.
var credentialStore *auth.CredentialsStore
if authFile != "" {
f, err := os.Open(authFile)
if err != nil {
log.Fatalf("failed to open authentication file %s: %s", authFile, err.Error())
}
credentialStore = auth.NewCredentialsStore()
if err := credentialStore.Load(f); err != nil {
log.Fatalf("failed to load authentication file: %s", err.Error())
}
}
// Create the HTTP query server.
s := httpd.New(httpAddr, store)
s := httpd.New(httpAddr, store, credentialStore)
s.CertFile = x509Cert
s.KeyFile = x509Key
s.AuthFile = authFile
s.DisableRedirect = disRedirect
s.Expvar = expvar
s.Version = version

@ -46,6 +46,12 @@ type Store interface {
Backup(leader bool) ([]byte, error)
}
type CredentialStore interface {
Check(username, password string) bool
HasPerm(username string, perm string) bool
}
// Response represents a response from the HTTP service.
type Response struct {
Results interface{} `json:"results,omitempty"`
@ -105,8 +111,7 @@ type Service struct {
CertFile string // Path to SSL certificate.
KeyFile string // Path to SSL private key.
AuthFile string // Path to basic auth credentials
credentialStore *CredentialsStore
credentialStore CredentialStore
Expvar bool
DisableRedirect bool // Disable leader-redirection.
@ -118,12 +123,13 @@ type Service struct {
}
// New returns an uninitialized HTTP service.
func New(addr string, store Store) *Service {
func New(addr string, store Store, credentials CredentialStore) *Service {
return &Service{
addr: addr,
store: store,
start: time.Now(),
logger: log.New(os.Stderr, "[http] ", log.LstdFlags),
addr: addr,
store: store,
start: time.Now(),
credentialStore: credentials,
logger: log.New(os.Stderr, "[http] ", log.LstdFlags),
}
}
@ -133,19 +139,6 @@ func (s *Service) Start() error {
Handler: s,
}
// Enable auth if requested.
if s.AuthFile != "" {
f, err := os.Open(s.AuthFile)
if err != nil {
return err
}
s.credentialStore = NewCredentialsStore()
if err := s.credentialStore.Load(f); err != nil {
return err
}
s.logger.Println("authentication configuration loaded from", s.AuthFile)
}
var ln net.Listener
var err error
if s.CertFile == "" || s.KeyFile == "" {
@ -186,7 +179,8 @@ func (s *Service) Close() {
// ServeHTTP allows Service to serve HTTP requests.
func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if s.credentialStore != nil {
if ok := s.credentialStore.CheckRequest(r); !ok {
username, password, ok := r.BasicAuth()
if !ok || !s.credentialStore.Check(username, password) {
w.WriteHeader(http.StatusUnauthorized)
return
}
@ -476,7 +470,11 @@ func (s *Service) CheckRequestPerm(r *http.Request, perm string) bool {
return true
}
return s.credentialStore.HasPermRequest(r, PermAll) || s.credentialStore.HasPermRequest(r, perm)
username, _, ok := r.BasicAuth()
if !ok {
return false
}
return s.credentialStore.HasPerm(username, PermAll) || s.credentialStore.HasPerm(username, perm)
}
// serveExpvar serves registered expvar information over HTTP.

@ -11,7 +11,7 @@ import (
func Test_NewService(t *testing.T) {
m := &MockStore{}
s := New("127.0.0.1:0", m)
s := New("127.0.0.1:0", m, nil)
if s == nil {
t.Fatalf("failed to create new service")
}
@ -19,7 +19,7 @@ func Test_NewService(t *testing.T) {
func Test_404Routes(t *testing.T) {
m := &MockStore{}
s := New("127.0.0.1:0", m)
s := New("127.0.0.1:0", m, nil)
if err := s.Start(); err != nil {
t.Fatalf("failed to start service")
}
@ -47,7 +47,7 @@ func Test_404Routes(t *testing.T) {
func Test_405Routes(t *testing.T) {
m := &MockStore{}
s := New("127.0.0.1:0", m)
s := New("127.0.0.1:0", m, nil)
if err := s.Start(); err != nil {
t.Fatalf("failed to start service")
}

Loading…
Cancel
Save