auth

Paddy 2014-09-01

23:1aa3a85ff853 Go to Latest

auth/session.go.old

Deprecate old implementations. Let's remove all of the osin stuff altogether, in favour of a more testable, unit-based approach. Leave all the old files around, for easy reference, but add the .old suffix so the go tools don't pick them up.

History
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/session.go.old	Mon Sep 01 09:13:52 2014 -0400
     1.3 @@ -0,0 +1,101 @@
     1.4 +package auth
     1.5 +
     1.6 +import (
     1.7 +	"errors"
     1.8 +	"net/http"
     1.9 +	"net/url"
    1.10 +	"time"
    1.11 +
    1.12 +	"strings"
    1.13 +	"secondbit.org/uuid"
    1.14 +)
    1.15 +
    1.16 +const sessionCookie = "session"
    1.17 +
    1.18 +var (
    1.19 +	ErrSessionNotFound = errors.New("Session not found.")
    1.20 +)
    1.21 +
    1.22 +type Session struct {
    1.23 +	Token   string
    1.24 +	Profile uuid.ID
    1.25 +	Expires time.Time
    1.26 +	Created time.Time
    1.27 +	IP      string
    1.28 +}
    1.29 +
    1.30 +type SessionStore interface {
    1.31 +	GetSession(token string) (Session, error)
    1.32 +	GetAllSessions(userID uuid.ID, num, page int) ([]Session, error)
    1.33 +	SaveSession(session Session) error
    1.34 +	DeleteSession(sessionID uuid.ID) error
    1.35 +}
    1.36 +
    1.37 +func validateSession(r *http.Request, c Context) error {
    1.38 +	cookie, err := r.Cookie(sessionCookie)
    1.39 +	if err == http.ErrNoCookie {
    1.40 +		return ErrSessionNotFound
    1.41 +	}
    1.42 +	_, err = c.Sessions.GetSession(cookie.Value)
    1.43 +	return err
    1.44 +}
    1.45 +
    1.46 +func HandleLoginRequest(w http.ResponseWriter, r *http.Request, ctx Context) {
    1.47 +	if r.Method == "GET" {
    1.48 +		ctx.RenderLogin(w, r)
    1.49 +		return
    1.50 +	} else if r.Method != "POST" {
    1.51 +		// TODO: return bad method error
    1.52 +		return
    1.53 +	}
    1.54 +
    1.55 +	if r.FormValue("username") == "" || r.FormValue("password") == "" {
    1.56 +		// TODO: return unauthenticated error
    1.57 +		return
    1.58 +	}
    1.59 +	id, err := ctx.Profiles.GetProfile(r.FormValue("username"), r.FormValue("password"))
    1.60 +	if err != nil {
    1.61 +		if err == ErrProfileNotFound {
    1.62 +			// TODO: return unauthenticated error
    1.63 +			return
    1.64 +		}
    1.65 +		// TODO: return internal server error
    1.66 +		return
    1.67 +	}
    1.68 +	session := Session{
    1.69 +		Token:   newToken(),
    1.70 +		Profile: id,
    1.71 +		Expires: time.Now().Add(ctx.Config.SessionLength),
    1.72 +		Created: time.Now(),
    1.73 +		IP:      r.Header.Get(ctx.Config.RequestIPHeader),
    1.74 +	}
    1.75 +	err = ctx.Sessions.SetSession(session)
    1.76 +	if err != nil {
    1.77 +		// TODO: return internal server error
    1.78 +		return
    1.79 +	}
    1.80 +	http.SetCookie(w, &http.Cookie{
    1.81 +		Name:     sessionCookie,
    1.82 +		Value:    session.Token,
    1.83 +		Expires:  session.Expires,
    1.84 +		Secure:   true,
    1.85 +		HttpOnly: true,
    1.86 +	})
    1.87 +
    1.88 +	redirectString := r.URL.Query().Get("redirect_to")
    1.89 +	if redirectString != "" {
    1.90 +		redirectURI, err := url.Parse(redirectString)
    1.91 +		if err != nil {
    1.92 +			// TODO: render a bad request error
    1.93 +			return
    1.94 +		}
    1.95 +		if !strings.HasSuffix("."+ctx.Config.LoginRedirectDomain, redirectURI.Host) && redirectURI.Host != ctx.Config.LoginRedirectDomain {
    1.96 +			// TODO: render a bad request error
    1.97 +			return
    1.98 +		}
    1.99 +	} else {
   1.100 +		redirectString = "https://" + ctx.Config.LoginRedirectDomain
   1.101 +	}
   1.102 +	http.Redirect(w, r, redirectString, http.StatusFound)
   1.103 +	return
   1.104 +}