Skip to content

Commit

Permalink
BREAKING CHANGE: release v2 and drop support for v1
Browse files Browse the repository at this point in the history
* BREAKING CHANGE: redesign caching and replace store with cache pkg
* BREAKING CHANGE: drop tfa pkg -- deprecated
* BREAKING CHANGE: drop error pkg
* BREAKING CHANGE: drop beraer pkg -- deprecated
* chore: move internal pkg to auth/internal
* BREAKING CHANGE: change auth.info interface and add setters/getters
* chore: remove internal user
* feat: add auth.Extentions type
* BREAKING CHANGE: remove StrategyKey type
* BREAKING CHANGE: change append/revoke function signature
* BREAKING CHANGE: rename basic strategy Comparator.Verify to Comparator.Compare
* chore: strategies errors honor  "strategies/" prefix
* BREAKING CHANGE: rename two factor  strategy struct
* refactor: digest strategy and replace public fields with options
* docs: update docs
* BREAKING CHANGE: drop auth.authenticator and replace it with union strategy
* docs: update _examples
  • Loading branch information
shaj13 committed Oct 1, 2020
1 parent 710ff6e commit d23d38d
Show file tree
Hide file tree
Showing 86 changed files with 2,299 additions and 3,583 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@ Here are a few bullet point reasons you might like to try it out:
## Strategies
* [kubernetes (Token Review)](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/kubernetes?tab=doc)
* [2FA](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/twofactor?tab=doc)
* [Certificate-Based](https://pkg.go.dev/github.com/shaj13/[email protected]/auth/strategies/x509?tab=doc)
* [Bearer-Token](https://pkg.go.dev/github.com/shaj13/[email protected]/auth/strategies/bearer?tab=doc)
* [Static-Token](https://pkg.go.dev/github.com/shaj13/[email protected]/auth/strategies/bearer?tab=doc)
* [LDAP](https://pkg.go.dev/github.com/shaj13/[email protected]/auth/strategies/ldap?tab=doc)
* [Basic](https://pkg.go.dev/github.com/shaj13/[email protected]/auth/strategies/basic?tab=doc)
* [Digest](https://pkg.go.dev/github.com/shaj13/[email protected]/auth/strategies/digest?tab=doc)
* [Certificate-Based](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/x509?tab=doc)
* [Bearer-Token](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/token?tab=doc)
* [Static-Token](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/token?tab=doc)
* [LDAP](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/ldap?tab=doc)
* [Basic](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/basic?tab=doc)
* [Digest](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/digest?tab=doc)
* [Union](https://pkg.go.dev/github.com/shaj13/go-guardian/auth/strategies/union?tab=doc)

# Examples
Examples are available on [GoDoc](https://pkg.go.dev/github.com/shaj13/go-guardian) or [Examples Folder](./_examples).
Expand Down
39 changes: 21 additions & 18 deletions _examples/basic_bearer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ import (

"github.com/shaj13/go-guardian/auth"
"github.com/shaj13/go-guardian/auth/strategies/basic"
"github.com/shaj13/go-guardian/auth/strategies/bearer"
"github.com/shaj13/go-guardian/store"
"github.com/shaj13/go-guardian/auth/strategies/token"
"github.com/shaj13/go-guardian/auth/strategies/union"
"github.com/shaj13/go-guardian/cache"
"github.com/shaj13/go-guardian/cache/container/fifo"
)

// Usage:
// curl -k http://127.0.0.1:8080/v1/book/1449311601 -u admin:admin
// curl -k http://127.0.0.1:8080/v1/auth/token -u admin:admin <obtain a token>
// curl -k http://127.0.0.1:8080/v1/book/1449311601 -H "Authorization: Bearer <token>"

var authenticator auth.Authenticator
var cache store.Cache
var strategy union.Union
var tokenStrategy auth.Strategy
var cacheObj cache.Cache

func main() {
setupGoGuardian()
Expand All @@ -39,9 +42,8 @@ func main() {

func createToken(w http.ResponseWriter, r *http.Request) {
token := uuid.New().String()
user := auth.NewDefaultUser("medium", "1", nil, nil)
tokenStrategy := authenticator.Strategy(bearer.CachedStrategyKey)
auth.Append(tokenStrategy, token, user, r)
user := auth.NewDefaultUser("admin", "1", nil, nil)
auth.Append(tokenStrategy, token, user)
body := fmt.Sprintf("token: %s \n", token)
w.Write([]byte(body))
}
Expand All @@ -59,20 +61,20 @@ func getBookAuthor(w http.ResponseWriter, r *http.Request) {
}

func setupGoGuardian() {
authenticator = auth.New()
cache = store.NewFIFO(context.Background(), time.Minute*10)

basicStrategy := basic.New(validateUser, cache)
tokenStrategy := bearer.New(bearer.NoOpAuthenticate, cache)

authenticator.EnableStrategy(basic.StrategyKey, basicStrategy)
authenticator.EnableStrategy(bearer.CachedStrategyKey, tokenStrategy)
ttl := fifo.TTL(time.Minute * 5)
exp := fifo.RegisterOnExpired(func(key interface{}) {
cacheObj.Peek(key)
})
cacheObj = cache.FIFO.New(ttl, exp)
basicStrategy := basic.NewCached(validateUser, cacheObj)
tokenStrategy = token.New(token.NoOpAuthenticate, cacheObj)
strategy = union.New(tokenStrategy, basicStrategy)
}

func validateUser(ctx context.Context, r *http.Request, userName, password string) (auth.Info, error) {
// here connect to db or any other service to fetch user and validate it.
if userName == "admin" && password == "admin" {
return auth.NewDefaultUser("medium", "1", nil, nil), nil
return auth.NewDefaultUser("admin", "1", nil, nil), nil
}

return nil, fmt.Errorf("Invalid credentials")
Expand All @@ -81,13 +83,14 @@ func validateUser(ctx context.Context, r *http.Request, userName, password strin
func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
_, user, err := strategy.AuthenticateRequest(r)
if err != nil {
fmt.Println(err)
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
log.Printf("User %s Authenticated\n", user.GetUserName())
next.ServeHTTP(w, r)
})
}
41 changes: 19 additions & 22 deletions _examples/digest/main.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
package main

import (
"crypto/md5"
_ "crypto/md5"
"fmt"
"hash"
"log"
"net/http"
"time"

"github.com/gorilla/mux"

"github.com/shaj13/go-guardian/auth"
"github.com/shaj13/go-guardian/auth/strategies/digest"
"github.com/shaj13/go-guardian/cache"
"github.com/shaj13/go-guardian/cache/container/fifo"
)

// Usage:
// curl --digest --user admin:admin http://127.0.0.1:8080/v1/book/1449311601

var authenticator auth.Authenticator
var strategy *digest.Digest

func init() {
var c cache.Cache
ttl := fifo.TTL(time.Minute * 3)
exp := fifo.RegisterOnExpired(func(key interface{}) {
c.Delete(key)
})
c = cache.FIFO.New(ttl, exp)
strategy = digest.New(validateUser, c)
}

func main() {
setupGoGuardian()
router := mux.NewRouter()
router.HandleFunc("/v1/book/{id}", middleware(http.HandlerFunc(getBookAuthor))).Methods("GET")
log.Println("server started and listening on http://127.0.0.1:8080")
Expand All @@ -38,23 +49,10 @@ func getBookAuthor(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(body))
}

func setupGoGuardian() {
authenticator = auth.New()

digestStrategy := &digest.Strategy{
Algorithm: "md5",
Hash: func(algo string) hash.Hash { return md5.New() },
Realm: "test",
FetchUser: validateUser,
}

authenticator.EnableStrategy(digest.StrategyKey, digestStrategy)
}

func validateUser(userName string) (string, auth.Info, error) {
// here connect to db or any other service to fetch user and validate it.
if userName == "admin" {
return "admin", auth.NewDefaultUser("medium", "1", nil, nil), nil
return "admin", auth.NewDefaultUser("admin", "1", nil, nil), nil
}

return "", nil, fmt.Errorf("Invalid credentials")
Expand All @@ -63,16 +61,15 @@ func validateUser(userName string) (string, auth.Info, error) {
func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
user, err := strategy.Authenticate(r.Context(), r)
if err != nil {
code := http.StatusUnauthorized
s := authenticator.Strategy(digest.StrategyKey)
s.(*digest.Strategy).WWWAuthenticate(w.Header())
w.Header().Add("WWW-Authenticate", strategy.GetChallenge())
http.Error(w, http.StatusText(code), code)
fmt.Println("send error", err)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
log.Printf("User %s Authenticated\n", user.GetUserName())
next.ServeHTTP(w, r)
})
}
25 changes: 13 additions & 12 deletions _examples/kubernetes/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package main

import (
"context"
"fmt"
"log"
"net/http"
Expand All @@ -15,18 +14,18 @@ import (

"github.com/shaj13/go-guardian/auth"
"github.com/shaj13/go-guardian/auth/strategies/kubernetes"
"github.com/shaj13/go-guardian/auth/strategies/token"
"github.com/shaj13/go-guardian/store"
"github.com/shaj13/go-guardian/cache"
"github.com/shaj13/go-guardian/cache/container/fifo"
)

// Usage:
// Run kubernetes mock api and get agent token
// go run mock.go
// Request server to verify token and get book author
// curl -k http://127.0.0.1:8080/v1/book/1449311601 -H "Authorization: Bearer <agent-token-from-mock>"
// <agent-token-from-mock>"

var authenticator auth.Authenticator
var cache store.Cache
var strategy auth.Strategy
var cacheObj cache.Cache

func main() {
setupGoGuardian()
Expand All @@ -50,22 +49,24 @@ func getBookAuthor(w http.ResponseWriter, r *http.Request) {
}

func setupGoGuardian() {
authenticator = auth.New()
cache = store.NewFIFO(context.Background(), time.Minute*10)
kubeStrategy := kubernetes.New(cache)
authenticator.EnableStrategy(token.CachedStrategyKey, kubeStrategy)
ttl := fifo.TTL(time.Minute * 5)
exp := fifo.RegisterOnExpired(func(key interface{}) {
cacheObj.Peek(key)
})
cacheObj = cache.FIFO.New(ttl, exp)
strategy = kubernetes.New(cacheObj)
}

func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
user, err := strategy.Authenticate(r.Context(), r)
if err != nil {
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
log.Printf("User %s Authenticated\n", user.GetUserName())
next.ServeHTTP(w, r)
})
}
22 changes: 12 additions & 10 deletions _examples/ldap/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package main

import (
"context"
"fmt"
"log"
"net/http"
Expand All @@ -15,14 +14,15 @@ import (

"github.com/shaj13/go-guardian/auth"
"github.com/shaj13/go-guardian/auth/strategies/ldap"
"github.com/shaj13/go-guardian/store"
"github.com/shaj13/go-guardian/cache"
"github.com/shaj13/go-guardian/cache/container/fifo"
)

// Usage:
// curl -k http://127.0.0.1:8080/v1/book/1449311601 -u tesla:password

var authenticator auth.Authenticator
var cache store.Cache
var strategy auth.Strategy
var cacheObj cache.Cache

func main() {
setupGoGuardian()
Expand Down Expand Up @@ -53,22 +53,24 @@ func setupGoGuardian() {
BindPassword: "password",
Filter: "(uid=%s)",
}
authenticator = auth.New()
cache = store.NewFIFO(context.Background(), time.Minute*10)
strategy := ldap.NewCached(cfg, cache)
authenticator.EnableStrategy(ldap.StrategyKey, strategy)
ttl := fifo.TTL(time.Minute * 5)
exp := fifo.RegisterOnExpired(func(key interface{}) {
cacheObj.Peek(key)
})
cacheObj = cache.FIFO.New(ttl, exp)
strategy = ldap.NewCached(cfg, cacheObj)
}

func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
user, err := strategy.Authenticate(r.Context(), r)
if err != nil {
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
log.Printf("User %s Authenticated\n", user.GetUserName())
next.ServeHTTP(w, r)
})
}
18 changes: 7 additions & 11 deletions _examples/twofactor/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
// Usage:
// curl -k http://127.0.0.1:8080/v1/book/1449311601 -u admin:admin -H "X-Example-OTP: 345515"

var authenticator auth.Authenticator
var strategy auth.Strategy

func main() {
setupGoGuardian()
Expand All @@ -44,16 +44,12 @@ func getBookAuthor(w http.ResponseWriter, r *http.Request) {
}

func setupGoGuardian() {
authenticator = auth.New()

basicStrategy := basic.AuthenticateFunc(validateUser)
tfaStrategy := twofactor.Strategy{
basicStrategy := basic.New(validateUser)
strategy = twofactor.TwoFactor{
Parser: twofactor.XHeaderParser("X-Example-OTP"),
Manager: OTPManager{},
Primary: basicStrategy,
}

authenticator.EnableStrategy(twofactor.StrategyKey, tfaStrategy)
}

func validateUser(ctx context.Context, r *http.Request, userName, password string) (auth.Info, error) {
Expand All @@ -68,13 +64,13 @@ func validateUser(ctx context.Context, r *http.Request, userName, password strin
func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
user, err := strategy.Authenticate(r.Context(), r)
if err != nil {
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
log.Printf("User %s Authenticated\n", user.GetUserName())
next.ServeHTTP(w, r)
})
}
Expand All @@ -83,14 +79,14 @@ type OTPManager struct{}

func (OTPManager) Enabled(_ auth.Info) bool { return true }

func (OTPManager) Load(_ auth.Info) (twofactor.OTP, error) {
func (OTPManager) Load(_ auth.Info) (twofactor.Verifier, error) {
// user otp configuration must be loaded from persistent storage
key := otp.NewKey(otp.HOTP, "LABEL", "GXNRHI2MFRFWXQGJHWZJFOSYI6E7MEVA")
ver := otp.New(key)
return ver, nil
}

func (OTPManager) Store(_ auth.Info, otp twofactor.OTP) error {
func (OTPManager) Store(_ auth.Info, otp twofactor.Verifier) error {
// persist user otp after verification
return nil
}
Loading

0 comments on commit d23d38d

Please sign in to comment.