зеркало из https://github.com/github/vitess-gh.git
96 строки
2.8 KiB
Go
96 строки
2.8 KiB
Go
// Copyright 2012, Google Inc. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Package acl contains functions to enforce access control lists.
|
|
// It allows you to register multiple security policies for enforcing
|
|
// ACLs for users or HTTP requests. The specific policy to use must be
|
|
// specified from a command line argument and cannot be changed on-the-fly.
|
|
package acl
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"net/http"
|
|
"sync"
|
|
|
|
log "github.com/golang/glog"
|
|
)
|
|
|
|
// This is a list of predefined roles. Applications are free
|
|
// to invent more roles, as long as the acl policies they use can
|
|
// understand what they mean.
|
|
const (
|
|
ADMIN = "admin"
|
|
DEBUGGING = "debugging"
|
|
MONITORING = "monitoring"
|
|
)
|
|
|
|
var (
|
|
securityPolicy = flag.String("security_policy", "", "security policy to enforce for URLs")
|
|
policies = make(map[string]Policy)
|
|
once sync.Once
|
|
currentPolicy Policy
|
|
)
|
|
|
|
// Policy defines the interface that needs to be satisfied by
|
|
// ACL policy implementors.
|
|
type Policy interface {
|
|
// CheckAccessActor can be called to verify if an actor
|
|
// has access to the role.
|
|
CheckAccessActor(actor, role string) error
|
|
// CheckAccessHTTP can be called to verify if an actor in
|
|
// the http request has access to the role.
|
|
CheckAccessHTTP(req *http.Request, role string) error
|
|
}
|
|
|
|
// RegisterPolicy registers a security policy. This function must be called
|
|
// before the first call to CheckAccess happens, preferably through an init.
|
|
// This will ensure that the requested policy can be found by other acl
|
|
// functions when needed.
|
|
func RegisterPolicy(name string, policy Policy) {
|
|
if _, ok := policies[name]; ok {
|
|
log.Fatalf("policy %s is already registered", name)
|
|
}
|
|
policies[name] = policy
|
|
}
|
|
|
|
func savePolicy() {
|
|
if *securityPolicy == "" {
|
|
return
|
|
}
|
|
currentPolicy = policies[*securityPolicy]
|
|
if currentPolicy == nil {
|
|
log.Warningf("policy %s not found, using fallback policy", *securityPolicy)
|
|
currentPolicy = FallbackPolicy{}
|
|
}
|
|
}
|
|
|
|
// CheckAccessActor uses the current security policy to
|
|
// verify if an actor has access to the role.
|
|
func CheckAccessActor(actor, role string) error {
|
|
once.Do(savePolicy)
|
|
if currentPolicy != nil {
|
|
return currentPolicy.CheckAccessActor(actor, role)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// CheckAccessHTTP uses the current security policy to
|
|
// verify if an actor in an http request has access to
|
|
// the role.
|
|
func CheckAccessHTTP(req *http.Request, role string) error {
|
|
once.Do(savePolicy)
|
|
if currentPolicy != nil {
|
|
return currentPolicy.CheckAccessHTTP(req, role)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// SendError is a convenience function that sends an ACL
|
|
// error as an HTTP response.
|
|
func SendError(w http.ResponseWriter, err error) {
|
|
w.WriteHeader(http.StatusForbidden)
|
|
fmt.Fprintf(w, "Access denied: %v\n", err)
|
|
}
|