Fix go vet and lint issues

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
Derek McGowan 2015-04-10 16:52:33 -07:00
parent 36d8ce0094
commit 6fd6773b21
6 changed files with 130 additions and 29 deletions

View File

@ -15,8 +15,11 @@ import (
"github.com/gorilla/mux"
)
const ADDR = ":4443"
const DEBUG_ADDR = "localhost:8080"
// ServerAddress is the secure server address to listen on
const ServerAddress = ":4443"
// DebugAddress is the debug server address to listen on
const DebugAddress = "localhost:8080"
var debug bool
var certFile, keyFile string
@ -31,8 +34,8 @@ func main() {
flag.Usage = usage
flag.Parse()
if DEBUG_ADDR != "" {
go debugServer(DEBUG_ADDR)
if DebugAddress != "" {
go debugServer(DebugAddress)
}
if certFile == "" || keyFile == "" {
@ -65,13 +68,13 @@ func main() {
r.Methods("POST").Path("/{imageName}/{tag}").Handler(hand(handlers.AddHandler, utils.SSUpdate))
server := http.Server{
Addr: ADDR,
Addr: ServerAddress,
Handler: r,
TLSConfig: tlsConfig,
}
if debug {
log.Println("[Vetinari Server] : Listening on", ADDR)
log.Println("[Vetinari Server] : Listening on", ServerAddress)
}
err := server.ListenAndServeTLS(certFile, keyFile)
@ -81,7 +84,7 @@ func main() {
}
func usage() {
log.Println(os.Stderr, "usage:", os.Args[0], "<config>")
log.Println("usage:", os.Args[0], "<config>")
flag.PrintDefaults()
}

View File

@ -4,6 +4,8 @@ import (
"fmt"
)
// HTTPError represents an application error which will map to
// an HTTP status code and returned error object.
type HTTPError struct {
HTTPStatus int
Code int

View File

@ -16,6 +16,7 @@ import (
var db = util.GetSqliteDB()
// MainHandler is the default handler for the server
func MainHandler(ctx utils.IContext, w http.ResponseWriter, r *http.Request) *errors.HTTPError {
if r.Method == "GET" {
err := json.NewEncoder(w).Encode("{}")
@ -24,7 +25,11 @@ func MainHandler(ctx utils.IContext, w http.ResponseWriter, r *http.Request) *er
}
} else {
w.WriteHeader(http.StatusNotFound)
return &errors.HTTPError{http.StatusNotFound, 9999, nil}
return &errors.HTTPError{
HTTPStatus: http.StatusNotFound,
Code: 9999,
Err: nil,
}
}
return nil
}
@ -40,32 +45,56 @@ func AddHandler(ctx utils.IContext, w http.ResponseWriter, r *http.Request) *err
err := decoder.Decode(&meta)
defer r.Body.Close()
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
// add to targets
local.AddBlob(vars["tag"], meta)
tufRepo, err := repo.NewRepo(local, "sha256", "sha512")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
_ = tufRepo.Init(true)
err = tufRepo.AddTarget(vars["tag"], json.RawMessage{})
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
err = tufRepo.Sign("targets.json")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
tufRepo.Snapshot(repo.CompressionTypeNone)
err = tufRepo.Sign("snapshot.json")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
tufRepo.Timestamp()
err = tufRepo.Sign("timestamp.json")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
return nil
}
@ -79,23 +108,39 @@ func RemoveHandler(ctx utils.IContext, w http.ResponseWriter, r *http.Request) *
local.RemoveBlob(vars["tag"])
tufRepo, err := repo.NewRepo(local, "sha256", "sha512")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
_ = tufRepo.Init(true)
tufRepo.RemoveTarget(vars["tag"])
err = tufRepo.Sign("targets.json")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
tufRepo.Snapshot(repo.CompressionTypeNone)
err = tufRepo.Sign("snapshot.json")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
tufRepo.Timestamp()
err = tufRepo.Sign("timestamp.json")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
return nil
}
@ -109,12 +154,17 @@ func GetHandler(ctx utils.IContext, w http.ResponseWriter, r *http.Request) *err
meta, err := local.GetMeta()
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
w.Write(meta[vars["tufFile"]])
return nil
}
// GenKeysHandler is the handler for generate keys endpoint
func GenKeysHandler(ctx utils.IContext, w http.ResponseWriter, r *http.Request) *errors.HTTPError {
log.Printf("GenKeysHandler")
// remove tag from tagets list
@ -122,7 +172,11 @@ func GenKeysHandler(ctx utils.IContext, w http.ResponseWriter, r *http.Request)
local := store.DBStore(db, vars["imageName"])
tufRepo, err := repo.NewRepo(local, "sha256", "sha512")
if err != nil {
return &errors.HTTPError{http.StatusInternalServerError, 9999, err}
return &errors.HTTPError{
HTTPStatus: http.StatusInternalServerError,
Code: 9999,
Err: err,
}
}
tufRepo.GenKey("root")
tufRepo.GenKey("targets")

View File

@ -1,10 +1,12 @@
package utils
// IScope is an identifier scope
type IScope interface {
ID() string
Compare(IScope) bool
}
// IAuthorizer is an interfaces to authorize a scope
type IAuthorizer interface {
// Authorize is expected to set the Authorization on the Context. If
// Authorization fails, an error should be returned, but additionally,
@ -13,6 +15,8 @@ type IAuthorizer interface {
Authorize(IContext, ...IScope) error
}
// IAuthorization is an interface to determine whether
// an object has a scope
type IAuthorization interface {
HasScope(IScope) bool
}
@ -21,46 +25,66 @@ type IAuthorization interface {
// THESE ARE FOR DEV PURPOSES ONLY, DO NOT USE IN
// PRODUCTION
// DON'T USE THIS FOR ANYTHING, IT'S VERY INSECURE
// InsecureAuthorizer is an insecure implementation of IAuthorizer.
// WARNING: DON'T USE THIS FOR ANYTHING, IT'S VERY INSECURE
type InsecureAuthorizer struct{}
// LIKE I SAID, VERY INSECURE
// Authorize authorizes any scope
// WARNING: LIKE I SAID, VERY INSECURE
func (auth *InsecureAuthorizer) Authorize(ctx IContext, scopes ...IScope) error {
ctx.SetAuthorization(&InsecureAuthorization{})
return nil
}
// ALSO DON'T USE THIS, IT'S ALSO VERY INSECURE
// InsecureAuthorization is an implementation of IAuthorization
// which will consider any scope authorized.
// WARNING: ALSO DON'T USE THIS, IT'S ALSO VERY INSECURE
type InsecureAuthorization struct {
}
// THIS IS JUST INCREDIBLY INSECURE
// HasScope always returns true for any scope
// WARNING: THIS IS JUST INCREDIBLY INSECURE
func (authzn *InsecureAuthorization) HasScope(scope IScope) bool {
return true
}
// ### END INSECURE AUTHORIZATION TOOLS ###
// NoAuthorization is an implementation of IAuthorization
// which never allows a scope to be valid.
type NoAuthorization struct{}
// HasScope returns false for any scope
func (authzn *NoAuthorization) HasScope(scope IScope) bool {
return false
}
// SimpleScope is a simple scope represented by a string.
type SimpleScope string
// ID returns the string representing the scope.
func (ss SimpleScope) ID() string {
return string(ss)
}
// Compare compares to the given scope for equality.
func (ss SimpleScope) Compare(toCompare IScope) bool {
return ss.ID() == toCompare.ID()
}
const (
// SSNoAuth is the simple scope "NoAuth"
SSNoAuth SimpleScope = SimpleScope("NoAuth")
SSCreate = SimpleScope("Create")
SSRead = SimpleScope("Read")
SSUpdate = SimpleScope("Update")
SSDelete = SimpleScope("Delete")
// SSCreate is the simple scope "Create"
SSCreate = SimpleScope("Create")
// SSRead is the simple scope "Read"
SSRead = SimpleScope("Read")
// SSUpdate is the simple scope "Update"
SSUpdate = SimpleScope("Update")
// SSDelete is the simple scope "Delete"
SSDelete = SimpleScope("Delete")
)

View File

@ -4,6 +4,7 @@ import (
"net/http"
)
// IContext defines an interface for managing authorizations.
type IContext interface {
// TODO: define a set of standard getters. Using getters
// will allow us to easily and transparently cache
@ -24,27 +25,36 @@ type IContext interface {
SetAuthorization(IAuthorization)
}
// IContextFactory creates a IContext from an http request.
type IContextFactory func(*http.Request) IContext
// Context represents an authorization context for a resource.
type Context struct {
resource string
authorization IAuthorization
}
// ContextFactory creates a new authorization context with the
// given HTTP request path as the resource.
func ContextFactory(r *http.Request) IContext {
return &Context{
resource: r.URL.Path,
}
}
// Resource returns the resource value for the context.
func (ctx *Context) Resource() string {
return ctx.resource
}
// Authorization returns an IAuthorization implementation for
// the context.
func (ctx *Context) Authorization() IAuthorization {
return ctx.authorization
}
// SetAuthorization allows setting an IAuthorization for
// the context.
func (ctx *Context) SetAuthorization(authzn IAuthorization) {
ctx.authorization = authzn
}

View File

@ -1,4 +1,3 @@
// http.go contains useful http utilities.
package utils
import (
@ -7,8 +6,12 @@ import (
"github.com/docker/vetinari/errors"
)
// BetterHandler defines an alterate HTTP handler interface which takes in
// a context for authorization and returns an HTTP application error.
type BetterHandler func(ctx IContext, w http.ResponseWriter, r *http.Request) *errors.HTTPError
// RootHandler is an implementation of an HTTP request handler which handles
// authorization and calling out to the defined alternate http handler.
type RootHandler struct {
handler BetterHandler
auth IAuthorizer
@ -16,12 +19,17 @@ type RootHandler struct {
context IContextFactory
}
// RootHandlerFactory creates a new RootHandler factory using the given
// Context creator and authorizer. The returned factory allows creating
// new RootHandlers from the alternate http handler BetterHandler and
// a scope.
func RootHandlerFactory(auth IAuthorizer, ctxFac IContextFactory) func(BetterHandler, ...IScope) *RootHandler {
return func(handler BetterHandler, scopes ...IScope) *RootHandler {
return &RootHandler{handler, auth, scopes, ctxFac}
}
}
// ServeHTTP serves an HTTP request and implements the http.Handler interface.
func (root *RootHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
ctx := root.context(r)
if err := root.auth.Authorize(ctx, root.scopes...); err != nil {