2018-02-10 19:14:42 +00:00
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/kirsle/blog/core/internal/models/users"
|
|
|
|
"github.com/kirsle/blog/core/internal/sessions"
|
|
|
|
"github.com/kirsle/blog/core/internal/types"
|
|
|
|
"github.com/urfave/negroni"
|
|
|
|
)
|
|
|
|
|
|
|
|
// CurrentUser returns the current user's object.
|
|
|
|
func CurrentUser(r *http.Request) (*users.User, error) {
|
|
|
|
session := sessions.Get(r)
|
|
|
|
if loggedIn, ok := session.Values["logged-in"].(bool); ok && loggedIn {
|
|
|
|
id := session.Values["user-id"].(int)
|
|
|
|
u, err := users.LoadReadonly(id)
|
|
|
|
u.IsAuthenticated = true
|
|
|
|
return u, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &users.User{
|
|
|
|
Admin: false,
|
|
|
|
}, errors.New("not authenticated")
|
|
|
|
}
|
|
|
|
|
2018-02-10 22:36:21 +00:00
|
|
|
// Login logs the browser in as the given user.
|
|
|
|
func Login(w http.ResponseWriter, r *http.Request, u *users.User) error {
|
|
|
|
session, err := sessions.Store.Get(r, "session") // TODO session name
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
session.Values["logged-in"] = true
|
|
|
|
session.Values["user-id"] = u.ID
|
|
|
|
session.Save(r, w)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-02-10 19:14:42 +00:00
|
|
|
// LoggedIn returns whether the current user is logged in to an account.
|
|
|
|
func LoggedIn(r *http.Request) bool {
|
|
|
|
session := sessions.Get(r)
|
|
|
|
if loggedIn, ok := session.Values["logged-in"].(bool); ok && loggedIn {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// LoginRequired is a middleware that requires a logged-in user.
|
|
|
|
func LoginRequired(onError http.HandlerFunc) negroni.HandlerFunc {
|
|
|
|
middleware := func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
|
|
|
ctx := r.Context()
|
|
|
|
if user, ok := ctx.Value(types.UserKey).(*users.User); ok {
|
|
|
|
if user.ID > 0 {
|
|
|
|
next(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
onError(w, r)
|
|
|
|
}
|
|
|
|
|
|
|
|
return middleware
|
|
|
|
}
|
|
|
|
|
|
|
|
// Middleware loads the user's authentication state from their session cookie.
|
|
|
|
func Middleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
|
|
|
|
u, err := CurrentUser(r)
|
|
|
|
if err != nil {
|
|
|
|
next(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.WithValue(r.Context(), types.UserKey, u)
|
|
|
|
next(w, r.WithContext(ctx))
|
|
|
|
}
|