-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Experiment with JWT-based worker redirection
- Loading branch information
Showing
7 changed files
with
147 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,91 @@ | ||
package _responses | ||
|
||
import ( | ||
"crypto/rand" | ||
"crypto/rsa" | ||
"crypto/x509" | ||
"encoding/pem" | ||
"net/url" | ||
"os" | ||
"time" | ||
|
||
"github.com/go-jose/go-jose/v4" | ||
"github.com/go-jose/go-jose/v4/jwt" | ||
"github.com/t2bot/matrix-media-repo/api/_apimeta" | ||
"github.com/t2bot/matrix-media-repo/common/rcontext" | ||
) | ||
|
||
// TODO: Persist and store key (or use some other source of information) | ||
var jwtKey, keyErr = rsa.GenerateKey(rand.Reader, 2048) | ||
var jwtSig, jwtErr = jose.NewSigner(jose.SigningKey{Algorithm: jose.HS256, Key: []byte("0102030405060708090A0B0C0D0E0F10")}, (&jose.SignerOptions{}).WithType("JWT")) | ||
var jweEnc, jweErr = jose.NewEncrypter(jose.A128GCM, jose.Recipient{Algorithm: jose.RSA_OAEP, Key: &jwtKey.PublicKey}, nil) | ||
|
||
func init() { | ||
// We don't expect these to happen, so just panic | ||
if keyErr != nil { | ||
panic(keyErr) | ||
} | ||
if jwtErr != nil { | ||
panic(jwtErr) | ||
} | ||
if jweErr != nil { | ||
panic(jweErr) | ||
} | ||
|
||
f1, _ := os.Create("./gdpr-data/jwe.rsa") | ||
f2, _ := os.Create("./gdpr-data/jwe.rsa.pub") | ||
defer f1.Close() | ||
defer f2.Close() | ||
keyPem := pem.EncodeToMemory(&pem.Block{ | ||
Type: "RSA PRIVATE KEY", | ||
Bytes: x509.MarshalPKCS1PrivateKey(jwtKey), | ||
}) | ||
pubPem := pem.EncodeToMemory(&pem.Block{ | ||
Type: "RSA PUBLIC KEY", | ||
Bytes: x509.MarshalPKCS1PublicKey(&jwtKey.PublicKey), | ||
}) | ||
f1.Write(keyPem) | ||
f2.Write(pubPem) | ||
} | ||
|
||
type RedirectResponse struct { | ||
ToUrl string | ||
} | ||
|
||
func Redirect(url string) *RedirectResponse { | ||
return &RedirectResponse{ToUrl: url} | ||
func Redirect(ctx rcontext.RequestContext, toUrl string, auth _apimeta.AuthContext) *RedirectResponse { | ||
if auth.IsAuthenticated() { | ||
// Figure out who we're authenticating as, and add that as JWT claims | ||
claims := jwt.Claims{ | ||
Issuer: ctx.Request.Host, | ||
} | ||
moreClaims := struct { | ||
Admin bool `json:"adm,omitempty"` | ||
AccessToken string `json:"tok,omitempty"` | ||
}{} | ||
if auth.Server.ServerName != "" { | ||
claims.Subject = auth.Server.ServerName | ||
|
||
// The server won't necessarily re-auth itself with the redirect, so we just put an expiration on it instead | ||
claims.Expiry = jwt.NewNumericDate(time.Now().Add(2 * time.Minute)) | ||
} else { | ||
claims.Subject = auth.User.UserId | ||
moreClaims.Admin = auth.User.IsShared | ||
moreClaims.AccessToken = auth.User.AccessToken | ||
} | ||
raw, err := jwt.Encrypted(jweEnc).Claims(claims).Claims(moreClaims).Serialize() | ||
if err != nil { | ||
panic(err) // should never happen if we've done things correctly | ||
} | ||
|
||
// Now add the query string | ||
parsedUrl, err := url.Parse(toUrl) | ||
if err != nil { | ||
panic(err) // it wouldn't have worked anyways | ||
} | ||
qs := parsedUrl.Query() | ||
qs.Set("org.matrix.media_auth", raw) | ||
parsedUrl.RawQuery = qs.Encode() | ||
toUrl = parsedUrl.String() | ||
} | ||
return &RedirectResponse{ToUrl: toUrl} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package custom | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/t2bot/matrix-media-repo/api/_apimeta" | ||
"github.com/t2bot/matrix-media-repo/api/_responses" | ||
"github.com/t2bot/matrix-media-repo/api/_routers" | ||
"github.com/t2bot/matrix-media-repo/common/rcontext" | ||
"github.com/t2bot/matrix-media-repo/database" | ||
"github.com/t2bot/matrix-media-repo/datastores" | ||
"github.com/t2bot/matrix-media-repo/pipelines/_steps/download" | ||
) | ||
|
||
func GetMediaById(r *http.Request, rctx rcontext.RequestContext, user _apimeta.UserInfo) interface{} { | ||
if !user.IsShared { | ||
return _responses.AuthFailed() | ||
} | ||
|
||
// TODO: This is beyond dangerous and needs proper filtering | ||
|
||
db := database.GetInstance().Media.Prepare(rctx) | ||
ds, err := datastores.Pick(rctx, datastores.LocalMediaKind) | ||
if err != nil { | ||
panic(err) | ||
} | ||
objectId := _routers.GetParam("objectId", r) | ||
medias, err := db.GetByLocation(ds.Id, objectId) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
media := medias[0] | ||
stream, err := download.OpenStream(rctx, media.Locatable) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
return &_responses.DownloadResponse{ | ||
ContentType: media.ContentType, | ||
Filename: media.UploadName, | ||
SizeBytes: media.SizeBytes, | ||
Data: stream, | ||
TargetDisposition: "infer", | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters