mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-28 21:26:40 +00:00
Compare commits
3 Commits
feat/byod-
...
fix-darwin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69752b7cb7 | ||
|
|
6f0eff3ba0 | ||
|
|
f8745723fc |
@@ -193,7 +193,7 @@ func (c *Connector) ToStorageConnector() (storage.Connector, error) {
|
|||||||
// are stored with types that Dex can open.
|
// are stored with types that Dex can open.
|
||||||
func mapConnectorToDex(connType string, config map[string]interface{}) (string, map[string]interface{}) {
|
func mapConnectorToDex(connType string, config map[string]interface{}) (string, map[string]interface{}) {
|
||||||
switch connType {
|
switch connType {
|
||||||
case "oidc", "zitadel", "entra", "okta", "pocketid", "authentik", "keycloak":
|
case "oidc", "zitadel", "entra", "okta", "pocketid", "authentik", "keycloak", "adfs":
|
||||||
return "oidc", applyOIDCDefaults(connType, config)
|
return "oidc", applyOIDCDefaults(connType, config)
|
||||||
default:
|
default:
|
||||||
return connType, config
|
return connType, config
|
||||||
@@ -218,6 +218,8 @@ func applyOIDCDefaults(connType string, config map[string]interface{}) map[strin
|
|||||||
setDefault(augmented, "claimMapping", map[string]string{"email": "preferred_username"})
|
setDefault(augmented, "claimMapping", map[string]string{"email": "preferred_username"})
|
||||||
case "okta", "pocketid":
|
case "okta", "pocketid":
|
||||||
augmented["scopes"] = []string{"openid", "profile", "email", "groups"}
|
augmented["scopes"] = []string{"openid", "profile", "email", "groups"}
|
||||||
|
case "adfs":
|
||||||
|
augmented["scopes"] = []string{"openid", "profile", "email", "allatclaims"}
|
||||||
}
|
}
|
||||||
|
|
||||||
return augmented
|
return augmented
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ func (p *Provider) buildStorageConnector(cfg *ConnectorConfig) (storage.Connecto
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
switch cfg.Type {
|
switch cfg.Type {
|
||||||
case "oidc", "zitadel", "entra", "okta", "pocketid", "authentik", "keycloak":
|
case "oidc", "zitadel", "entra", "okta", "pocketid", "authentik", "keycloak", "adfs":
|
||||||
dexType = "oidc"
|
dexType = "oidc"
|
||||||
configData, err = buildOIDCConnectorConfig(cfg, redirectURI)
|
configData, err = buildOIDCConnectorConfig(cfg, redirectURI)
|
||||||
case "google":
|
case "google":
|
||||||
@@ -220,6 +220,8 @@ func buildOIDCConnectorConfig(cfg *ConnectorConfig, redirectURI string) ([]byte,
|
|||||||
oidcConfig["scopes"] = []string{"openid", "profile", "email", "groups"}
|
oidcConfig["scopes"] = []string{"openid", "profile", "email", "groups"}
|
||||||
case "pocketid":
|
case "pocketid":
|
||||||
oidcConfig["scopes"] = []string{"openid", "profile", "email", "groups"}
|
oidcConfig["scopes"] = []string{"openid", "profile", "email", "groups"}
|
||||||
|
case "adfs":
|
||||||
|
oidcConfig["scopes"] = []string{"openid", "profile", "email", "allatclaims"}
|
||||||
}
|
}
|
||||||
return encodeConnectorConfig(oidcConfig)
|
return encodeConnectorConfig(oidcConfig)
|
||||||
}
|
}
|
||||||
@@ -283,7 +285,7 @@ func inferIdentityProviderType(dexType, connectorID string, _ map[string]interfa
|
|||||||
// inferOIDCProviderType infers the specific OIDC provider from connector ID
|
// inferOIDCProviderType infers the specific OIDC provider from connector ID
|
||||||
func inferOIDCProviderType(connectorID string) string {
|
func inferOIDCProviderType(connectorID string) string {
|
||||||
connectorIDLower := strings.ToLower(connectorID)
|
connectorIDLower := strings.ToLower(connectorID)
|
||||||
for _, provider := range []string{"pocketid", "zitadel", "entra", "okta", "authentik", "keycloak"} {
|
for _, provider := range []string{"pocketid", "zitadel", "entra", "okta", "authentik", "keycloak", "adfs"} {
|
||||||
if strings.Contains(connectorIDLower, provider) {
|
if strings.Contains(connectorIDLower, provider) {
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ func identityProviderToConnectorConfig(idpConfig *types.IdentityProvider) *dex.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generateIdentityProviderID generates a unique ID for an identity provider.
|
// generateIdentityProviderID generates a unique ID for an identity provider.
|
||||||
// For specific provider types (okta, zitadel, entra, google, pocketid, microsoft),
|
// For specific provider types (okta, zitadel, entra, google, pocketid, microsoft, adfs),
|
||||||
// the ID is prefixed with the type name. Generic OIDC providers get no prefix.
|
// the ID is prefixed with the type name. Generic OIDC providers get no prefix.
|
||||||
func generateIdentityProviderID(idpType types.IdentityProviderType) string {
|
func generateIdentityProviderID(idpType types.IdentityProviderType) string {
|
||||||
id := xid.New().String()
|
id := xid.New().String()
|
||||||
@@ -296,6 +296,8 @@ func generateIdentityProviderID(idpType types.IdentityProviderType) string {
|
|||||||
return "authentik-" + id
|
return "authentik-" + id
|
||||||
case types.IdentityProviderTypeKeycloak:
|
case types.IdentityProviderTypeKeycloak:
|
||||||
return "keycloak-" + id
|
return "keycloak-" + id
|
||||||
|
case types.IdentityProviderTypeADFS:
|
||||||
|
return "adfs-" + id
|
||||||
default:
|
default:
|
||||||
// Generic OIDC - no prefix
|
// Generic OIDC - no prefix
|
||||||
return id
|
return id
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ const (
|
|||||||
IdentityProviderTypeAuthentik IdentityProviderType = "authentik"
|
IdentityProviderTypeAuthentik IdentityProviderType = "authentik"
|
||||||
// IdentityProviderTypeKeycloak is the Keycloak identity provider
|
// IdentityProviderTypeKeycloak is the Keycloak identity provider
|
||||||
IdentityProviderTypeKeycloak IdentityProviderType = "keycloak"
|
IdentityProviderTypeKeycloak IdentityProviderType = "keycloak"
|
||||||
|
// IdentityProviderTypeADFS is the Microsoft AD FS identity provider
|
||||||
|
IdentityProviderTypeADFS IdentityProviderType = "adfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IdentityProvider represents an identity provider configuration
|
// IdentityProvider represents an identity provider configuration
|
||||||
@@ -112,7 +114,8 @@ func (t IdentityProviderType) IsValid() bool {
|
|||||||
switch t {
|
switch t {
|
||||||
case IdentityProviderTypeOIDC, IdentityProviderTypeZitadel, IdentityProviderTypeEntra,
|
case IdentityProviderTypeOIDC, IdentityProviderTypeZitadel, IdentityProviderTypeEntra,
|
||||||
IdentityProviderTypeGoogle, IdentityProviderTypeOkta, IdentityProviderTypePocketID,
|
IdentityProviderTypeGoogle, IdentityProviderTypeOkta, IdentityProviderTypePocketID,
|
||||||
IdentityProviderTypeMicrosoft, IdentityProviderTypeAuthentik, IdentityProviderTypeKeycloak:
|
IdentityProviderTypeMicrosoft, IdentityProviderTypeAuthentik, IdentityProviderTypeKeycloak,
|
||||||
|
IdentityProviderTypeADFS:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
25
release_files/darwin-ui-uninstaller.sh
Normal file → Executable file
25
release_files/darwin-ui-uninstaller.sh
Normal file → Executable file
@@ -1,14 +1,19 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
export PATH=$PATH:/usr/local/bin
|
export PATH=$PATH:/usr/local/bin:/opt/homebrew/bin
|
||||||
|
|
||||||
# check if netbird is installed
|
NB_BIN=$(command -v netbird)
|
||||||
NB_BIN=$(which netbird)
|
if [ -n "$NB_BIN" ]; then
|
||||||
if [ -z "$NB_BIN" ]
|
echo "Stopping NetBird daemon"
|
||||||
then
|
"$NB_BIN" service stop 2>/dev/null || true
|
||||||
exit 0
|
echo "Uninstalling NetBird daemon"
|
||||||
|
"$NB_BIN" service uninstall 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
# start netbird daemon service
|
|
||||||
echo "netbird daemon service still running. You can uninstall it by running: "
|
PLIST=/Library/LaunchDaemons/netbird.plist
|
||||||
echo "sudo netbird service stop"
|
if [ -f "$PLIST" ]; then
|
||||||
echo "sudo netbird service uninstall"
|
launchctl bootout system "$PLIST" 2>/dev/null || launchctl unload "$PLIST" 2>/dev/null || true
|
||||||
|
rm -f "$PLIST"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|||||||
@@ -146,7 +146,11 @@ func (c *ClaimsExtractor) ToGroups(token *jwt.Token, claimName string) []string
|
|||||||
userJWTGroups := make([]string, 0)
|
userJWTGroups := make([]string, 0)
|
||||||
|
|
||||||
if claim, ok := claims[claimName]; ok {
|
if claim, ok := claims[claimName]; ok {
|
||||||
if claimGroups, ok := claim.([]interface{}); ok {
|
switch claimGroups := claim.(type) {
|
||||||
|
case string:
|
||||||
|
// Some IdPs emit a single group claim as a string instead of an array.
|
||||||
|
userJWTGroups = append(userJWTGroups, claimGroups)
|
||||||
|
case []any:
|
||||||
for _, g := range claimGroups {
|
for _, g := range claimGroups {
|
||||||
if group, ok := g.(string); ok {
|
if group, ok := g.(string); ok {
|
||||||
userJWTGroups = append(userJWTGroups, group)
|
userJWTGroups = append(userJWTGroups, group)
|
||||||
@@ -154,9 +158,11 @@ func (c *ClaimsExtractor) ToGroups(token *jwt.Token, claimName string) []string
|
|||||||
log.Debugf("JWT claim %q contains a non-string group (type: %T): %v", claimName, g, g)
|
log.Debugf("JWT claim %q contains a non-string group (type: %T): %v", claimName, g, g)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
log.Debugf("JWT claim %q is not a string or string array (type: %T): %v", claimName, claim, claim)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("JWT claim %q is not a string array", claimName)
|
log.Debugf("JWT claim %q is missing", claimName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return userJWTGroups
|
return userJWTGroups
|
||||||
|
|||||||
@@ -249,6 +249,15 @@ func TestClaimsExtractor_ToGroups(t *testing.T) {
|
|||||||
groupClaimName: "groups",
|
groupClaimName: "groups",
|
||||||
expectedGroups: []string{},
|
expectedGroups: []string{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "extracts single group string from claim",
|
||||||
|
claims: jwt.MapClaims{
|
||||||
|
"sub": "user-123",
|
||||||
|
"groups": "admin",
|
||||||
|
},
|
||||||
|
groupClaimName: "groups",
|
||||||
|
expectedGroups: []string{"admin"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "handles custom claim name",
|
name: "handles custom claim name",
|
||||||
claims: jwt.MapClaims{
|
claims: jwt.MapClaims{
|
||||||
|
|||||||
@@ -2917,6 +2917,7 @@ components:
|
|||||||
- okta
|
- okta
|
||||||
- pocketid
|
- pocketid
|
||||||
- microsoft
|
- microsoft
|
||||||
|
- adfs
|
||||||
example: oidc
|
example: oidc
|
||||||
IdentityProvider:
|
IdentityProvider:
|
||||||
type: object
|
type: object
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ const (
|
|||||||
IdentityProviderTypeOkta IdentityProviderType = "okta"
|
IdentityProviderTypeOkta IdentityProviderType = "okta"
|
||||||
IdentityProviderTypePocketid IdentityProviderType = "pocketid"
|
IdentityProviderTypePocketid IdentityProviderType = "pocketid"
|
||||||
IdentityProviderTypeZitadel IdentityProviderType = "zitadel"
|
IdentityProviderTypeZitadel IdentityProviderType = "zitadel"
|
||||||
|
IdentityProviderTypeAdfs IdentityProviderType = "adfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Valid indicates whether the value is a known member of the IdentityProviderType enum.
|
// Valid indicates whether the value is a known member of the IdentityProviderType enum.
|
||||||
@@ -537,6 +538,8 @@ func (e IdentityProviderType) Valid() bool {
|
|||||||
return true
|
return true
|
||||||
case IdentityProviderTypeZitadel:
|
case IdentityProviderTypeZitadel:
|
||||||
return true
|
return true
|
||||||
|
case IdentityProviderTypeAdfs:
|
||||||
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user