2020-08-05 08:13:32 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/base64"
|
|
|
|
"encoding/json"
|
|
|
|
"io"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
2020-08-06 16:54:26 +00:00
|
|
|
"time"
|
2020-08-05 08:13:32 +00:00
|
|
|
|
2022-05-05 23:38:25 +00:00
|
|
|
"git.rootprojects.org/root/keypairs"
|
2020-08-05 08:13:32 +00:00
|
|
|
)
|
|
|
|
|
2020-08-06 16:54:26 +00:00
|
|
|
// Verify will verify both JWT and uncompressed JWS
|
2020-08-05 08:13:32 +00:00
|
|
|
func Verify(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if "POST" != r.Method {
|
|
|
|
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-05-05 23:38:25 +00:00
|
|
|
jws := &keypairs.JWS{}
|
2020-08-05 08:13:32 +00:00
|
|
|
|
|
|
|
authzParts := strings.Split(r.Header.Get("Authorization"), " ")
|
|
|
|
lenAuthz := len(authzParts)
|
|
|
|
if 2 == lenAuthz {
|
|
|
|
jwt := authzParts[1]
|
|
|
|
jwsParts := strings.Split(jwt, ".")
|
|
|
|
if 3 == len(jwsParts) {
|
2020-08-17 23:14:09 +00:00
|
|
|
jws.Protected = jwsParts[0]
|
|
|
|
jws.Payload = jwsParts[1]
|
|
|
|
jws.Signature = jwsParts[2]
|
2020-08-05 08:13:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if nil == jws {
|
|
|
|
if 0 != lenAuthz {
|
|
|
|
http.Error(w, "Bad Request: malformed Authorization header", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
decoder := json.NewDecoder(r.Body)
|
2020-08-17 23:14:09 +00:00
|
|
|
err := decoder.Decode(jws)
|
2020-08-05 08:13:32 +00:00
|
|
|
if nil != err && io.EOF != err {
|
|
|
|
log.Printf("json decode error: %s", err)
|
|
|
|
http.Error(w, "Bad Request: invalid JWS body", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
defer r.Body.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
protected, err := base64.RawURLEncoding.DecodeString(jws.Protected)
|
|
|
|
if nil != err {
|
|
|
|
http.Error(w, "Bad Request: invalid JWS header base64Url encoding", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if err := json.Unmarshal([]byte(protected), &jws.Header); nil != err {
|
2020-08-06 16:54:26 +00:00
|
|
|
log.Printf("json decode header error: %s", err)
|
2020-08-05 08:13:32 +00:00
|
|
|
http.Error(w, "Bad Request: invalid JWS header", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
payload, err := base64.RawURLEncoding.DecodeString(jws.Payload)
|
|
|
|
if nil != err {
|
|
|
|
http.Error(w, "Bad Request: invalid JWS payload base64Url encoding", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if err := json.Unmarshal([]byte(payload), &jws.Claims); nil != err {
|
2020-08-06 16:54:26 +00:00
|
|
|
log.Printf("json decode claims error: %s", err)
|
2020-08-05 08:13:32 +00:00
|
|
|
http.Error(w, "Bad Request: invalid JWS claims", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-08-06 16:54:26 +00:00
|
|
|
if "false" == r.URL.Query().Get("exp") {
|
|
|
|
//expf64, _ := jws.Claims["exp"].(float64)
|
|
|
|
jws.Claims["exp"] = float64(time.Now().Add(5 * time.Minute).Unix())
|
|
|
|
}
|
|
|
|
|
2022-05-05 23:38:25 +00:00
|
|
|
errs := keypairs.VerifyClaims(nil, jws)
|
|
|
|
if 0 == len(errs) {
|
|
|
|
log.Printf("jws verify error: %s", errs)
|
2020-08-05 08:13:32 +00:00
|
|
|
http.Error(w, "Bad Request: could not verify JWS claims", http.StatusBadRequest)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
b := []byte(`{"success":true}`)
|
|
|
|
w.Write(append(b, '\n'))
|
|
|
|
}
|