Skip to content

Commit

Permalink
Merge pull request kubenav#304 from kubenav/allow-additional-oidc-scopes
Browse files Browse the repository at this point in the history
Allow additional OIDC scopes
  • Loading branch information
ricoberger authored Feb 15, 2021
2 parents 4eea3d8 + 71adfbc commit 49bf3b8
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 4 deletions.
20 changes: 17 additions & 3 deletions pkg/api/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
"net/http"
"strings"

"github.com/kubenav/kubenav/pkg/api/middleware"

Expand All @@ -23,6 +24,7 @@ type OIDCRequest struct {
RedirectURL string `json:"redirectURL"`
RefreshToken string `json:"refreshToken"`
Code string `json:"code"`
Scopes string `json:"scopes"`
}

// OIDCResponse is the structure of a response for one of the OIDC methods.
Expand Down Expand Up @@ -64,12 +66,16 @@ func (c *Client) oidcGetLinkHandler(w http.ResponseWriter, r *http.Request) {
return
}

oidcRequest.Scopes = strings.ReplaceAll(oidcRequest.Scopes, " ", "")
scopes := strings.Split(oidcRequest.Scopes, ",")
scopes = append(scopes, oidc.ScopeOpenID)

oauth2Config := oauth2.Config{
ClientID: oidcRequest.ClientID,
ClientSecret: oidcRequest.ClientSecret,
RedirectURL: oidcRequest.RedirectURL,
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID},
Scopes: scopes,
}

oidcResponse := OIDCResponse{
Expand Down Expand Up @@ -111,12 +117,16 @@ func (c *Client) oidcGetRefreshTokenHandler(w http.ResponseWriter, r *http.Reque
return
}

oidcRequest.Scopes = strings.ReplaceAll(oidcRequest.Scopes, " ", "")
scopes := strings.Split(oidcRequest.Scopes, ",")
scopes = append(scopes, oidc.ScopeOpenID)

oauth2Config := oauth2.Config{
ClientID: oidcRequest.ClientID,
ClientSecret: oidcRequest.ClientSecret,
RedirectURL: oidcRequest.RedirectURL,
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID},
Scopes: scopes,
}

oauth2Token, err := oauth2Config.Exchange(ctx, oidcRequest.Code)
Expand Down Expand Up @@ -172,12 +182,16 @@ func (c *Client) oidcGetAccessTokenHandler(w http.ResponseWriter, r *http.Reques
return
}

oidcRequest.Scopes = strings.ReplaceAll(oidcRequest.Scopes, " ", "")
scopes := strings.Split(oidcRequest.Scopes, ",")
scopes = append(scopes, oidc.ScopeOpenID)

oauth2Config := oauth2.Config{
ClientID: oidcRequest.ClientID,
ClientSecret: oidcRequest.ClientSecret,
RedirectURL: oidcRequest.RedirectURL,
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID},
Scopes: scopes,
}

