route/cmd/routed/common.go

137 lines
2.4 KiB
Go
Raw Normal View History

2017-12-15 18:18:13 +00:00
package main
2017-04-29 02:47:24 +00:00
import (
"context"
"errors"
2018-01-21 16:22:10 +00:00
"net/http"
"time"
2017-04-29 02:47:24 +00:00
2017-09-30 13:41:35 +00:00
"git.xeserv.us/xena/route/internal/database"
2018-01-21 17:07:21 +00:00
"git.xeserv.us/xena/route/internal/middleware"
2017-04-29 02:47:24 +00:00
"github.com/Xe/ln"
2018-01-21 16:22:10 +00:00
"github.com/twitchtv/twirp"
2017-10-01 15:06:27 +00:00
"golang.org/x/net/trace"
2017-04-29 02:47:24 +00:00
)
// errors
var (
ErrNotAuthorized = errors.New("server: not authorized")
)
2018-01-21 16:22:10 +00:00
func (s *Server) makeTwirpHooks() *twirp.ServerHooks {
hooks := &twirp.ServerHooks{}
2017-04-29 02:47:24 +00:00
2018-01-21 16:22:10 +00:00
hooks.RequestRouted = func(ctx context.Context) (context.Context, error) {
ctx = withStartTime(ctx)
method, ok := twirp.MethodName(ctx)
if !ok {
return ctx, nil
}
pkg, ok := twirp.PackageName(ctx)
if !ok {
return ctx, nil
}
svc, ok := twirp.ServiceName(ctx)
if !ok {
return ctx, nil
}
ctx = ln.WithF(ctx, ln.F{
"twirp_method": method,
"twirp_package": pkg,
"twirp_service": svc,
})
2018-01-21 17:07:21 +00:00
hdr, ok := middleware.GetHeaders(ctx)
2018-01-21 16:22:10 +00:00
if !ok {
return ctx, errors.New("can't get request headers")
}
req, _ := http.NewRequest("GET", "/", nil)
req.Header = hdr
ck, err := req.Cookie("routed")
if err != nil {
return ctx, err
}
tok := ck.Value
t, err := s.db.GetToken(ctx, tok)
if err != nil {
return ctx, err
}
ctx = withAuthToken(ctx, t)
ctx = ln.WithF(ctx, t.F())
return ctx, nil
2017-04-29 02:47:24 +00:00
}
2018-01-21 16:22:10 +00:00
hooks.ResponseSent = func(ctx context.Context) {
f := ln.F{}
now := time.Now()
t, ok := getStartTime(ctx)
if ok {
f["response_time"] = now.Sub(t)
}
ln.Log(ctx, f, ln.Action("response sent"))
}
hooks.Error = func(ctx context.Context, e twirp.Error) context.Context {
f := ln.F{}
for k, v := range e.MetaMap() {
f["twirp_meta_"+k] = v
}
ln.Error(ctx, e, f, ln.Action("twirp error"), ln.F{
"twirp_error_code": e.Code(),
"twirp_error_msg": e.Msg(),
})
return ctx
2017-04-29 02:47:24 +00:00
}
2018-01-21 16:22:10 +00:00
return hooks
}
func (s *Server) getAuth(ctx context.Context, operation, scope string) (database.Token, error) {
t, ok := getAuthToken(ctx)
if !ok {
return database.Token{}, errors.New("no auth token in context")
2017-04-29 02:47:24 +00:00
}
ok = false
for _, sc := range t.Scopes {
if sc == scope {
ok = true
}
}
2018-01-21 16:22:10 +00:00
2017-04-29 02:47:24 +00:00
if !ok {
2018-01-21 16:22:10 +00:00
return database.Token{}, ErrNotAuthorized
2017-04-29 02:47:24 +00:00
}
2018-01-21 16:22:10 +00:00
ln.WithF(ctx, ln.F{"operation": operation})
return t, nil
2017-04-29 02:47:24 +00:00
}
func handleError(ctx context.Context, clitok database.Token, err error, f ln.F) error {
2017-10-01 15:06:27 +00:00
tr, ok := trace.FromContext(ctx)
if !ok {
goto skip
}
tr.SetError()
skip:
2017-10-01 13:28:13 +00:00
ln.Error(ctx, err, f, clitok)
2017-04-29 02:47:24 +00:00
return err
}