-
Notifications
You must be signed in to change notification settings - Fork 1
/
bulma.go
94 lines (77 loc) · 2.34 KB
/
bulma.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright 2017 The Bulma Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package bulma provides HTTP Basic Auth.
package bulma
import (
"net/http"
)
// Realm is the authenticate message to require authorization.
// See RFC 2617, section 1.2.
var Realm = "Authorization Required"
// Config is used to configure the basic auth handler.
type Config struct {
// Realm Default is "Authorization Required"
// See RFC 2617, section 1.2.
Realm string
// Validator is the interface indicating the type implementing it
// supports credentials validation.
Validator Validator
// Success will be used if the authentication succeeded.
Success http.Handler
// Error will be used if authentication fails.
Error http.Handler
}
type basicAuth struct {
config *Config
}
// New returns an http handler from a given configuration.
func New(c *Config) http.Handler {
if c.Realm == "" {
c.Realm = Realm
}
return &basicAuth{c}
}
func (b *basicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) {
username, password, ok := r.BasicAuth()
credential := Credential{
Username: username,
Password: password,
Authorization: ok,
}
var next http.Handler
if b.config.Validator != nil && b.config.Validator.Validate(&credential) {
next = b.config.Success
} else if b.config.Error != nil {
next = err(b.config.Realm, b.config.Error)
} else {
next = require(b.config.Realm)
}
next.ServeHTTP(w, r)
}
// BasicAuth is a simple wrapper of New.
func BasicAuth(realm string, success http.Handler, v Validator) http.Handler {
return New(&Config{
Realm: realm,
Success: success,
Validator: v,
})
}
// require returns a Handler that authenticates user.
func require(realm string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
writeHeader(w, realm)
w.Write([]byte(http.StatusText(http.StatusUnauthorized)))
})
}
// writeHeader replies to the request with the authentication header.
func writeHeader(w http.ResponseWriter, realm string) {
w.Header().Add("WWW-Authenticate", `Basic realm="`+realm+`"`)
w.WriteHeader(http.StatusUnauthorized)
}
func err(realm string, h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
writeHeader(w, realm)
h.ServeHTTP(w, r)
})
}