mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 05:01:10 -05:00
100 lines
2.4 KiB
Go
100 lines
2.4 KiB
Go
package samlsp
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/crewjam/saml"
|
|
)
|
|
|
|
const defaultSessionCookieName = "token"
|
|
|
|
var _ SessionProvider = CookieSessionProvider{}
|
|
|
|
// CookieSessionProvider is an implementation of SessionProvider that stores
|
|
// session tokens in an HTTP cookie.
|
|
type CookieSessionProvider struct {
|
|
Name string
|
|
Domain string
|
|
HTTPOnly bool
|
|
Secure bool
|
|
SameSite http.SameSite
|
|
MaxAge time.Duration
|
|
Codec SessionCodec
|
|
}
|
|
|
|
// CreateSession is called when we have received a valid SAML assertion and
|
|
// should create a new session and modify the http response accordingly, e.g. by
|
|
// setting a cookie.
|
|
func (c CookieSessionProvider) CreateSession(w http.ResponseWriter, r *http.Request, assertion *saml.Assertion) error {
|
|
// Cookies should not have the port attached to them so strip it off
|
|
if domain, _, err := net.SplitHostPort(c.Domain); err == nil {
|
|
c.Domain = domain
|
|
}
|
|
|
|
session, err := c.Codec.New(assertion)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
value, err := c.Codec.Encode(session)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: c.Name,
|
|
Domain: c.Domain,
|
|
Value: value,
|
|
MaxAge: int(c.MaxAge.Seconds()),
|
|
HttpOnly: c.HTTPOnly,
|
|
Secure: c.Secure || r.URL.Scheme == "https",
|
|
SameSite: c.SameSite,
|
|
Path: "/",
|
|
})
|
|
return nil
|
|
}
|
|
|
|
// DeleteSession is called to modify the response such that it removed the current
|
|
// session, e.g. by deleting a cookie.
|
|
func (c CookieSessionProvider) DeleteSession(w http.ResponseWriter, r *http.Request) error {
|
|
// Cookies should not have the port attached to them so strip it off
|
|
if domain, _, err := net.SplitHostPort(c.Domain); err == nil {
|
|
c.Domain = domain
|
|
}
|
|
|
|
cookie, err := r.Cookie(c.Name)
|
|
|
|
if err == http.ErrNoCookie {
|
|
return nil
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
cookie.Value = ""
|
|
cookie.Expires = time.Unix(1, 0) // past time as close to epoch as possible, but not zero time.Time{}
|
|
cookie.Path = "/"
|
|
cookie.Domain = c.Domain
|
|
http.SetCookie(w, cookie)
|
|
return nil
|
|
}
|
|
|
|
// GetSession returns the current Session associated with the request, or
|
|
// ErrNoSession if there is no valid session.
|
|
func (c CookieSessionProvider) GetSession(r *http.Request) (Session, error) {
|
|
cookie, err := r.Cookie(c.Name)
|
|
if err == http.ErrNoCookie {
|
|
return nil, ErrNoSession
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
session, err := c.Codec.Decode(cookie.Value)
|
|
if err != nil {
|
|
return nil, ErrNoSession
|
|
}
|
|
return session, nil
|
|
}
|