diff --git a/apiGo/api/ApiBase.go b/apiGo/api/ApiBase.go
index d404141..d77f086 100644
--- a/apiGo/api/ApiBase.go
+++ b/apiGo/api/ApiBase.go
@@ -6,6 +6,7 @@ import (
"fmt"
"log"
"net/http"
+ "openmediacenter/apiGo/api/oauth"
)
const APIPREFIX = "/api"
@@ -36,10 +37,13 @@ func AddHandler(action string, apiNode int, n interface{}, h func() []byte) {
}
func ServerInit(port uint16) {
- http.Handle(APIPREFIX+"/video", http.HandlerFunc(videoHandler))
- http.Handle(APIPREFIX+"/tags", http.HandlerFunc(tagHandler))
- http.Handle(APIPREFIX+"/settings", http.HandlerFunc(settingsHandler))
- http.Handle(APIPREFIX+"/actor", http.HandlerFunc(actorHandler))
+ http.Handle(APIPREFIX+"/video", oauth.ValidateToken(videoHandler))
+ http.Handle(APIPREFIX+"/tags", oauth.ValidateToken(tagHandler))
+ http.Handle(APIPREFIX+"/settings", oauth.ValidateToken(settingsHandler))
+ 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)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
diff --git a/apiGo/api/oauth/Oauth.go b/apiGo/api/oauth/Oauth.go
new file mode 100644
index 0000000..0ecacc7
--- /dev/null
+++ b/apiGo/api/oauth/Oauth.go
@@ -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)
+ }
+}
diff --git a/apiGo/go.mod b/apiGo/go.mod
index 3826c84..28d8db6 100644
--- a/apiGo/go.mod
+++ b/apiGo/go.mod
@@ -2,4 +2,8 @@ module openmediacenter/apiGo
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
+)
diff --git a/apiGo/go.sum b/apiGo/go.sum
index d314899..b0f2563 100644
--- a/apiGo/go.sum
+++ b/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/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=
diff --git a/src/elements/ActorTile/ActorTile.test.js b/src/elements/ActorTile/ActorTile.test.js
index 47eef82..9e8907d 100644
--- a/src/elements/ActorTile/ActorTile.test.js
+++ b/src/elements/ActorTile/ActorTile.test.js
@@ -12,12 +12,8 @@ describe('', function () {
const func = jest.fn((_) => {});
const wrapper = shallow( func()}/>);
- const func1 = jest.fn();
- prepareViewBinding(func1);
-
wrapper.simulate('click');
- expect(func1).toBeCalledTimes(0);
expect(func).toBeCalledTimes(1);
});
});
diff --git a/src/setupTests.js b/src/setupTests.js
index 33c35f7..2135359 100644
--- a/src/setupTests.js
+++ b/src/setupTests.js
@@ -19,7 +19,8 @@ global.prepareFetchApi = (response) => {
const mockJsonPromise = Promise.resolve(response);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
- text: () => mockJsonPromise
+ text: () => mockJsonPromise,
+ status: 200
});
return (jest.fn().mockImplementation(() => mockFetchPromise));
};
@@ -33,19 +34,6 @@ global.prepareFailingFetchApi = () => {
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) => {
const helpers = require('./utils/Api');
helpers.callAPI = jest.fn().mockImplementation((_, __, func1) => {func1(resonse);});
diff --git a/src/utils/Api.ts b/src/utils/Api.ts
index 23102a9..bb72ef3 100644
--- a/src/utils/Api.ts
+++ b/src/utils/Api.ts
@@ -43,6 +43,153 @@ interface ApiBaseRequest {
[_: 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
* @param apinode which api backend handler to call
@@ -50,12 +197,28 @@ interface ApiBaseRequest {
* @param callback the callback with json reply from backend
* @param errorcallback a optional callback if an error occured
*/
-export function callAPI(apinode: APINode, fd: ApiBaseRequest, callback: (_: T) => void, errorcallback: (_: string) => void = (_: string): void => {}): void {
- fetch(getAPIDomain() + apinode, {method: 'POST', body: JSON.stringify(fd)})
- .then((response) => response.json()
- .then((result) => {
- callback(result);
- })).catch(reason => errorcallback(reason));
+export function callAPI(apinode: APINode,
+ fd: ApiBaseRequest,
+ callback: (_: T) => void,
+ errorcallback: (_: string) => void = (_: string): void => {
+ }): void {
+ 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(apinode: APINode, fd: ApiBaseRequest, callback: (_: T
* @param callback the callback with PLAIN text reply from backend
*/
export function callAPIPlain(apinode: APINode, fd: ApiBaseRequest, callback: (_: string) => void): void {
- fetch(getAPIDomain() + apinode, {method: 'POST', body: JSON.stringify(fd)})
- .then((response) => response.text()
- .then((result) => {
- callback(result);
- }));
-
+ checkAPITokenValid(() => {
+ fetch(getAPIDomain() + apinode, {
+ method: 'POST', body: JSON.stringify(fd), headers: new Headers({
+ 'Content-Type': 'application/json',
+ 'Authorization': 'Bearer ' + apiToken,
+ })
+ })
+ .then((response) => response.text()
+ .then((result) => {
+ callback(result);
+ }));
+ });
}
/**