-
Notifications
You must be signed in to change notification settings - Fork 4
feature: Oauth authentication #41
Changes from 4 commits
264b9f8
3e86a31
fefbadf
0054d12
f86e356
c1a8cdd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,16 @@ spec: | |
| protocol: TCP | ||
| args: | ||
| - "--https-port={{ .Values.plugin.port }}" | ||
| {{- if .Values.plugin.oauth.enabled }} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this all hard-wired during installation? Could we make it configurable via some ConfigMap? So admin can enable it post-installation by modifying some configmap and then doing deployment roll-out?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. diff --git a/charts/openshift-console-plugin/templates/configmap-oauth.yaml b/charts/openshift-console-plugin/templates/configmap-oauth.yaml
new file mode 100644
index 0000000..ceb4a4b
--- /dev/null
+++ b/charts/openshift-console-plugin/templates/configmap-oauth.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "openshift-console-plugin.name" . }}-oauth
+ namespace: {{ .Release.Namespace }}
+ labels:
+ {{- include "openshift-console-plugin.labels" . | nindent 4 }}
+data:
+ GITHUB_CLIENT_ID: {{ .Values.plugin.oauth.githubClientId | quote }}
diff --git a/charts/openshift-console-plugin/templates/deployment.yaml b/charts/openshift-console-plugin/templates/deployment.yaml
index 37a79fe..8eaa70b 100644
--- a/charts/openshift-console-plugin/templates/deployment.yaml
+++ b/charts/openshift-console-plugin/templates/deployment.yaml
@@ -13,6 +13,8 @@ spec:
{{- include "openshift-console-plugin.selectorLabels" . | nindent 6 }}
template:
metadata:
+ annotations:
+ checksum/oauth-config: {{ include (print $.Template.BasePath "/configmap-oauth.yaml") . | sha256sum }}
labels:
{{- include "openshift-console-plugin.labels" . | nindent 8 }}
spec:
@@ -28,16 +30,19 @@ spec:
protocol: TCP
args:
- "--https-port={{ .Values.plugin.port }}"
- {{- if .Values.plugin.oauth.enabled }}
env:
- name: GITHUB_CLIENT_ID
- value: {{ .Values.plugin.oauth.githubClientId | quote }}
+ valueFrom:
+ configMapKeyRef:
+ name: {{ template "openshift-console-plugin.name" . }}-oauth
+ key: GITHUB_CLIENT_ID
+ optional: true
- name: GITHUB_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: {{ .Values.plugin.oauth.githubSecretName }}
key: {{ .Values.plugin.oauth.githubSecretKey }}
- {{- end }}
+ optional: true
imagePullPolicy: {{ .Values.plugin.imagePullPolicy }}
{{- if and (.Values.plugin.securityContext.enabled) (.Values.plugin.containerSecurityContext) }}
securityContext: {{ tpl (toYaml (omit .Values.plugin.containerSecurityContext "enabled")) $ | nindent 12 }}
diff --git a/charts/openshift-console-plugin/values.yaml b/charts/openshift-console-plugin/values.yaml
index 229bf23..e0e1c57 100644
--- a/charts/openshift-console-plugin/values.yaml
+++ b/charts/openshift-console-plugin/values.yaml
@@ -26,9 +26,8 @@ plugin:
memory: 50Mi
basePath: /
oauth:
- enabled: false
githubClientId: ""
- githubSecretName: ""
+ githubSecretName: "github-oauth"
githubSecretKey: "client-secret"
certificateSecretName: ""
serviceAccount:
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enabling GitHub OAuth (post-installation)OAuth is disabled by default. The plugin determines whether OAuth is active Replace 1. Create a GitHub OAuth App
2. Create the Secretoc create secret generic github-oauth \
--from-literal=client-secret=<YOUR_CLIENT_SECRET> \
-n console-functions-pluginIf you used a custom secret name or key during installation 3. Set the Client ID in the ConfigMapoc patch configmap console-functions-plugin-oauth \
-n console-functions-plugin \
--type merge \
-p '{"data":{"GITHUB_CLIENT_ID":"<YOUR_CLIENT_ID>"}}'4. Restart the podsThe deployment has a checksum annotation that triggers a rollout oc rollout restart deployment/console-functions-plugin -n console-functions-plugin5. Verifyoc rollout status deployment/console-functions-plugin -n console-functions-pluginCheck the plugin UI. The "Sign in with GitHub" button should now be active. Disabling OAuthTo disable OAuth again, clear the Client ID: oc patch configmap console-functions-plugin-oauth \
-n console-functions-plugin \
--type merge \
-p '{"data":{"GITHUB_CLIENT_ID":""}}'
oc rollout restart deployment/console-functions-plugin -n console-functions-pluginYou can optionally delete the Secret as well: oc delete secret github-oauth -n console-functions-plugin |
||
| env: | ||
| - name: GITHUB_CLIENT_ID | ||
| value: {{ .Values.plugin.oauth.githubClientId | quote }} | ||
| - name: GITHUB_CLIENT_SECRET | ||
| valueFrom: | ||
| secretKeyRef: | ||
| name: {{ .Values.plugin.oauth.githubSecretName }} | ||
| key: {{ .Values.plugin.oauth.githubSecretKey }} | ||
| {{- end }} | ||
| imagePullPolicy: {{ .Values.plugin.imagePullPolicy }} | ||
| {{- if and (.Values.plugin.securityContext.enabled) (.Values.plugin.containerSecurityContext) }} | ||
| securityContext: {{ tpl (toYaml (omit .Values.plugin.containerSecurityContext "enabled")) $ | nindent 12 }} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import { render, screen } from '@testing-library/react'; | ||
| import userEvent from '@testing-library/user-event'; | ||
| import { DisconnectConfirmModal } from './DisconnectConfirmModal'; | ||
|
|
||
| vi.mock('react-i18next', () => ({ | ||
| useTranslation: () => ({ t: (key: string) => key }), | ||
| })); | ||
|
|
||
| describe('DisconnectConfirmModal', () => { | ||
| const defaultProps = { | ||
| isOpen: true, | ||
| onClose: vi.fn(), | ||
| onConfirm: vi.fn(), | ||
| }; | ||
|
|
||
| afterEach(() => { | ||
| vi.restoreAllMocks(); | ||
| }); | ||
|
|
||
| it('renders title and confirmation text', () => { | ||
| render(<DisconnectConfirmModal {...defaultProps} />); | ||
|
|
||
| expect(screen.getByText('Disconnect from GitHub')).toBeInTheDocument(); | ||
| expect( | ||
| screen.getByText('Are you sure you want to disconnect from GitHub?'), | ||
| ).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('renders Disconnect and Cancel buttons', () => { | ||
| render(<DisconnectConfirmModal {...defaultProps} />); | ||
|
|
||
| expect(screen.getByRole('button', { name: 'Disconnect' })).toBeInTheDocument(); | ||
| expect(screen.getByRole('button', { name: 'Cancel' })).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('calls onConfirm when Disconnect is clicked', async () => { | ||
| const onConfirm = vi.fn(); | ||
| const user = userEvent.setup(); | ||
|
|
||
| render(<DisconnectConfirmModal {...defaultProps} onConfirm={onConfirm} />); | ||
|
|
||
| await user.click(screen.getByRole('button', { name: 'Disconnect' })); | ||
|
|
||
| expect(onConfirm).toHaveBeenCalledOnce(); | ||
| }); | ||
|
|
||
| it('calls onClose when Cancel is clicked', async () => { | ||
| const onClose = vi.fn(); | ||
| const user = userEvent.setup(); | ||
|
|
||
| render(<DisconnectConfirmModal {...defaultProps} onClose={onClose} />); | ||
|
|
||
| await user.click(screen.getByRole('button', { name: 'Cancel' })); | ||
|
|
||
| expect(onClose).toHaveBeenCalledOnce(); | ||
| }); | ||
|
|
||
| it('does not render content when closed', () => { | ||
| render(<DisconnectConfirmModal {...defaultProps} isOpen={false} />); | ||
|
|
||
| expect(screen.queryByText('Disconnect from GitHub')).not.toBeInTheDocument(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from '@patternfly/react-core'; | ||
| import { useTranslation } from 'react-i18next'; | ||
|
|
||
| interface DisconnectConfirmModalProps { | ||
| isOpen: boolean; | ||
| onClose: () => void; | ||
| onConfirm: () => void; | ||
| } | ||
|
|
||
| export function DisconnectConfirmModal({ | ||
| isOpen, | ||
| onClose, | ||
| onConfirm, | ||
| }: DisconnectConfirmModalProps) { | ||
| const { t } = useTranslation('plugin__console-functions-plugin'); | ||
|
|
||
| return ( | ||
| <Modal isOpen={isOpen} onClose={onClose} variant="small"> | ||
| <ModalHeader title={t('Disconnect from GitHub')} /> | ||
| <ModalBody>{t('Are you sure you want to disconnect from GitHub?')}</ModalBody> | ||
| <ModalFooter> | ||
| <Button variant="danger" onClick={onConfirm}> | ||
| {t('Disconnect')} | ||
| </Button> | ||
| <Button variant="link" onClick={onClose}> | ||
| {t('Cancel')} | ||
| </Button> | ||
| </ModalFooter> | ||
| </Modal> | ||
| ); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.