ts := oauth2Config.TokenSource(ctx, &oauth2.Token{RefreshToken: oidcRequest.RefreshToken})
Expand Down
11 changes: 11 additions & 0 deletions src/components/settings/clusters/EditCluster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ const EditCluster: React.FunctionComponent<IEditClusterProps> = ({ cluster, clos
authProviderOIDC.clientID,
authProviderOIDC.clientSecret,
authProviderOIDC.certificateAuthority,
authProviderOIDC.scopes,
);

setShowModal(false);
Expand Down Expand Up @@ -602,6 +603,16 @@ const EditCluster: React.FunctionComponent<IEditClusterProps> = ({ cluster, clos
onIonChange={handleAuthProviderOIDC}
/>
</IonItem>
<IonItem>
<IonLabel position="stacked">Scopes (optional)</IonLabel>
<IonInput
type="text"
required={true}
value={authProviderOIDC.scopes}
name="scopes"
onIonChange={handleAuthProviderOIDC}
/>
</IonItem>
<IonItem>
<IonLabel position="stacked">Certificate Authority (optional)</IonLabel>
<IonTextarea
Expand Down
12 changes: 11 additions & 1 deletion src/components/settings/clusters/oidc/OIDC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const OIDC: React.FunctionComponent<IOIDCProps> = ({ close, history }: IOIDCProp
const [discoveryURL, setDiscoveryURL] = useState<string>('');
const [clientID, setClientID] = useState<string>('');
const [clientSecret, setClientSecret] = useState<string>('');
const [scopes, setScopes] = useState<string>('');
const [certificateAuthority, setCertificateAuthority] = useState<string>('');
const [refreshToken, setRefreshToken] = useState<string>('');
const [error, setError] = useState<string>('');
Expand All @@ -42,6 +43,10 @@ const OIDC: React.FunctionComponent<IOIDCProps> = ({ close, history }: IOIDCProp
setClientSecret(event.target.value);
};

const handleScopes = (event) => {
setScopes(event.target.value);
};

const handleCertificateAuthority = (event) => {
setCertificateAuthority(event.target.value);
};
Expand All @@ -59,6 +64,7 @@ const OIDC: React.FunctionComponent<IOIDCProps> = ({ close, history }: IOIDCProp
saveTemporaryCredentials({
clientID: clientID,
clientSecret: clientSecret,
scopes: scopes,
idpIssuerURL: discoveryURL,
refreshToken: refreshToken,
certificateAuthority: ca,
Expand All @@ -72,7 +78,7 @@ const OIDC: React.FunctionComponent<IOIDCProps> = ({ close, history }: IOIDCProp
history.push('/settings/clusters/oidc');
} else {
try {
const url = await getOIDCLink(discoveryURL, clientID, clientSecret, ca);
const url = await getOIDCLink(discoveryURL, clientID, clientSecret, ca, scopes);
close();
window.location.replace(url);
} catch (err) {
Expand Down Expand Up @@ -114,6 +120,10 @@ const OIDC: React.FunctionComponent<IOIDCProps> = ({ close, history }: IOIDCProp
<IonLabel position="stacked">Client Secret</IonLabel>
<IonInput type="text" required={true} value={clientSecret} onInput={handleClientSecret} />
</IonItem>
<IonItem>
<IonLabel position="stacked">Scopes (optional)</IonLabel>
<IonInput type="text" required={true} value={scopes} onInput={handleScopes} />
</IonItem>
<IonItem>
<IonLabel position="stacked">Certificate Authority (optional)</IonLabel>
<IonTextarea autoGrow={true} value={certificateAuthority} onInput={handleCertificateAuthority} />
Expand Down
1 change: 1 addition & 0 deletions src/declarations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export interface IClusterAuthProviderGoogle {
export interface IClusterAuthProviderOIDC {
clientID: string;
clientSecret: string;
scopes?: string;
idToken: string;
idpIssuerURL: string;
refreshToken: string;
Expand Down
4 changes: 4 additions & 0 deletions src/utils/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,7 @@ export const getOIDCAccessToken = async (credentials: IClusterAuthProviderOIDC):
certificateAuthority: credentials.certificateAuthority ? credentials.certificateAuthority : '',
redirectURL: OIDC_REDIRECT_URL_WEB,
refreshToken: credentials.refreshToken,
scopes: credentials.scopes ? credentials.scopes : '',
}),
});

Expand Down Expand Up @@ -887,6 +888,7 @@ export const getOIDCLink = async (
clientID: string,
clientSecret: string,
certificateAuthority: string,
scopes?: string,
): Promise<string> => {
try {
await checkServer();
Expand All @@ -899,6 +901,7 @@ export const getOIDCLink = async (
clientSecret: clientSecret,
certificateAuthority: certificateAuthority,
redirectURL: OIDC_REDIRECT_URL_WEB,
scopes: scopes ? scopes : '',
}),
});

Expand Down Expand Up @@ -936,6 +939,7 @@ export const getOIDCRefreshToken = async (
certificateAuthority: credentials.certificateAuthority,
redirectURL: OIDC_REDIRECT_URL_WEB,
code: code,
scopes: credentials.scopes ? credentials.scopes : '',
}),
});

Expand Down

0 comments on commit 49bf3b8

Please sign in to comment.