82 lines
2.4 KiB
Go
82 lines
2.4 KiB
Go
package provider
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
|
|
jwt "github.com/dgrijalva/jwt-go"
|
|
"github.com/go-pkgz/rest"
|
|
|
|
"github.com/go-pkgz/auth/logger"
|
|
"github.com/go-pkgz/auth/token"
|
|
)
|
|
|
|
// DirectHandler implements non-oauth2 provider authorizing user in traditional way with storage
|
|
// with users and hashes
|
|
type DirectHandler struct {
|
|
logger.L
|
|
CredChecker CredChecker
|
|
ProviderName string
|
|
TokenService TokenService
|
|
Issuer string
|
|
}
|
|
|
|
// CredChecker defines interface to check credentials
|
|
type CredChecker interface {
|
|
Check(user, password string) (ok bool, err error)
|
|
}
|
|
|
|
// CredCheckerFunc type is an adapter to allow the use of ordinary functions as CredsChecker.
|
|
type CredCheckerFunc func(user, password string) (ok bool, err error)
|
|
|
|
// Check calls f(user,passwd)
|
|
func (f CredCheckerFunc) Check(user, password string) (ok bool, err error) {
|
|
return f(user, password)
|
|
}
|
|
|
|
// Name of the handler
|
|
func (p DirectHandler) Name() string { return p.ProviderName }
|
|
|
|
// LoginHandler checks "user" and "passwd" against data store and makes jwt if all passed
|
|
// GET /something?user=name&password=xyz&sess=[0|1]
|
|
func (p DirectHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
|
|
user, password := r.URL.Query().Get("user"), r.URL.Query().Get("passwd")
|
|
aud := r.URL.Query().Get("aud")
|
|
sessOnly := r.URL.Query().Get("sess") == "1"
|
|
if p.CredChecker == nil {
|
|
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, errors.New("empty credential store"), "no credential store")
|
|
return
|
|
}
|
|
ok, err := p.CredChecker.Check(user, password)
|
|
if err != nil {
|
|
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to access creds store")
|
|
return
|
|
}
|
|
if !ok {
|
|
rest.SendErrorJSON(w, r, p.L, http.StatusForbidden, nil, "incorrect user or password")
|
|
return
|
|
}
|
|
claims := token.Claims{
|
|
User: &token.User{Name: user},
|
|
StandardClaims: jwt.StandardClaims{
|
|
Issuer: p.Issuer,
|
|
Audience: aud,
|
|
},
|
|
SessionOnly: sessOnly,
|
|
}
|
|
|
|
if _, err = p.TokenService.Set(w, claims); err != nil {
|
|
rest.SendErrorJSON(w, r, p.L, http.StatusInternalServerError, err, "failed to set token")
|
|
return
|
|
}
|
|
rest.RenderJSON(w, r, claims.User)
|
|
}
|
|
|
|
// AuthHandler doesn't do anything for direct login as it has no callbacks
|
|
func (p DirectHandler) AuthHandler(w http.ResponseWriter, r *http.Request) {}
|
|
|
|
// LogoutHandler - GET /logout
|
|
func (p DirectHandler) LogoutHandler(w http.ResponseWriter, r *http.Request) {
|
|
p.TokenService.Reset(w)
|
|
}
|