Skip to content

Commit

Permalink
fix: add back OAUTH2 [DHIS2-15326]
Browse files Browse the repository at this point in the history
  • Loading branch information
tomzemp committed Feb 9, 2024
1 parent b630568 commit aa7b357
Show file tree
Hide file tree
Showing 13 changed files with 588 additions and 17 deletions.
18 changes: 18 additions & 0 deletions cypress/integration/oauth2.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Feature: Users should be able to add OAuth2 clients

Scenario: User adds OAuth2 client
Given the user visits the 'OAuth2 Clients' page
And the user clicks on the 'Add OAuth2 client' button
And the user enters the relevant details in the form that appears
Then a snackbar message should appear telling the user that the client was saved
And the page should show the new client in the table of clients

Scenario: No OAuth2 clients are present
Given the user visits the 'OAuth2 Clients' page
And there are no OAuth2 clients
Then the message 'There are currently no OAuth2 clients registered' should be shown

Scenario: Some OAuth2 clients are present
Given the user visits the 'OAuth2 Clients' page
And there are some OAuth2 clients
Then a table showing all clients should be present
100 changes: 83 additions & 17 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-01-23T20:33:57.618Z\n"
"PO-Revision-Date: 2024-01-23T20:33:57.618Z\n"
"POT-Creation-Date: 2024-02-09T16:13:02.251Z\n"
"PO-Revision-Date: 2024-02-09T16:13:02.251Z\n"

msgid "Failed to load: {{error}}"
msgstr "Failed to load: {{error}}"
Expand Down Expand Up @@ -89,6 +89,84 @@ msgstr "Don't sync metadata if DHIS versions differ"
msgid "Metadata Versioning"
msgstr "Metadata Versioning"

msgid "This client ID is already taken"
msgstr "This client ID is already taken"

msgid "Name"
msgstr "Name"

msgid "Required"
msgstr "Required"

msgid "Client ID"
msgstr "Client ID"

msgid "Client Secret"
msgstr "Client Secret"

msgid "Grant Types"
msgstr "Grant Types"

msgid "Password"
msgstr "Password"

msgid "Refresh token"
msgstr "Refresh token"

msgid "Authorization code"
msgstr "Authorization code"

msgid "One URL per line"
msgstr "One URL per line"

msgid "Redirect URIs"
msgstr "Redirect URIs"

msgid "This field should contain a list of URLs"
msgstr "This field should contain a list of URLs"

msgid "Create new OAuth2 Client"
msgstr "Create new OAuth2 Client"

msgid "Edit OAuth2 Client"
msgstr "Edit OAuth2 Client"

msgid "Save"
msgstr "Save"

msgid "Cancel"
msgstr "Cancel"

msgid "There are currently no OAuth2 clients registered"
msgstr "There are currently no OAuth2 clients registered"

msgid "Edit"
msgstr "Edit"

msgid "Delete"
msgstr "Delete"

msgid "OAuth2 client saved"
msgstr "OAuth2 client saved"

msgid "Failed to save OAuth2 client"
msgstr "Failed to save OAuth2 client"

msgid "Add OAuth2 client"
msgstr "Add OAuth2 client"

msgid "Yes"
msgstr "Yes"

msgid "No"
msgstr "No"

msgid "OAuth2 client deleted"
msgstr "OAuth2 client deleted"

msgid "Failed to delete OAuth2 client"
msgstr "Failed to delete OAuth2 client"

msgid "Settings updated"
msgstr "Settings updated"

Expand Down Expand Up @@ -146,6 +224,9 @@ msgstr "Synchronization"
msgid "Synchronization settings"
msgstr "Synchronization settings"

msgid "OAuth2 Clients"
msgstr "OAuth2 Clients"

msgid "Scheduled jobs"
msgstr "Scheduled jobs"

Expand All @@ -155,9 +236,6 @@ msgstr "This field is required"
msgid "This field should be a URL"
msgstr "This field should be a URL"

msgid "This field should contain a list of URLs"
msgstr "This field should contain a list of URLs"

msgid "This field should be a number"
msgstr "This field should be a number"

Expand Down Expand Up @@ -554,9 +632,6 @@ msgstr "Database language"
msgid "Property to display in analysis modules"
msgstr "Property to display in analysis modules"

msgid "Name"
msgstr "Name"

msgid "Short name"
msgstr "Short name"

Expand Down Expand Up @@ -599,9 +674,6 @@ msgstr "Port"
msgid "Username"
msgstr "Username"

msgid "Password"
msgstr "Password"

msgid "TLS"
msgstr "TLS"

