2019-03-24 14:57:29 +01:00
|
|
|
package serv
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2019-04-10 07:38:48 +02:00
|
|
|
"net/url"
|
2019-03-24 14:57:29 +01:00
|
|
|
|
|
|
|
"github.com/bradfitz/gomemcache/memcache"
|
2019-04-10 07:38:48 +02:00
|
|
|
"github.com/dosco/super-graph/rails"
|
2019-03-24 14:57:29 +01:00
|
|
|
"github.com/garyburd/redigo/redis"
|
|
|
|
)
|
|
|
|
|
|
|
|
func railsRedisHandler(next http.HandlerFunc) http.HandlerFunc {
|
2019-04-08 08:47:59 +02:00
|
|
|
cookie := conf.Auth.Cookie
|
2019-03-24 14:57:29 +01:00
|
|
|
if len(cookie) == 0 {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Msg("no auth.cookie defined")
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
if len(conf.Auth.Rails.URL) == 0 {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Msg("no auth.rails.url defined")
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
rp := &redis.Pool{
|
2019-04-10 07:38:48 +02:00
|
|
|
MaxIdle: conf.Auth.Rails.MaxIdle,
|
|
|
|
MaxActive: conf.Auth.Rails.MaxActive,
|
2019-03-24 14:57:29 +01:00
|
|
|
Dial: func() (redis.Conn, error) {
|
2019-04-10 07:38:48 +02:00
|
|
|
c, err := redis.DialURL(conf.Auth.Rails.URL)
|
2019-03-24 14:57:29 +01:00
|
|
|
if err != nil {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Err(err).Send()
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
pwd := conf.Auth.Rails.Password
|
2019-03-24 14:57:29 +01:00
|
|
|
if len(pwd) != 0 {
|
|
|
|
if _, err := c.Do("AUTH", pwd); err != nil {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Err(err).Send()
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return c, err
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ck, err := r.Cookie(cookie)
|
|
|
|
if err != nil {
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
key := fmt.Sprintf("session:%s", ck.Value)
|
|
|
|
sessionData, err := redis.Bytes(rp.Get().Do("GET", key))
|
|
|
|
if err != nil {
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
userID, err := rails.ParseCookie(string(sessionData))
|
2019-03-24 14:57:29 +01:00
|
|
|
if err != nil {
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.WithValue(r.Context(), userIDKey, userID)
|
|
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func railsMemcacheHandler(next http.HandlerFunc) http.HandlerFunc {
|
2019-04-08 08:47:59 +02:00
|
|
|
cookie := conf.Auth.Cookie
|
2019-03-24 14:57:29 +01:00
|
|
|
if len(cookie) == 0 {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Msg("no auth.cookie defined")
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
if len(conf.Auth.Rails.URL) == 0 {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Msg("no auth.rails.url defined")
|
2019-04-10 07:38:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
rURL, err := url.Parse(conf.Auth.Rails.URL)
|
|
|
|
if err != nil {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Err(err).Send()
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
mc := memcache.New(rURL.Host)
|
2019-03-24 14:57:29 +01:00
|
|
|
|
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ck, err := r.Cookie(cookie)
|
|
|
|
if err != nil {
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
key := fmt.Sprintf("session:%s", ck.Value)
|
|
|
|
item, err := mc.Get(key)
|
|
|
|
if err != nil {
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
userID, err := rails.ParseCookie(string(item.Value))
|
2019-03-24 14:57:29 +01:00
|
|
|
if err != nil {
|
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.WithValue(r.Context(), userIDKey, userID)
|
|
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func railsCookieHandler(next http.HandlerFunc) http.HandlerFunc {
|
2019-04-08 08:47:59 +02:00
|
|
|
cookie := conf.Auth.Cookie
|
2019-03-24 14:57:29 +01:00
|
|
|
if len(cookie) == 0 {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Msg("no auth.cookie defined")
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
ra, err := railsAuth(conf)
|
|
|
|
if err != nil {
|
2019-11-25 08:22:33 +01:00
|
|
|
errlog.Fatal().Err(err).Send()
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
2019-04-10 07:38:48 +02:00
|
|
|
|
2019-03-24 14:57:29 +01:00
|
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ck, err := r.Cookie(cookie)
|
2019-11-02 22:13:17 +01:00
|
|
|
if err != nil || len(ck.Value) == 0 {
|
2019-10-25 06:01:22 +02:00
|
|
|
logger.Warn().Err(err).Msg("rails cookie missing")
|
2019-03-24 14:57:29 +01:00
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
userID, err := ra.ParseCookie(ck.Value)
|
2019-03-24 14:57:29 +01:00
|
|
|
if err != nil {
|
2019-10-25 06:01:22 +02:00
|
|
|
logger.Warn().Err(err).Msg("failed to parse rails cookie")
|
2019-03-24 14:57:29 +01:00
|
|
|
next.ServeHTTP(w, r)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := context.WithValue(r.Context(), userIDKey, userID)
|
|
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
func railsAuth(c *config) (*rails.Auth, error) {
|
|
|
|
secret := c.Auth.Rails.SecretKeyBase
|
|
|
|
if len(secret) == 0 {
|
|
|
|
return nil, errors.New("no auth.rails.secret_key_base defined")
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
version := c.Auth.Rails.Version
|
|
|
|
if len(version) == 0 {
|
|
|
|
return nil, errors.New("no auth.rails.version defined")
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
ra, err := rails.NewAuth(version, secret)
|
2019-03-24 14:57:29 +01:00
|
|
|
if err != nil {
|
2019-04-10 07:38:48 +02:00
|
|
|
return nil, err
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
if len(c.Auth.Rails.Salt) != 0 {
|
|
|
|
ra.Salt = c.Auth.Rails.Salt
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
if len(conf.Auth.Rails.SignSalt) != 0 {
|
|
|
|
ra.SignSalt = c.Auth.Rails.SignSalt
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
if len(conf.Auth.Rails.AuthSalt) != 0 {
|
|
|
|
ra.AuthSalt = c.Auth.Rails.AuthSalt
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|
|
|
|
|
2019-04-10 07:38:48 +02:00
|
|
|
return ra, nil
|
2019-03-24 14:57:29 +01:00
|
|
|
}
|