Files
remark42/backend/vendor/github.com/go-pkgz/auth/provider/direct.go
T

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)
}