mirror of
https://github.com/pomerium/pomerium.git
synced 2025-07-19 09:38:03 +02:00
urlutil: add version to query string
This commit is contained in:
parent
78a221cdbf
commit
076a5d2123
7 changed files with 167 additions and 96 deletions
|
@ -1,13 +1,74 @@
|
|||
package urlutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/version"
|
||||
"github.com/pomerium/pomerium/pkg/grpc/identity"
|
||||
"github.com/pomerium/pomerium/pkg/hpke"
|
||||
)
|
||||
|
||||
// DefaultDeviceType is the default device type when none is specified.
|
||||
const DefaultDeviceType = "any"
|
||||
|
||||
const signInExpiry = time.Minute * 5
|
||||
|
||||
// CallbackURL builds the callback URL using an HPKE encrypted query string.
|
||||
func CallbackURL(
|
||||
authenticatePrivateKey *hpke.PrivateKey,
|
||||
proxyPublicKey *hpke.PublicKey,
|
||||
requestParams url.Values,
|
||||
profile *identity.Profile,
|
||||
) (string, error) {
|
||||
redirectURL, err := ParseAndValidateURL(requestParams.Get(QueryRedirectURI))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid %s: %w", QueryRedirectURI, err)
|
||||
}
|
||||
|
||||
var callbackURL *url.URL
|
||||
if requestParams.Has(QueryCallbackURI) {
|
||||
callbackURL, err = ParseAndValidateURL(requestParams.Get(QueryCallbackURI))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid %s: %w", QueryCallbackURI, err)
|
||||
}
|
||||
} else {
|
||||
callbackURL, err = DeepCopy(redirectURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error copying %s: %w", QueryRedirectURI, err)
|
||||
}
|
||||
callbackURL.Path = "/.pomerium/callback/"
|
||||
callbackURL.RawQuery = ""
|
||||
}
|
||||
|
||||
callbackParams := callbackURL.Query()
|
||||
if requestParams.Has(QueryIsProgrammatic) {
|
||||
callbackParams.Set(QueryIsProgrammatic, "true")
|
||||
}
|
||||
callbackParams.Set(QueryRedirectURI, redirectURL.String())
|
||||
|
||||
rawProfile, err := protojson.Marshal(profile)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error marshaling identity profile: %w", err)
|
||||
}
|
||||
callbackParams.Set(QueryIdentityProfile, string(rawProfile))
|
||||
callbackParams.Set(QueryVersion, version.FullVersion())
|
||||
|
||||
BuildTimeParameters(callbackParams, signInExpiry)
|
||||
|
||||
callbackParams, err = hpke.EncryptURLValues(authenticatePrivateKey, proxyPublicKey, callbackParams)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error encrypting callback params: %w", err)
|
||||
}
|
||||
callbackURL.RawQuery = callbackParams.Encode()
|
||||
|
||||
return callbackURL.String(), nil
|
||||
}
|
||||
|
||||
// RedirectURL returns the redirect URL from the query string or a cookie.
|
||||
func RedirectURL(r *http.Request) (string, bool) {
|
||||
if v := r.FormValue(QueryRedirectURI); v != "" {
|
||||
|
@ -21,16 +82,42 @@ func RedirectURL(r *http.Request) (string, bool) {
|
|||
return "", false
|
||||
}
|
||||
|
||||
// SignInURL builds the sign in URL using an HPKE encrypted query string.
|
||||
func SignInURL(
|
||||
senderPrivateKey *hpke.PrivateKey,
|
||||
authenticatePublicKey *hpke.PublicKey,
|
||||
authenticateURL *url.URL,
|
||||
redirectURL *url.URL,
|
||||
idpID string,
|
||||
) (string, error) {
|
||||
signInURL := *authenticateURL
|
||||
signInURL.Path = "/.pomerium/sign_in"
|
||||
|
||||
q := signInURL.Query()
|
||||
q.Set(QueryRedirectURI, redirectURL.String())
|
||||
q.Set(QueryIdentityProviderID, idpID)
|
||||
q.Set(QueryVersion, version.FullVersion())
|
||||
BuildTimeParameters(q, signInExpiry)
|
||||
q, err := hpke.EncryptURLValues(senderPrivateKey, authenticatePublicKey, q)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
signInURL.RawQuery = q.Encode()
|
||||
|
||||
return signInURL.String(), nil
|
||||
}
|
||||
|
||||
// SignOutURL returns the /.pomerium/sign_out URL.
|
||||
func SignOutURL(r *http.Request, authenticateURL *url.URL, key []byte) string {
|
||||
u := authenticateURL.ResolveReference(&url.URL{
|
||||
Path: "/.pomerium/sign_out",
|
||||
})
|
||||
q := u.Query()
|
||||
if redirectURI, ok := RedirectURL(r); ok {
|
||||
u.RawQuery = (&url.Values{
|
||||
QueryRedirectURI: {redirectURI},
|
||||
}).Encode()
|
||||
q.Set(QueryRedirectURI, redirectURI)
|
||||
}
|
||||
q.Set(QueryVersion, version.FullVersion())
|
||||
u.RawQuery = q.Encode()
|
||||
return NewSignedURL(key, u).Sign().String()
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue