Merge branch 'Oauth_auth' into 'master'
OAuth2 See merge request lukas/openmediacenter!37
This commit is contained in:
commit
b625a4d958
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"openmediacenter/apiGo/api/oauth"
|
||||||
)
|
)
|
||||||
|
|
||||||
const APIPREFIX = "/api"
|
const APIPREFIX = "/api"
|
||||||
@ -36,10 +37,13 @@ func AddHandler(action string, apiNode int, n interface{}, h func() []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ServerInit(port uint16) {
|
func ServerInit(port uint16) {
|
||||||
http.Handle(APIPREFIX+"/video", http.HandlerFunc(videoHandler))
|
http.Handle(APIPREFIX+"/video", oauth.ValidateToken(videoHandler))
|
||||||
http.Handle(APIPREFIX+"/tags", http.HandlerFunc(tagHandler))
|
http.Handle(APIPREFIX+"/tags", oauth.ValidateToken(tagHandler))
|
||||||
http.Handle(APIPREFIX+"/settings", http.HandlerFunc(settingsHandler))
|
http.Handle(APIPREFIX+"/settings", oauth.ValidateToken(settingsHandler))
|
||||||
http.Handle(APIPREFIX+"/actor", http.HandlerFunc(actorHandler))
|
http.Handle(APIPREFIX+"/actor", oauth.ValidateToken(actorHandler))
|
||||||
|
|
||||||
|
// initialize oauth service and add corresponding auth routes
|
||||||
|
oauth.InitOAuth()
|
||||||
|
|
||||||
fmt.Printf("OpenMediacenter server up and running on port %d\n", port)
|
fmt.Printf("OpenMediacenter server up and running on port %d\n", port)
|
||||||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
|
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
|
||||||
|
67
apiGo/api/oauth/Oauth.go
Normal file
67
apiGo/api/oauth/Oauth.go
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package oauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gopkg.in/oauth2.v3/errors"
|
||||||
|
"gopkg.in/oauth2.v3/manage"
|
||||||
|
"gopkg.in/oauth2.v3/models"
|
||||||
|
"gopkg.in/oauth2.v3/server"
|
||||||
|
"gopkg.in/oauth2.v3/store"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var srv *server.Server
|
||||||
|
|
||||||
|
func InitOAuth() {
|
||||||
|
manager := manage.NewDefaultManager()
|
||||||
|
// token store
|
||||||
|
manager.MustTokenStorage(store.NewMemoryTokenStore())
|
||||||
|
|
||||||
|
clientStore := store.NewClientStore()
|
||||||
|
// todo we need to check here if a password is enabled in db -- when yes set it here!
|
||||||
|
clientStore.Set("openmediacenter", &models.Client{
|
||||||
|
ID: "openmediacenter",
|
||||||
|
Secret: "openmediacenter",
|
||||||
|
Domain: "http://localhost:8081",
|
||||||
|
})
|
||||||
|
|
||||||
|
manager.MapClientStorage(clientStore)
|
||||||
|
srv = server.NewServer(server.NewConfig(), manager)
|
||||||
|
srv.SetClientInfoHandler(server.ClientFormHandler)
|
||||||
|
manager.SetRefreshTokenCfg(manage.DefaultRefreshTokenCfg)
|
||||||
|
|
||||||
|
srv.SetInternalErrorHandler(func(err error) (re *errors.Response) {
|
||||||
|
log.Println("Internal Error:", err.Error())
|
||||||
|
return
|
||||||
|
})
|
||||||
|
|
||||||
|
srv.SetResponseErrorHandler(func(re *errors.Response) {
|
||||||
|
log.Println("Response Error:", re.Error.Error())
|
||||||
|
})
|
||||||
|
|
||||||
|
http.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
err := srv.HandleAuthorizeRequest(w, r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
http.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
err := srv.HandleTokenRequest(w, r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func ValidateToken(f http.HandlerFunc) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
_, err := srv.ValidationBearerToken(r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
}
|
@ -2,4 +2,8 @@ module openmediacenter/apiGo
|
|||||||
|
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require github.com/go-sql-driver/mysql v1.5.0
|
require (
|
||||||
|
github.com/go-session/session v3.1.2+incompatible
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0
|
||||||
|
gopkg.in/oauth2.v3 v3.12.0
|
||||||
|
)
|
||||||
|
109
apiGo/go.sum
109
apiGo/go.sum
@ -1,2 +1,111 @@
|
|||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
|
||||||
|
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||||
|
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||||
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/gavv/httpexpect v2.0.0+incompatible h1:1X9kcRshkSKEjNJJxX9Y9mQ5BRfbxU5kORdjhlA1yX8=
|
||||||
|
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||||
|
github.com/go-session/session v3.1.2+incompatible h1:yStchEObKg4nk2F7JGE7KoFIrA/1Y078peagMWcrncg=
|
||||||
|
github.com/go-session/session v3.1.2+incompatible/go.mod h1:8B3iivBQjrz/JtC68Np2T1yBBLxTan3mn/3OM0CyRt0=
|
||||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||||
|
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
|
||||||
|
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
|
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
|
||||||
|
github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs=
|
||||||
|
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||||
|
github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w=
|
||||||
|
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||||
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
|
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||||
|
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||||
|
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||||
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
|
github.com/tidwall/btree v0.0.0-20170113224114-9876f1454cf0 h1:QnyrPZZvPmR0AtJCxxfCtI1qN+fYpKTKJ/5opWmZ34k=
|
||||||
|
github.com/tidwall/btree v0.0.0-20170113224114-9876f1454cf0/go.mod h1:huei1BkDWJ3/sLXmO+bsCNELL+Bp2Kks9OLyQFkzvA8=
|
||||||
|
github.com/tidwall/buntdb v1.1.0 h1:H6LzK59KiNjf1nHVPFrYj4Qnl8d8YLBsYamdL8N+Bao=
|
||||||
|
github.com/tidwall/buntdb v1.1.0/go.mod h1:Y39xhcDW10WlyYXeLgGftXVbjtM0QP+/kpz8xl9cbzE=
|
||||||
|
github.com/tidwall/gjson v1.3.2 h1:+7p3qQFaH3fOMXAJSrdZwGKcOO/lYdGS0HqGhPqDdTI=
|
||||||
|
github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
|
||||||
|
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb h1:5NSYaAdrnblKByzd7XByQEJVT8+9v0W/tIY0Oo4OwrE=
|
||||||
|
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb/go.mod h1:lKYYLFIr9OIgdgrtgkZ9zgRxRdvPYsExnYBsEAd8W5M=
|
||||||
|
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
|
||||||
|
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||||
|
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
|
||||||
|
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
|
github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e h1:+NL1GDIUOKxVfbp2KoJQD9cTQ6dyP2co9q4yzmT9FZo=
|
||||||
|
github.com/tidwall/rtree v0.0.0-20180113144539-6cd427091e0e/go.mod h1:/h+UnNGt0IhNNJLkGikcdcJqm66zGD/uJGMRxK/9+Ao=
|
||||||
|
github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563 h1:Otn9S136ELckZ3KKDyCkxapfufrqDqwmGjcHfAyXRrE=
|
||||||
|
github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563/go.mod h1:mLqSmt7Dv/CNneF2wfcChfN1rvapyQr01LGKnKex0DQ=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||||
|
github.com/valyala/fasthttp v1.6.0 h1:uWF8lgKmeaIewWVPwi4GRq2P6+R46IgYZdxWtM+GtEY=
|
||||||
|
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||||
|
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||||
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
|
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
|
||||||
|
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
|
||||||
|
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
|
||||||
|
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
|
||||||
|
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
|
||||||
|
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||||
|
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
|
||||||
|
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/oauth2.v3 v3.12.0 h1:yOffAPoolH/i2JxwmC+pgtnY3362iPahsDpLXfDFvNg=
|
||||||
|
gopkg.in/oauth2.v3 v3.12.0/go.mod h1:XEYgKqWX095YiPT+Aw5y3tCn+7/FMnlTFKrupgSiJ3I=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
@ -12,12 +12,8 @@ describe('<ActorTile/>', function () {
|
|||||||
const func = jest.fn((_) => {});
|
const func = jest.fn((_) => {});
|
||||||
const wrapper = shallow(<ActorTile actor={{Thumbnail: '-1', Name: 'testname', id: 3}} onClick={() => func()}/>);
|
const wrapper = shallow(<ActorTile actor={{Thumbnail: '-1', Name: 'testname', id: 3}} onClick={() => func()}/>);
|
||||||
|
|
||||||
const func1 = jest.fn();
|
|
||||||
prepareViewBinding(func1);
|
|
||||||
|
|
||||||
wrapper.simulate('click');
|
wrapper.simulate('click');
|
||||||
|
|
||||||
expect(func1).toBeCalledTimes(0);
|
|
||||||
expect(func).toBeCalledTimes(1);
|
expect(func).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,7 +19,8 @@ global.prepareFetchApi = (response) => {
|
|||||||
const mockJsonPromise = Promise.resolve(response);
|
const mockJsonPromise = Promise.resolve(response);
|
||||||
const mockFetchPromise = Promise.resolve({
|
const mockFetchPromise = Promise.resolve({
|
||||||
json: () => mockJsonPromise,
|
json: () => mockJsonPromise,
|
||||||
text: () => mockJsonPromise
|
text: () => mockJsonPromise,
|
||||||
|
status: 200
|
||||||
});
|
});
|
||||||
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
||||||
};
|
};
|
||||||
@ -33,19 +34,6 @@ global.prepareFailingFetchApi = () => {
|
|||||||
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* prepares a viewbinding instance
|
|
||||||
* @param func a mock function to be called
|
|
||||||
*/
|
|
||||||
global.prepareViewBinding = (func) => {
|
|
||||||
GlobalInfos.getViewBinding = () => {
|
|
||||||
return {
|
|
||||||
changeRootElement: func,
|
|
||||||
returnToLastElement: func
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
global.callAPIMock = (resonse) => {
|
global.callAPIMock = (resonse) => {
|
||||||
const helpers = require('./utils/Api');
|
const helpers = require('./utils/Api');
|
||||||
helpers.callAPI = jest.fn().mockImplementation((_, __, func1) => {func1(resonse);});
|
helpers.callAPI = jest.fn().mockImplementation((_, __, func1) => {func1(resonse);});
|
||||||
|
193
src/utils/Api.ts
193
src/utils/Api.ts
@ -43,6 +43,153 @@ interface ApiBaseRequest {
|
|||||||
[_: string]: string | number | boolean | object
|
[_: string]: string | number | boolean | object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// store api token - empty if not set
|
||||||
|
let apiToken = ''
|
||||||
|
|
||||||
|
// a callback que to be called after api token refresh
|
||||||
|
let callQue: (() => void)[] = []
|
||||||
|
// flag to check wheter a api refresh is currently pending
|
||||||
|
let refreshInProcess = false;
|
||||||
|
// store the expire seconds of token
|
||||||
|
let expireSeconds = -1;
|
||||||
|
|
||||||
|
interface APIToken {
|
||||||
|
access_token: string;
|
||||||
|
expires_in: number;
|
||||||
|
scope: string;
|
||||||
|
token_type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* refresh the api token or use that one in cookie if still valid
|
||||||
|
* @param callback to be called after successful refresh
|
||||||
|
*/
|
||||||
|
export function refreshAPIToken(callback: () => void): void {
|
||||||
|
callQue.push(callback);
|
||||||
|
|
||||||
|
// check if already is a token refresh is in process
|
||||||
|
if (refreshInProcess) {
|
||||||
|
// if yes return
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// if not set flat
|
||||||
|
refreshInProcess = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if a cookie with token is available
|
||||||
|
const token = getTokenCookie();
|
||||||
|
if (token !== null) {
|
||||||
|
// check if token is at least valid for the next minute
|
||||||
|
if (token.expire > (new Date().getTime() / 1000) + 60) {
|
||||||
|
apiToken = token.token;
|
||||||
|
expireSeconds = token.expire;
|
||||||
|
callback();
|
||||||
|
console.log("token still valid...")
|
||||||
|
callFuncQue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("grant_type", "client_credentials");
|
||||||
|
formData.append("client_id", "openmediacenter");
|
||||||
|
formData.append("client_secret", 'openmediacenter');
|
||||||
|
formData.append("scope", 'all');
|
||||||
|
|
||||||
|
|
||||||
|
fetch(getBackendDomain() + '/token', {method: 'POST', body: formData})
|
||||||
|
.then((response) => response.json()
|
||||||
|
.then((result: APIToken) => {
|
||||||
|
console.log(result)
|
||||||
|
// set api token
|
||||||
|
apiToken = result.access_token;
|
||||||
|
// set expire time
|
||||||
|
expireSeconds = (new Date().getTime() / 1000) + result.expires_in;
|
||||||
|
setTokenCookie(apiToken, expireSeconds);
|
||||||
|
// call all handlers and release flag
|
||||||
|
callFuncQue();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call all qued callbacks
|
||||||
|
*/
|
||||||
|
function callFuncQue(): void {
|
||||||
|
// call all pending handlers
|
||||||
|
callQue.map(func => {
|
||||||
|
return func();
|
||||||
|
})
|
||||||
|
// reset pending que
|
||||||
|
callQue = []
|
||||||
|
// release flag to be able to start new refresh
|
||||||
|
refreshInProcess = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the cookie for the currently gotten token
|
||||||
|
* @param token token string
|
||||||
|
* @param validSec second time when the token will be invalid
|
||||||
|
*/
|
||||||
|
function setTokenCookie(token: string, validSec: number): void {
|
||||||
|
let d = new Date();
|
||||||
|
d.setTime(validSec * 1000);
|
||||||
|
console.log("token set" + d.toUTCString())
|
||||||
|
let expires = "expires=" + d.toUTCString();
|
||||||
|
document.cookie = "token=" + token + ";" + expires + ";path=/";
|
||||||
|
document.cookie = "token_expire=" + validSec + ";" + expires + ";path=/";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get all required cookies for the token
|
||||||
|
*/
|
||||||
|
function getTokenCookie(): { token: string, expire: number } | null {
|
||||||
|
const token = decodeCookie('token');
|
||||||
|
const expireInString = decodeCookie('token_expire');
|
||||||
|
const expireIn = parseInt(expireInString, 10) | 0;
|
||||||
|
|
||||||
|
if (expireIn !== 0 && token !== '') {
|
||||||
|
return {token: token, expire: expireIn};
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* decode a simple cookie with key specified
|
||||||
|
* @param key cookie key
|
||||||
|
*/
|
||||||
|
function decodeCookie(key: string): string {
|
||||||
|
let name = key + "=";
|
||||||
|
let decodedCookie = decodeURIComponent(document.cookie);
|
||||||
|
let ca = decodedCookie.split(';');
|
||||||
|
for (let i = 0; i < ca.length; i++) {
|
||||||
|
let c = ca[i];
|
||||||
|
while (c.charAt(0) === ' ') {
|
||||||
|
c = c.substring(1);
|
||||||
|
}
|
||||||
|
if (c.indexOf(name) === 0) {
|
||||||
|
return c.substring(name.length, c.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if api token is valid -- if not request new one
|
||||||
|
* when finished call callback
|
||||||
|
* @param callback function to be called afterwards
|
||||||
|
*/
|
||||||
|
function checkAPITokenValid(callback: () => void): void {
|
||||||
|
// check if token is valid and set
|
||||||
|
if (apiToken === '' || expireSeconds <= new Date().getTime() / 1000) {
|
||||||
|
refreshAPIToken(() => {
|
||||||
|
callback()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A backend api call
|
* A backend api call
|
||||||
* @param apinode which api backend handler to call
|
* @param apinode which api backend handler to call
|
||||||
@ -50,12 +197,28 @@ interface ApiBaseRequest {
|
|||||||
* @param callback the callback with json reply from backend
|
* @param callback the callback with json reply from backend
|
||||||
* @param errorcallback a optional callback if an error occured
|
* @param errorcallback a optional callback if an error occured
|
||||||
*/
|
*/
|
||||||
export function callAPI<T>(apinode: APINode, fd: ApiBaseRequest, callback: (_: T) => void, errorcallback: (_: string) => void = (_: string): void => {}): void {
|
export function callAPI<T>(apinode: APINode,
|
||||||
fetch(getAPIDomain() + apinode, {method: 'POST', body: JSON.stringify(fd)})
|
fd: ApiBaseRequest,
|
||||||
.then((response) => response.json()
|
callback: (_: T) => void,
|
||||||
.then((result) => {
|
errorcallback: (_: string) => void = (_: string): void => {
|
||||||
callback(result);
|
}): void {
|
||||||
})).catch(reason => errorcallback(reason));
|
checkAPITokenValid(() => {
|
||||||
|
fetch(getAPIDomain() + apinode, {
|
||||||
|
method: 'POST', body: JSON.stringify(fd), headers: new Headers({
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'Bearer ' + apiToken,
|
||||||
|
}),
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.log('Error: ' + response.statusText);
|
||||||
|
// todo place error popup here
|
||||||
|
} else {
|
||||||
|
response.json().then((result: T) => {
|
||||||
|
callback(result);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}).catch(reason => errorcallback(reason));
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,12 +228,18 @@ export function callAPI<T>(apinode: APINode, fd: ApiBaseRequest, callback: (_: T
|
|||||||
* @param callback the callback with PLAIN text reply from backend
|
* @param callback the callback with PLAIN text reply from backend
|
||||||
*/
|
*/
|
||||||
export function callAPIPlain(apinode: APINode, fd: ApiBaseRequest, callback: (_: string) => void): void {
|
export function callAPIPlain(apinode: APINode, fd: ApiBaseRequest, callback: (_: string) => void): void {
|
||||||
fetch(getAPIDomain() + apinode, {method: 'POST', body: JSON.stringify(fd)})
|
checkAPITokenValid(() => {
|
||||||
.then((response) => response.text()
|
fetch(getAPIDomain() + apinode, {
|
||||||
.then((result) => {
|
method: 'POST', body: JSON.stringify(fd), headers: new Headers({
|
||||||
callback(result);
|
'Content-Type': 'application/json',
|
||||||
}));
|
'Authorization': 'Bearer ' + apiToken,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => response.text()
|
||||||
|
.then((result) => {
|
||||||
|
callback(result);
|
||||||
|
}));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user