Bind Feishu identity to OpenVPN sessions and refine management UI
This commit is contained in:
1 parent
347799cb1e
commit
8fd8c0cd73
27 files changed
+1556
-1011
No files matched your search
@@ -47,7 +47,7 @@ func TestFeishuExchangeUsesJSONAndRejectsUnexpectedIdentity(t *testing.T) {
|
||||
t.Fatalf("exchange: %q %v", token, err)
|
||||
}
|
||||
user, tenant, err := fetchFeishuUser(context.Background(), token)
|
||||
if err != nil || tenant != "tenant_1" || user.Subject != "tenant_1:ou_1" {
|
||||
if err != nil || tenant != "tenant_1" || user.Subject != "tenant_1:ou_1" || user.Name != "Alice" {
|
||||
t.Fatalf("identity: %+v %s %v", user, tenant, err)
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ func TestGrantSingleUseAndSignedToken(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
grant := codeData{requestState: requestState{ClientID: "opsx-vpn", Redirect: "https://vpn.example.com/oauth2/callback", Nonce: "nonce-1"}, Subject: "tenant:ou_1"}
|
||||
grant := codeData{requestState: requestState{ClientID: "opsx-vpn", Redirect: "https://vpn.example.com/oauth2/callback", Nonce: "nonce-1"}, Subject: "tenant:ou_1", Name: "Alice"}
|
||||
if err := saveGrant("code", code, grant, time.Minute); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func TestGrantSingleUseAndSignedToken(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var claims map[string]any
|
||||
if json.Unmarshal(claimsRaw, &claims) != nil || claims["sub"] != "tenant:ou_1" || claims["nonce"] != "nonce-1" || claims["aud"] != "opsx-vpn" {
|
||||
if json.Unmarshal(claimsRaw, &claims) != nil || claims["sub"] != "tenant:ou_1" || claims["name"] != "Alice" || claims["nonce"] != "nonce-1" || claims["aud"] != "opsx-vpn" {
|
||||
t.Fatalf("unexpected claims: %v", claims)
|
||||
}
|
||||
if info, err := filepath.Glob(filepath.Join(dir, "identity", "*.pem")); err != nil || len(info) != 1 {
|
||||
@@ -130,6 +130,33 @@ func TestGrantSingleUseAndSignedToken(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDTokenOmitsMissingDisplayName(t *testing.T) {
|
||||
t.Setenv("VPN_DATA_DIR", t.TempDir())
|
||||
key, kid, err := signingKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
token, err := signIDToken(key, kid, "https://vpn.example.com/id", model.IdentityProvider{ClientID: "opsx-vpn"}, codeData{Subject: "tenant:ou_1"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
parts := strings.Split(token, ".")
|
||||
if len(parts) != 3 {
|
||||
t.Fatal("invalid JWT")
|
||||
}
|
||||
body, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var claims map[string]any
|
||||
if json.Unmarshal(body, &claims) != nil || claims["sub"] != "tenant:ou_1" {
|
||||
t.Fatalf("stable identity missing: %v", claims)
|
||||
}
|
||||
if _, present := claims["name"]; present {
|
||||
t.Fatal("empty display name should not be added to ID token")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRedirectIsExactAndNoOpenRedirect(t *testing.T) {
|
||||
if !validateRedirect("https://vpn.example.com/oauth2/callback", "vpn.example.com") {
|
||||
t.Fatal("valid callback rejected")
|
||||
|
||||
Reference in new issue
Block a user