mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 08:01:35 +00:00
fix: oauth settings for github and gitlab (#3219)
* fix: oauth settings for github and gitlab * toggle only in SSO * fix oauth user toggle
This commit is contained in:
committed by
GitHub
parent
af1b4c0dde
commit
e762fbe2cd
@@ -28,6 +28,9 @@
|
||||
|
||||
let values: Record<string, any> = {}
|
||||
let initialOauths: Record<string, any> = {}
|
||||
let initialRequirePreexistingUserForOauth: boolean = false
|
||||
let requirePreexistingUserForOauth: boolean = false
|
||||
let ssoOrOauth: 'sso' | 'oauth' = 'sso'
|
||||
|
||||
let serverConfig = {}
|
||||
let initialValues: Record<string, any> = {}
|
||||
@@ -47,6 +50,9 @@
|
||||
}
|
||||
}
|
||||
initialOauths = (await SettingService.getGlobal({ key: 'oauths' })) ?? {}
|
||||
requirePreexistingUserForOauth =
|
||||
(await SettingService.getGlobal({ key: 'require_preexisting_user_for_oauth' })) ?? false
|
||||
initialRequirePreexistingUserForOauth = requirePreexistingUserForOauth
|
||||
oauths = JSON.parse(JSON.stringify(initialOauths))
|
||||
initialValues = Object.fromEntries(
|
||||
(
|
||||
@@ -111,6 +117,12 @@
|
||||
})
|
||||
initialOauths = JSON.parse(JSON.stringify(oauths))
|
||||
}
|
||||
if (initialRequirePreexistingUserForOauth !== requirePreexistingUserForOauth) {
|
||||
await SettingService.setGlobal({
|
||||
key: 'require_preexisting_user_for_oauth',
|
||||
requestBody: { value: requirePreexistingUserForOauth }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
console.error('Values not loaded')
|
||||
}
|
||||
@@ -201,34 +213,121 @@
|
||||
{/if}
|
||||
{/if}
|
||||
{#if category == 'SSO/OAuth'}
|
||||
<div class="mb-6">
|
||||
<h4 class="pb-4">SSO</h4>
|
||||
{#if !$enterpriseLicense || $enterpriseLicense.endsWith('_pro')}
|
||||
<Alert type="warning" title="Limited to 10 SSO users">
|
||||
Without EE, the number of SSO users is limited to 10. SCIM/SAML is available on EE
|
||||
</Alert>
|
||||
{/if}
|
||||
<div>
|
||||
<Tabs bind:selected={ssoOrOauth} class="mt-2 mb-4">
|
||||
<Tab value="sso">SSO</Tab>
|
||||
<Tab value="oauth">OAuth</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
|
||||
<div class="mb-6">
|
||||
{#if ssoOrOauth === 'sso'}
|
||||
{#if !$enterpriseLicense || $enterpriseLicense.endsWith('_pro')}
|
||||
<Alert type="warning" title="Limited to 10 SSO users">
|
||||
Without EE, the number of SSO users is limited to 10. SCIM/SAML is available on
|
||||
EE
|
||||
</Alert>
|
||||
{/if}
|
||||
|
||||
<div class="py-1" />
|
||||
<Alert type="info" title="Single Sign On">
|
||||
When at least one of the below option is set, users will be able to login to
|
||||
Windmill via their third-party account.
|
||||
<br /> To test SSO, the recommended workflow is to to save the settings and try to
|
||||
login in an incognito window.
|
||||
</Alert>
|
||||
<div class="flex flex-col gap-2 py-4">
|
||||
<OAuthSetting name="google" bind:value={oauths['google']} />
|
||||
<OAuthSetting name="microsoft" bind:value={oauths['microsoft']} />
|
||||
<OktaSetting bind:value={oauths['okta']} />
|
||||
<OAuthSetting name="github" bind:value={oauths['github']} />
|
||||
<OAuthSetting name="gitlab" bind:value={oauths['gitlab']} />
|
||||
<OAuthSetting name="jumpcloud" bind:value={oauths['jumpcloud']} />
|
||||
<KeycloakSetting bind:value={oauths['keycloak']} />
|
||||
<AuthentikSetting bind:value={oauths['authentik']} />
|
||||
<AutheliaSetting bind:value={oauths['authelia']} />
|
||||
<KanidmSetting bind:value={oauths['kanidm']} />
|
||||
<ZitadelSetting bind:value={oauths['zitadel']} />
|
||||
{#each Object.keys(oauths) as k}
|
||||
{#if !['authelia', 'authentik', 'google', 'microsoft', 'github', 'gitlab', 'jumpcloud', 'okta', 'keycloak', 'slack', 'kanidm', 'zitadel'].includes(k) && 'login_config' in oauths[k]}
|
||||
{#if oauths[k]}
|
||||
<div class="flex flex-col gap-2 pb-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<label class="text-md font-medium text-primary">{k}</label>
|
||||
<CloseButton
|
||||
on:close={() => {
|
||||
delete oauths[k]
|
||||
oauths = { ...oauths }
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="p-2 border rounded">
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Id</span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Client Id"
|
||||
bind:value={oauths[k]['id']}
|
||||
/>
|
||||
</label>
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Secret</span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Client Secret"
|
||||
bind:value={oauths[k]['secret']}
|
||||
/>
|
||||
</label>
|
||||
{#if !windmillBuiltins.includes(k) && k != 'slack'}
|
||||
<CustomSso bind:login_config={oauths[k]['login_config']} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
<div class="flex gap-2 py-4">
|
||||
<input type="text" placeholder="client_id" bind:value={clientName} />
|
||||
<Button
|
||||
variant="border"
|
||||
color="blue"
|
||||
hover="yo"
|
||||
size="sm"
|
||||
endIcon={{ icon: Plus }}
|
||||
disabled={clientName == ''}
|
||||
on:click={() => {
|
||||
oauths[clientName] = { id: '', secret: '', login_config: {} }
|
||||
clientName = ''
|
||||
}}
|
||||
>
|
||||
Add custom SSO client {!$enterpriseLicense ? '(requires ee)' : ''}
|
||||
</Button>
|
||||
</div>
|
||||
<div class="flex gap-2 py-4">
|
||||
<Toggle
|
||||
options={{
|
||||
right:
|
||||
'Require users to have been added manually to windmill to sign in through OAuth'
|
||||
}}
|
||||
bind:checked={requirePreexistingUserForOauth}
|
||||
/>
|
||||
</div>
|
||||
{:else if ssoOrOauth === 'oauth'}
|
||||
<Alert type="info" title="OAuth Resources">
|
||||
When one of the below option is set, you will be able to create a specific
|
||||
resource containing a token automatically generated by the third-party provider.
|
||||
<br />
|
||||
To test it after setting an oauth client, go to the Resources menu and create a new
|
||||
one of the type of your oauth client (i.e. a 'github' resource if you set Github OAuth).
|
||||
</Alert>
|
||||
<div class="py-1" />
|
||||
<OAuthSetting login={false} name="slack" bind:value={oauths['slack']} />
|
||||
<div class="py-1" />
|
||||
|
||||
<div class="py-1" />
|
||||
<Alert type="info" title="Test on a separate tab">
|
||||
The recommended workflow is to to save your oauth setting and test them directly on
|
||||
the login or resource page
|
||||
</Alert>
|
||||
<div class="flex flex-col gap-2 py-4">
|
||||
<OAuthSetting name="google" bind:value={oauths['google']} />
|
||||
<OAuthSetting name="microsoft" bind:value={oauths['microsoft']} />
|
||||
<OktaSetting bind:value={oauths['okta']} />
|
||||
<OAuthSetting name="github" bind:value={oauths['github']} />
|
||||
<OAuthSetting name="gitlab" bind:value={oauths['gitlab']} />
|
||||
<OAuthSetting name="jumpcloud" bind:value={oauths['jumpcloud']} />
|
||||
<KeycloakSetting bind:value={oauths['keycloak']} />
|
||||
<AuthentikSetting bind:value={oauths['authentik']} />
|
||||
<AutheliaSetting bind:value={oauths['authelia']} />
|
||||
<KanidmSetting bind:value={oauths['kanidm']} />
|
||||
<ZitadelSetting bind:value={oauths['zitadel']} />
|
||||
{#each Object.keys(oauths) as k}
|
||||
{#if !['authelia', 'authentik', 'google', 'microsoft', 'github', 'gitlab', 'jumpcloud', 'okta', 'keycloak', 'slack', 'kanidm', 'zitadel'].includes(k) && 'login_config' in oauths[k]}
|
||||
{#if oauths[k]}
|
||||
{#if !('login_config' in oauths[k])}
|
||||
{#if !['slack'].includes(k) && oauths[k]}
|
||||
<div class="flex flex-col gap-2 pb-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<label class="text-md font-medium text-primary">{k}</label>
|
||||
@@ -257,108 +356,48 @@
|
||||
/>
|
||||
</label>
|
||||
{#if !windmillBuiltins.includes(k) && k != 'slack'}
|
||||
<CustomSso bind:login_config={oauths[k]['login_config']} />
|
||||
<CustomOauth bind:connect_config={oauths[k]['connect_config']} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<input type="text" placeholder="client_id" bind:value={clientName} />
|
||||
<Button
|
||||
variant="border"
|
||||
color="blue"
|
||||
hover="yo"
|
||||
size="sm"
|
||||
endIcon={{ icon: Plus }}
|
||||
disabled={clientName == ''}
|
||||
on:click={() => {
|
||||
oauths[clientName] = { id: '', secret: '', login_config: {} }
|
||||
clientName = ''
|
||||
}}
|
||||
>
|
||||
Add custom SSO client {!$enterpriseLicense ? '(requires ee)' : ''}
|
||||
</Button>
|
||||
</div>
|
||||
<h4 class="py-4">OAuth</h4>
|
||||
<Alert type="info" title="Require a corresponding resource type">
|
||||
After setting an oauth client, make sure that there is a corresponding resource type
|
||||
with the same name with a "token" field in the admins workspace.
|
||||
</Alert>
|
||||
<div class="py-1" />
|
||||
<OAuthSetting login={false} name="slack" bind:value={oauths['slack']} />
|
||||
<div class="py-1" />
|
||||
|
||||
{#each Object.keys(oauths) as k}
|
||||
{#if !['authelia', 'authentik', 'google', 'microsoft', 'github', 'gitlab', 'jumpcloud', 'okta', 'keycloak', 'slack', 'kanidm', 'zitadel'].includes(k) && !('login_config' in oauths[k])}
|
||||
{#if oauths[k]}
|
||||
<div class="flex flex-col gap-2 pb-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<label class="text-md font-medium text-primary">{k}</label>
|
||||
<CloseButton
|
||||
on:close={() => {
|
||||
delete oauths[k]
|
||||
oauths = { ...oauths }
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div class="p-2 border rounded">
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Id</span>
|
||||
<input type="text" placeholder="Client Id" bind:value={oauths[k]['id']} />
|
||||
</label>
|
||||
<label class="block pb-2">
|
||||
<span class="text-primary font-semibold text-sm">Client Secret</span>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Client Secret"
|
||||
bind:value={oauths[k]['secret']}
|
||||
/>
|
||||
</label>
|
||||
{#if !windmillBuiltins.includes(k) && k != 'slack'}
|
||||
<CustomOauth bind:connect_config={oauths[k]['connect_config']} />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<select name="oauth_name" id="oauth_name" bind:value={oauth_name}>
|
||||
<option value={undefined}>Select an OAuth client</option>
|
||||
<option value="custom">Fully Custom (requires ee)</option>
|
||||
{#each windmillBuiltins as name}
|
||||
<option value={name}>{capitalize(name)}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{#if oauth_name == 'custom'}
|
||||
<input type="text" placeholder="client_id" bind:value={resourceName} />
|
||||
{:else}
|
||||
<input type="text" value={oauth_name ?? ''} disabled />
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
<div class="flex gap-2">
|
||||
<select name="oauth_name" id="oauth_name" bind:value={oauth_name}>
|
||||
<option value={undefined}>Select an OAuth client</option>
|
||||
<option value="custom">Fully Custom (requires ee)</option>
|
||||
{#each windmillBuiltins as name}
|
||||
<option value={name}>{capitalize(name)}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{#if oauth_name == 'custom'}
|
||||
<input type="text" placeholder="client_id" bind:value={resourceName} />
|
||||
{:else}
|
||||
<input type="text" value={oauth_name ?? ''} disabled />
|
||||
{/if}
|
||||
<Button
|
||||
variant="border"
|
||||
color="blue"
|
||||
hover="yo"
|
||||
size="sm"
|
||||
endIcon={{ icon: Plus }}
|
||||
disabled={!oauth_name ||
|
||||
(oauth_name == 'custom' && resourceName == '') ||
|
||||
(oauth_name == 'custom' && !$enterpriseLicense)}
|
||||
on:click={() => {
|
||||
let name = oauth_name == 'custom' ? resourceName : oauth_name
|
||||
oauths[name ?? ''] = { id: '', secret: '' }
|
||||
resourceName = ''
|
||||
}}
|
||||
>
|
||||
Add OAuth client {oauth_name == 'custom' && !$enterpriseLicense
|
||||
? '(requires ee)'
|
||||
: ''}
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
variant="border"
|
||||
color="blue"
|
||||
hover="yo"
|
||||
size="sm"
|
||||
endIcon={{ icon: Plus }}
|
||||
disabled={!oauth_name ||
|
||||
(oauth_name == 'custom' && resourceName == '') ||
|
||||
(oauth_name == 'custom' && !$enterpriseLicense)}
|
||||
on:click={() => {
|
||||
let name = oauth_name == 'custom' ? resourceName : oauth_name
|
||||
oauths[name ?? ''] = { id: '', secret: '' }
|
||||
resourceName = ''
|
||||
}}
|
||||
>
|
||||
Add OAuth client {oauth_name == 'custom' && !$enterpriseLicense
|
||||
? '(requires ee)'
|
||||
: ''}
|
||||
</Button>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<div>
|
||||
|
||||
@@ -103,14 +103,7 @@ export const settings: Record<string, Setting[]> = {
|
||||
ee_only: ''
|
||||
}
|
||||
],
|
||||
'SSO/OAuth': [
|
||||
{
|
||||
label: 'Require users to have been added manually to windmill to sign in through OAuth',
|
||||
key: 'require_preexisting_user_for_oauth',
|
||||
fieldType: 'boolean',
|
||||
storage: 'setting'
|
||||
}
|
||||
],
|
||||
'SSO/OAuth': [],
|
||||
Registries: [
|
||||
{
|
||||
label: 'Pip Extra Index Url',
|
||||
|
||||
Reference in New Issue
Block a user