Commit a32b62f2 authored by Juergen Enge's avatar Juergen Enge
Browse files

poster in player

parent 75beac92
Pipeline #15667 passed with stages
in 3 minutes and 43 seconds
...@@ -35,7 +35,9 @@ delivers json file with testdata (including available metadata) ...@@ -35,7 +35,9 @@ delivers json file with testdata (including available metadata)
https://media.memobase.k8s.unibas.ch/memo/<signature>/<command> https://media.memobase.k8s.unibas.ch/memo/<signature>/<command>
Token Subject: ```<signature>``` Token Subject: ```<signature>```
With fallback additional token claim: ```fb = <fallback-signature>```
* master * master
......
...@@ -12,9 +12,9 @@ cmdprefix = "/command/" ...@@ -12,9 +12,9 @@ cmdprefix = "/command/"
jwtkey = "swordfish" jwtkey = "swordfish"
jwtalg = ["HS256", "HS384", "HS512"] # "hs256" "hs384" "hs512" "es256" "es384" "es512" "ps256" "ps384" "ps512" jwtalg = ["HS256", "HS384", "HS512"] # "hs256" "hs384" "hs512" "es256" "es384" "es512" "ps256" "ps384" "ps512"
resolverCacheSize = 1000 resolverCacheSize = 1000
errorTemplate = "C:/daten/go/dev/memobase/streaming-server/web/template/error.gohtml" # error message for memoHandler errorTemplate = "C:/daten/go/src/gitlab.switch.ch/memoriav/memobase-2020/services/streaming-server/web/template/error.gohtml" # error message for memoHandler
videoviewertemplate = "C:/daten/go/dev/memobase/streaming-server/web/template/videojs.gohtml" videoviewertemplate = "C:/daten/go/src/gitlab.switch.ch/memoriav/memobase-2020/services/streaming-server/web/template/videojs.gohtml"
audioviewertemplate = "C:/daten/go/dev/memobase/streaming-server/web/template/audiohowler.gohtml" audioviewertemplate = "C:/daten/go/src/gitlab.switch.ch/memoriav/memobase-2020/services/streaming-server/web/template/audiohowler.gohtml"
baseurl = "http://localhost:88" baseurl = "http://localhost:88"
[[filemap]] [[filemap]]
......
...@@ -31,8 +31,15 @@ func (av *ActionVideo) viewer(w http.ResponseWriter, req *http.Request, me *Medi ...@@ -31,8 +31,15 @@ func (av *ActionVideo) viewer(w http.ResponseWriter, req *http.Request, me *Medi
type vData struct { type vData struct {
BackgroundColor string BackgroundColor string
VideoSource string VideoSource string
PosterSource string
VideoType string VideoType string
} }
scheme := "http"
if req.TLS != nil {
scheme = "https"
}
var err error var err error
newtoken := "" newtoken := ""
if me.Access != Media_Public { if me.Access != Media_Public {
...@@ -41,11 +48,25 @@ func (av *ActionVideo) viewer(w http.ResponseWriter, req *http.Request, me *Medi ...@@ -41,11 +48,25 @@ func (av *ActionVideo) viewer(w http.ResponseWriter, req *http.Request, me *Medi
return false, fmt.Errorf("Cannot create token: %v", err) return false, fmt.Errorf("Cannot create token: %v", err)
} }
} }
posterurl := ""
scheme := "http" poster, err := av.ms.resolver.resolve(me.Signature + "-poster")
if req.TLS != nil { if err == nil {
scheme = "https" posterurl = fmt.Sprintf("%s://%s/%s/%s/resize/size%vx%v/formatJPEG",
scheme,
req.Host,
strings.Trim(av.ms.urlPrefix, "/"),
poster.Signature,
poster.Width,
poster.Height)
if poster.Access != Media_Public {
postertoken, err := NewJWT(av.ms.jwtSecret, poster.Signature, av.ms.jwtAlg[0], 7200, "", "")
if err != nil {
return false, fmt.Errorf("Cannot create token: %v", err)
}
posterurl += fmt.Sprintf("?auth=%v", postertoken)
}
} }
data := vData{ data := vData{
BackgroundColor: "#000000", BackgroundColor: "#000000",
VideoSource: fmt.Sprintf("%s://%s/%s/%s/master?auth=%s", VideoSource: fmt.Sprintf("%s://%s/%s/%s/master?auth=%s",
...@@ -54,7 +75,8 @@ func (av *ActionVideo) viewer(w http.ResponseWriter, req *http.Request, me *Medi ...@@ -54,7 +75,8 @@ func (av *ActionVideo) viewer(w http.ResponseWriter, req *http.Request, me *Medi
strings.Trim(av.ms.urlPrefix, "/"), strings.Trim(av.ms.urlPrefix, "/"),
me.Signature, me.Signature,
newtoken), newtoken),
VideoType: "video/mp4", PosterSource: posterurl,
VideoType: "video/mp4",
} }
av.ms.videoViewerTemplate.Execute(w, data) av.ms.videoViewerTemplate.Execute(w, data)
return true, nil return true, nil
......
...@@ -47,7 +47,7 @@ func NameFromUri(uri url.URL) string { ...@@ -47,7 +47,7 @@ func NameFromUri(uri url.URL) string {
return parts[l-1] return parts[l-1]
} }
func CheckRequestJWT(req *http.Request, secret string, alg []string, subject string) error { func CheckRequestJWT(req *http.Request, secret string, alg []string, subject string, subClaim string) error {
var token []string var token []string
var ok bool var ok bool
...@@ -70,13 +70,13 @@ func CheckRequestJWT(req *http.Request, secret string, alg []string, subject str ...@@ -70,13 +70,13 @@ func CheckRequestJWT(req *http.Request, secret string, alg []string, subject str
return errors.New(fmt.Sprintf("Access denied: no jwt token found")) return errors.New(fmt.Sprintf("Access denied: no jwt token found"))
} }
} }
if err := CheckJWT(token[0], secret, alg, subject); err != nil { if err := CheckJWT(token[0], secret, alg, subject, subClaim); err != nil {
return emperror.Wrapf(err, "Access denied: token check failed") return emperror.Wrapf(err, "Access denied: token check failed")
} }
return nil return nil
} }
func CheckJWT(tokenstring string, secret string, alg []string, subject string) error { func CheckJWT(tokenstring string, secret string, alg []string, subject string, subClaim string) error {
subject = strings.TrimRight(strings.ToLower(subject), "/") subject = strings.TrimRight(strings.ToLower(subject), "/")
token, err := jwt.Parse(tokenstring, func(token *jwt.Token) (interface{}, error) { token, err := jwt.Parse(tokenstring, func(token *jwt.Token) (interface{}, error) {
talg := token.Method.Alg() talg := token.Method.Alg()
...@@ -100,7 +100,7 @@ func CheckJWT(tokenstring string, secret string, alg []string, subject string) e ...@@ -100,7 +100,7 @@ func CheckJWT(tokenstring string, secret string, alg []string, subject string) e
if !ok { if !ok {
return fmt.Errorf("Cannot mapUri claims from token [sub:%s]", subject) return fmt.Errorf("Cannot mapUri claims from token [sub:%s]", subject)
} }
if strings.ToLower(claims["sub"].(string)) == subject { if strings.ToLower(claims[subClaim].(string)) == subject {
return nil return nil
} else { } else {
return fmt.Errorf("Invalid subject [%s]. Should be [%s]", claims["sub"].(string), subject) return fmt.Errorf("Invalid subject [%s]. Should be [%s]", claims["sub"].(string), subject)
......
...@@ -120,7 +120,7 @@ func (ms *memoServer) commandHandler(w http.ResponseWriter, req *http.Request) { ...@@ -120,7 +120,7 @@ func (ms *memoServer) commandHandler(w http.ResponseWriter, req *http.Request) {
http.Error(w, errStr, http.StatusNotFound) http.Error(w, errStr, http.StatusNotFound)
return return
} }
if err := CheckRequestJWT(req, ms.jwtSecret, ms.jwtAlg, "cmd:"+cmd); err != nil { if err := CheckRequestJWT(req, ms.jwtSecret, ms.jwtAlg, "cmd:"+cmd, "sub"); err != nil {
errStr := fmt.Sprintf("Access denied: token check failed: %v", err) errStr := fmt.Sprintf("Access denied: token check failed: %v", err)
ms.log.Error(errStr) ms.log.Error(errStr)
http.Error(w, errStr, http.StatusForbidden) http.Error(w, errStr, http.StatusForbidden)
......
...@@ -111,7 +111,7 @@ func (ms *memoServer) HandlerIIIF(writer http.ResponseWriter, req *http.Request) ...@@ -111,7 +111,7 @@ func (ms *memoServer) HandlerIIIF(writer http.ResponseWriter, req *http.Request)
return return
} }
if me.Access != Media_Public { if me.Access != Media_Public {
if err := CheckJWT(token, ms.jwtSecret, ms.jwtAlg, signature); err != nil { if err := CheckJWT(token, ms.jwtSecret, ms.jwtAlg, signature, "sub"); err != nil {
ms.DoPanicf(writer, http.StatusForbidden, "Access denied: token check failed: %v", err) ms.DoPanicf(writer, http.StatusForbidden, "Access denied: token check failed: %v", err)
return return
} }
......
...@@ -54,6 +54,7 @@ func (ms *memoServer) mainHandler(w http.ResponseWriter, req *http.Request) { ...@@ -54,6 +54,7 @@ func (ms *memoServer) mainHandler(w http.ResponseWriter, req *http.Request) {
paramstr, _ := vars["params"] paramstr, _ := vars["params"]
params := strings.Split(paramstr, "/") params := strings.Split(paramstr, "/")
subClaim := "sub"
// resolve signature // resolve signature
me, err := ms.resolver.resolve(signature) me, err := ms.resolver.resolve(signature)
if err != nil { if err != nil {
...@@ -66,18 +67,20 @@ func (ms *memoServer) mainHandler(w http.ResponseWriter, req *http.Request) { ...@@ -66,18 +67,20 @@ func (ms *memoServer) mainHandler(w http.ResponseWriter, req *http.Request) {
} }
} }
if fallback != "" { if fallback != "" {
// todo: check jwt for fallback
me, err = ms.resolver.resolve(fallback) me, err = ms.resolver.resolve(fallback)
if err != nil { if err != nil {
ms.DoPanicf(w, http.StatusNotFound, "signature %v and fallback %v not found: %v", signature, fallback, err) ms.DoPanicf(w, http.StatusNotFound, "signature %v and fallback %v not found: %v", signature, fallback, err)
return return
} }
subClaim = "fb"
} else { } else {
ms.DoPanicf(w, http.StatusNotFound, "signature %v not found: %v", signature, err) ms.DoPanicf(w, http.StatusNotFound, "signature %v not found: %v", signature, err)
return return
} }
} }
if me.Access != Media_Public { if me.Access != Media_Public {
if err := CheckRequestJWT(req, ms.jwtSecret, ms.jwtAlg, signature); err != nil { if err := CheckRequestJWT(req, ms.jwtSecret, ms.jwtAlg, signature, subClaim); err != nil {
ms.DoPanicf(w, http.StatusForbidden, "Access denied: token check failed: %v", err) ms.DoPanicf(w, http.StatusForbidden, "Access denied: token check failed: %v", err)
return return
} }
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
controls controls
preload="auto" preload="auto"
width="100vw" width="100vw"
height="100vw" height="100vw"{{if ne .PosterSource ""}}
poster="/web/static/memoriav_logo_400x400.jpg" poster="{{.PosterSource}}"{{end}}
data-setup="{}" data-setup="{}"
style="width: 100vw; height: 100vh"> style="width: 100vw; height: 100vh">
<source src="{{.VideoSource}}" type="{{.VideoType}}" /> <source src="{{.VideoSource}}" type="{{.VideoType}}" />
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment