Skip to content

Commit 0bab9f6

Browse files
committed
Add External OAuth tab with domain-scoped provider selection to login page
1 parent 62d4fc3 commit 0bab9f6

File tree

1 file changed

+155
-51
lines changed

1 file changed

+155
-51
lines changed

ui/src/views/auth/Login.vue

Lines changed: 155 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,64 @@
150150
</a-select>
151151
</a-form-item>
152152
</a-tab-pane>
153+
<a-tab-pane key="oauth" :disabled="!socialLogin">
154+
<template #tab>
155+
<span>
156+
<img src="/assets/github.svg" style="width: 16px; vertical-align: middle" />
157+
<img src="/assets/google.svg" style="width: 16px; vertical-align: middle" />
158+
External
159+
</span>
160+
</template>
161+
<a-form-item name="oauthDomain">
162+
<a-input
163+
size="large"
164+
type="text"
165+
:placeholder="$t('label.domain')"
166+
v-model:value="form.oauthDomain"
167+
@pressEnter="handleOauthDomainSubmit"
168+
@blur="handleOauthDomainSubmit"
169+
>
170+
<template #prefix>
171+
<project-outlined />
172+
</template>
173+
</a-input>
174+
</a-form-item>
175+
<div class="center" v-if="oauthGithubProvider || oauthGoogleProvider">
176+
<div class="social-auth" v-if="oauthGithubProvider">
177+
<a-button
178+
@click="handleGithubProviderAndDomain"
179+
tag="a"
180+
color="primary"
181+
:href="getGitHubUrl(from)"
182+
class="auth-btn github-auth"
183+
style="height: 38px; width: 185px; padding: 0; margin-bottom: 5px;" >
184+
<img src="/assets/github.svg" style="width: 32px; padding: 5px" />
185+
<a-typography-text>Sign in with Github</a-typography-text>
186+
</a-button>
187+
</div>
188+
<div class="social-auth" v-if="oauthGoogleProvider">
189+
<a-button
190+
@click="handleGoogleProviderAndDomain"
191+
tag="a"
192+
color="primary"
193+
:href="getGoogleUrl(from)"
194+
class="auth-btn google-auth"
195+
style="height: 38px; width: 185px; padding: 0" >
196+
<img src="/assets/google.svg" style="width: 32px; padding: 5px" />
197+
<a-typography-text>Sign in with Google</a-typography-text>
198+
</a-button>
199+
</div>
200+
</div>
201+
<div v-else-if="oauthLoading" style="text-align: center; padding: 20px 0;">
202+
<a-spin />
203+
</div>
204+
<div v-else style="text-align: center; color: #999; padding: 20px 0;">
205+
<span v-if="form.oauthDomain">No OAuth providers configured for this domain</span>
206+
</div>
207+
</a-tab-pane>
153208
</a-tabs>
154209

155-
<a-form-item>
210+
<a-form-item v-if="customActiveKey !== 'oauth'">
156211
<a-button
157212
size="large"
158213
type="primary"
@@ -174,35 +229,6 @@
174229
</router-link>
175230
</a-col>
176231
</a-row>
177-
<div class="content" v-if="socialLogin">
178-
<p class="or">or</p>
179-
</div>
180-
<div class="center">
181-
<div class="social-auth" v-if="githubprovider">
182-
<a-button
183-
@click="handleGithubProviderAndDomain"
184-
tag="a"
185-
color="primary"
186-
:href="getGitHubUrl(from)"
187-
class="auth-btn github-auth"
188-
style="height: 38px; width: 185px; padding: 0; margin-bottom: 5px;" >
189-
<img src="/assets/github.svg" style="width: 32px; padding: 5px" />
190-
<a-typography-text>Sign in with Github</a-typography-text>
191-
</a-button>
192-
</div>
193-
<div class="social-auth" v-if="googleprovider">
194-
<a-button
195-
@click="handleGoogleProviderAndDomain"
196-
tag="a"
197-
color="primary"
198-
:href="getGoogleUrl(from)"
199-
class="auth-btn google-auth"
200-
style="height: 38px; width: 185px; padding: 0" >
201-
<img src="/assets/google.svg" style="width: 32px; padding: 5px" />
202-
<a-typography-text>Sign in with Google</a-typography-text>
203-
</a-button>
204-
</div>
205-
</div>
206232
</a-form>
207233
</template>
208234

@@ -235,6 +261,13 @@ export default {
235261
githubredirecturi: '',
236262
googleclientid: '',
237263
githubclientid: '',
264+
oauthGoogleProvider: false,
265+
oauthGithubProvider: false,
266+
oauthGoogleClientId: '',
267+
oauthGithubClientId: '',
268+
oauthGoogleRedirectUri: '',
269+
oauthGithubRedirectUri: '',
270+
oauthLoading: false,
238271
loginType: 0,
239272
state: {
240273
time: 60,
@@ -269,6 +302,7 @@ export default {
269302
server: (this.server.apiHost || '') + this.server.apiBase,
270303
username: this.$route.query?.username || '',
271304
domain: this.$route.query?.domain || '',
305+
oauthDomain: '',
272306
project: null
273307
})
274308
this.rules = reactive({})
@@ -322,24 +356,56 @@ export default {
322356
}
323357
})
324358
},
325-
fetchOauthProviders () {
326-
getAPI('listOauthProvider', {}).then(response => {
359+
fetchOauthProviders (domain) {
360+
const params = {}
361+
if (domain) {
362+
params.domain = domain
363+
}
364+
if (domain) {
365+
this.oauthLoading = true
366+
}
367+
getAPI('listOauthProvider', params).then(response => {
327368
if (response) {
328369
const oauthproviders = response.listoauthproviderresponse.oauthprovider || []
329-
oauthproviders.forEach(item => {
330-
if (item.provider === 'google') {
331-
this.googleprovider = item.enabled
332-
this.googleclientid = item.clientid
333-
this.googleredirecturi = item.redirecturi
334-
}
335-
if (item.provider === 'github') {
336-
this.githubprovider = item.enabled
337-
this.githubclientid = item.clientid
338-
this.githubredirecturi = item.redirecturi
339-
}
340-
})
341-
this.socialLogin = this.googleprovider || this.githubprovider
370+
if (!domain) {
371+
oauthproviders.forEach(item => {
372+
if (item.provider === 'google') {
373+
this.googleprovider = item.enabled
374+
this.googleclientid = item.clientid
375+
this.googleredirecturi = item.redirecturi
376+
}
377+
if (item.provider === 'github') {
378+
this.githubprovider = item.enabled
379+
this.githubclientid = item.clientid
380+
this.githubredirecturi = item.redirecturi
381+
}
382+
})
383+
this.socialLogin = oauthproviders.some(item => item.enabled)
384+
this.oauthGithubProvider = this.githubprovider
385+
this.oauthGoogleProvider = this.googleprovider
386+
this.oauthGithubClientId = this.githubclientid
387+
this.oauthGoogleClientId = this.googleclientid
388+
this.oauthGithubRedirectUri = this.githubredirecturi
389+
this.oauthGoogleRedirectUri = this.googleredirecturi
390+
} else {
391+
this.oauthGithubProvider = false
392+
this.oauthGoogleProvider = false
393+
oauthproviders.forEach(item => {
394+
if (item.provider === 'google') {
395+
this.oauthGoogleProvider = item.enabled
396+
this.oauthGoogleClientId = item.clientid
397+
this.oauthGoogleRedirectUri = item.redirecturi
398+
}
399+
if (item.provider === 'github') {
400+
this.oauthGithubProvider = item.enabled
401+
this.oauthGithubClientId = item.clientid
402+
this.oauthGithubRedirectUri = item.redirecturi
403+
}
404+
})
405+
}
342406
}
407+
}).finally(() => {
408+
this.oauthLoading = false
343409
})
344410
},
345411
// handler
@@ -355,8 +421,29 @@ export default {
355421
},
356422
handleTabClick (key) {
357423
this.customActiveKey = key
424+
if (key === 'oauth') {
425+
this.oauthGithubProvider = this.githubprovider
426+
this.oauthGoogleProvider = this.googleprovider
427+
this.oauthGithubClientId = this.githubclientid
428+
this.oauthGoogleClientId = this.googleclientid
429+
this.oauthGithubRedirectUri = this.githubredirecturi
430+
this.oauthGoogleRedirectUri = this.googleredirecturi
431+
}
358432
this.setRules()
359433
},
434+
handleOauthDomainSubmit () {
435+
const domain = this.form.oauthDomain
436+
if (domain) {
437+
this.fetchOauthProviders(domain)
438+
} else {
439+
this.oauthGithubProvider = this.githubprovider
440+
this.oauthGoogleProvider = this.googleprovider
441+
this.oauthGithubClientId = this.githubclientid
442+
this.oauthGoogleClientId = this.googleclientid
443+
this.oauthGithubRedirectUri = this.githubredirecturi
444+
this.oauthGoogleRedirectUri = this.googleredirecturi
445+
}
446+
},
360447
handleGithubProviderAndDomain () {
361448
this.handleDomain()
362449
this.$store.commit('SET_OAUTH_PROVIDER_USED_TO_LOGIN', 'github')
@@ -367,16 +454,25 @@ export default {
367454
},
368455
handleDomain () {
369456
const values = toRaw(this.form)
370-
if (!values.domain) {
371-
this.$store.commit('SET_DOMAIN_USED_TO_LOGIN', '/')
457+
if (this.customActiveKey === 'oauth') {
458+
if (!values.oauthDomain) {
459+
this.$store.commit('SET_DOMAIN_USED_TO_LOGIN', '/')
460+
} else {
461+
this.$store.commit('SET_DOMAIN_USED_TO_LOGIN', values.oauthDomain)
462+
}
372463
} else {
373-
this.$store.commit('SET_DOMAIN_USED_TO_LOGIN', values.domain)
464+
if (!values.domain) {
465+
this.$store.commit('SET_DOMAIN_USED_TO_LOGIN', '/')
466+
} else {
467+
this.$store.commit('SET_DOMAIN_USED_TO_LOGIN', values.domain)
468+
}
374469
}
375470
},
376471
getGitHubUrl (from) {
377472
const rootURl = 'https://github.com/login/oauth/authorize'
473+
const clientId = this.customActiveKey === 'oauth' ? this.oauthGithubClientId : this.githubclientid
378474
const options = {
379-
client_id: this.githubclientid,
475+
client_id: clientId,
380476
scope: 'user:email',
381477
state: 'cloudstack'
382478
}
@@ -387,9 +483,11 @@ export default {
387483
},
388484
getGoogleUrl (from) {
389485
const rootUrl = 'https://accounts.google.com/o/oauth2/v2/auth'
486+
const redirectUri = this.customActiveKey === 'oauth' ? this.oauthGoogleRedirectUri : this.googleredirecturi
487+
const clientId = this.customActiveKey === 'oauth' ? this.oauthGoogleClientId : this.googleclientid
390488
const options = {
391-
redirect_uri: this.googleredirecturi,
392-
client_id: this.googleclientid,
489+
redirect_uri: redirectUri,
490+
client_id: clientId,
393491
access_type: 'offline',
394492
response_type: 'code',
395493
prompt: 'consent',
@@ -526,6 +624,12 @@ export default {
526624
width: 368px;
527625
margin: 0 auto;
528626
627+
:deep(.tab-center .ant-tabs-tab) {
628+
padding: 12px 4px;
629+
font-size: 13px;
630+
margin: 0 !important;
631+
}
632+
529633
.mobile & {
530634
max-width: 368px;
531635
width: 98%;

0 commit comments

Comments
 (0)