Expand Down Expand Up @@ -665,9 +737,6 @@ msgstr "Minimum characters in password"
msgid "CORS whitelist"
msgstr "CORS whitelist"

msgid "One URL per line"
msgstr "One URL per line"

msgid "reCAPTCHA Site Key"
msgstr "reCAPTCHA Site Key"

Expand Down Expand Up @@ -713,9 +782,6 @@ msgstr ""
"system unusable. If you have entered data, it is strongly recommended that "
"you do not change your calendar setting."

msgid "Cancel"
msgstr "Cancel"

msgid "Yes, change calendar"
msgstr "Yes, change calendar"

Expand Down
162 changes: 162 additions & 0 deletions src/oauth2-client-editor/ClientForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import i18n from '@dhis2/d2-i18n'
import { Button, Modal, ModalTitle, ModalContent } from '@dhis2/ui'
import { getInstance as getD2 } from 'd2'
import FormBuilder from 'd2-ui/lib/forms/FormBuilder.component.js'
import { isUrlArray, isRequired } from 'd2-ui/lib/forms/Validators.js'
import PropTypes from 'prop-types'
import React from 'react'
import MultiToggle from '../form-fields/multi-toggle.js'
import TextField from '../form-fields/text-field.js'
import styles from './ClientForm.module.css'

const formFieldStyle = {
width: '100%',
}

const validateClientID = async (v) => {
const d2 = await getD2()
const list = await d2.models.oAuth2Clients.list({
paging: false,
filter: [`cid:eq:${v}`],
})
if (list.size > 0) {
throw i18n.t('This client ID is already taken')
}
}

const ClientForm = ({ clientModel, onUpdate, onSave, onCancel }) => {
const grantTypes = ((clientModel && clientModel.grantTypes) || []).reduce(
(curr, prev) => {
curr[prev] = true
return curr
},
{}
)

const fields = [
{
name: 'name',
value: clientModel.name,
component: TextField,
props: {
floatingLabelText: i18n.t('Name'),
style: formFieldStyle,
changeEvent: 'onBlur',
},
validators: [
{
validator: isRequired,
message: i18n.t('Required'),
},
],
},
{
name: 'cid',
value: clientModel.cid,
component: TextField,
props: {
floatingLabelText: i18n.t('Client ID'),
style: formFieldStyle,
changeEvent: 'onBlur',
},
validators: [
{
validator: isRequired,
message: i18n.t('Required'),
},
{
validator: (v) => v.toString().trim().length > 0,
message: i18n.t('Required'),
},
],
asyncValidators: [validateClientID],
},
{
name: 'secret',
value: clientModel && clientModel.secret,
component: TextField,
props: {
floatingLabelText: i18n.t('Client Secret'),
disabled: true,
style: formFieldStyle,
},
},
{
name: 'grantTypes',
component: MultiToggle,
style: formFieldStyle,
props: {
label: i18n.t('Grant Types'),
items: [
{
name: 'password',
text: i18n.t('Password'),
value: grantTypes.password,
},
{
name: 'refresh_token',
text: i18n.t('Refresh token'),
value: grantTypes.refresh_token,
},
{
name: 'authorization_code',
text: i18n.t('Authorization code'),
value: grantTypes.authorization_code,
},
],
},
},
{
name: 'redirectUris',
value: (clientModel.redirectUris || []).join('\n'),
component: TextField,
props: {
hintText: i18n.t('One URL per line'),
floatingLabelText: i18n.t('Redirect URIs'),
multiLine: true,
style: formFieldStyle,
changeEvent: 'onBlur',
},
validators: [
{
validator: isUrlArray,
message: i18n.t('This field should contain a list of URLs'),
},
],
},
]

const headerText =
clientModel.id === undefined
? i18n.t('Create new OAuth2 Client')
: i18n.t('Edit OAuth2 Client')
return (
<Modal onClose={onCancel}>
<ModalTitle>{headerText}</ModalTitle>
<ModalContent>
<FormBuilder fields={fields} onUpdateField={onUpdate} />
<div style={{ marginTop: '1rem' }}>
<Button primary onClick={onSave}>
{i18n.t('Save')}
</Button>
<Button
secondary
onClick={onCancel}
className={styles.cancelBtn}
>
{i18n.t('Cancel')}
</Button>
</div>
</ModalContent>
</Modal>
)
}

ClientForm.propTypes = {
clientModel: PropTypes.object.isRequired,
onCancel: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
onUpdate: PropTypes.func.isRequired,
}

export default ClientForm
3 changes: 3 additions & 0 deletions src/oauth2-client-editor/ClientForm.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.cancelBtn {
float: right;
}
Loading

0 comments on commit aa7b357

Please sign in to comment.