Skip to content

Commit

Permalink
feat(chart): add user email verification (#35)
Browse files Browse the repository at this point in the history
Signed-off-by: Sven Trieflinger <[email protected]>
Signed-off-by: Sebastian Becker <[email protected]>
Co-authored-by: Sebastian Becker <[email protected]>
  • Loading branch information
strieflin and sbckr authored Dec 18, 2024
1 parent b71fae2 commit 9393715
Show file tree
Hide file tree
Showing 4 changed files with 213 additions and 14 deletions.
88 changes: 88 additions & 0 deletions charts/thymus/scripts/create-user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash

#
# Copyright (c) 2024 - for information on the respective copyright owner
# see the NOTICE file and/or the repository https://github.com/carbynestack/thymus.
#
# SPDX-License-Identifier: Apache-2.0
#

# This script creates a user in Kratos and verifies the user's email address.
#
# The script expects the following environment variables to be set:
# - MAILSLURPER_ADDRESS: The address of the MailSlurper instance.
# - KRATOS_ADMIN_SERVICE_ADDRESS: The address of the Kratos admin service instance.
# - KRATOS_PUBLIC_SERVICE_ADDRESS: The address of the Kratos public service instance.
# - RETRY_PERIOD: The time to wait between retries when polling for the verification code. Default is 1 second.
# - RETRIES: The number of times to retry getting the verification code. Default is 10.

RETRY_PERIOD=${RETRY_PERIOD:-1}
RETRIES=${RETRIES:-10}

if [ -z "${MAILSLURPER_ADDRESS}" ]; then
echo "Error: MAILSLURPER_ADDRESS environment variable is not set."
exit 1
fi

if [ -z "${KRATOS_ADMIN_SERVICE_ADDRESS}" ]; then
echo "Error: KRATOS_ADMIN_SERVICE_ADDRESS environment variable is not set."
exit 1
fi

if [ -z "${KRATOS_PUBLIC_SERVICE_ADDRESS}" ]; then
echo "Error: KRATOS_PUBLIC_SERVICE_ADDRESS environment variable is not set."
exit 1
fi

# Checks if the last command failed and exits the script if it did.
exitOnError() {
STATUS_CODE=$?
if [ $STATUS_CODE -ne 0 ]; then
echo "$1 Exit Code: $STATUS_CODE"
exit 1
fi
}

# Gets the verification code from the email sent by Kratos.
getVerificationCode() {
email=$1
for i in $(seq 1 "${RETRIES}"); do
code=$(curl -X GET -sf -H 'Content-Type: application/JSON' \
"http://${MAILSLURPER_ADDRESS}/mail?to=${email}\&order=desc" | \
jq -r '.mailItems[0].body | capture("code: (?<code>\\w+)").code')
exitOnError "Failed to get verification code for user: $email."
if [[ -n "$code" ]]; then
echo "$code"
return
fi
sleep "$((i*RETRY_PERIOD))"
done
echo "Failed to get verification code for user: $email."
exit 1
}

# Extracts the email from the user credentials file.
email=$(jq -r '.traits.email' < /user-credentials/data.json)

echo "Creating user: ${email}"
curl -X POST -vf -H 'Content-Type: application/json' -d @/user-credentials/data.json "http://${KRATOS_ADMIN_SERVICE_ADDRESS}/admin/identities"
exitOnError "Failed to create user: ${email}."

echo "Verifying user: ${email}"
flowID=$(curl -X GET -sf -H 'Content-Type: application/JSON' \
"http://${KRATOS_PUBLIC_SERVICE_ADDRESS}/self-service/verification/api" | \
jq -r '.id')
exitOnError "Failed to create verification flow for user: ${email}."

curl -X POST -sf -H 'Content-Type: application/JSON' \
"http://${KRATOS_PUBLIC_SERVICE_ADDRESS}/self-service/verification?flow=${flowID}" \
--data "{\"method\": \"code\", \"email\": \"${email}\"}"
exitOnError "Failed to initiate verification flow for user: ${email}."

code=$(getVerificationCode "${email}")
curl -X POST -sf -H 'Content-Type: application/JSON' \
"http://${KRATOS_PUBLIC_SERVICE_ADDRESS}/self-service/verification?flow=${flowID}" \
--data "{\"method\": \"code\", \"code\": \"$code\"}"
exitOnError "Failed finalize verification for user: ${email}."

echo "User ${email} successfully created"
81 changes: 81 additions & 0 deletions charts/thymus/templates/mailslurper.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#
# Copyright (c) 2024 - for information on the respective copyright owner
# see the NOTICE file and/or the repository https://github.com/carbynestack/thymus.
#
# SPDX-License-Identifier: Apache-2.0
#

# Deployment for mailslurper
{{- if .Values.thymus.users.enabled }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "thymus.fullname" . }}-mailslurper
namespace: {{ .Release.Namespace }}
labels:
app.kubernetes.io/name: {{ include "thymus.name" . }}-mailslurper
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
spec:
replicas: {{ .Values.thymus.policyCatalogue.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "thymus.name" . }}-mailslurper
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "thymus.name" . }}-mailslurper
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- if .Values.mailslurper.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.mailslurper.image.pullSecrets }}
- name: {{ . }}
{{- end}}
{{- end}}
containers:
- name: "{{ .Chart.Name }}-mailslurper"
image: "{{ .Values.mailslurper.image.registry }}/{{ .Values.mailslurper.image.repository }}:{{ .Values.mailslurper.image.tag }}"
imagePullPolicy: {{ .Values.mailslurper.image.pullPolicy }}
ports:
- name: ui
containerPort: 4436
protocol: TCP
- name: api
containerPort: 4437
protocol: TCP
- name: smtp
containerPort: 1025
protocol: TCP
---
# Service for exposing mailslurper
apiVersion: v1
kind: Service
metadata:
name: {{ include "thymus.fullname" . }}-mailslurper
namespace: {{ .Release.Namespace }}
{{- if .Values.mailslurper.service.annotations }}
annotations:
{{ .Values.mailslurper.service.annotations | toYaml | trim | indent 4 }}
{{- end}}
spec:
selector:
app.kubernetes.io/name: {{ include "thymus.name" . }}-mailslurper
app.kubernetes.io/instance: {{ .Release.Name }}
ports:
- name: ui
protocol: TCP
port: {{ .Values.mailslurper.service.uiPort }}
targetPort: ui
- name: api
protocol: TCP
port: {{ .Values.mailslurper.service.apiPort }}
targetPort: api
- name: smtp
protocol: TCP
port: {{ .Values.mailslurper.service.smtpPort }}
targetPort: smtp
{{- end }}
18 changes: 12 additions & 6 deletions charts/thymus/templates/users.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

# Create demo users
{{- if .Values.thymus.users.enabled }}
{{- $command := printf "curl -X POST -sf -H 'Content-Type: application/json' -d @/user-credentials/data.json http://%s-kratos-admin:80/admin/identities"
(include "thymus.fullname" . ) -}}
{{- range $index, $value := .Values.thymus.users.data }}
---
apiVersion: v1
Expand All @@ -18,7 +16,7 @@ metadata:
data:
data.json: |
{
"traits": {
"traits": {
"email": "{{ $value.email }}"
},
"credentials": {
Expand All @@ -35,7 +33,7 @@ kind: Job
metadata:
name: "create-user-{{ $index }}"
spec:
backoffLimit: 10
backoffLimit: 5
template:
spec:
volumes:
Expand All @@ -44,11 +42,19 @@ spec:
name: "user-credentials-{{ $index }}"
containers:
- name: add-user
image: curlimages/curl:8.8.0
image: pnnlmiscscripts/curl-jq
{{- $files := $.Files }}
command:
- "sh"
- "-c"
- {{ $command | quote }}
- {{ $files.Get "scripts/create-user.sh" | quote | indent 14 }}
env:
- name: MAILSLURPER_ADDRESS
value: "{{ include "thymus.fullname" $ }}-mailslurper:{{ $.Values.mailslurper.service.apiPort }}"
- name: KRATOS_ADMIN_SERVICE_ADDRESS
value: {{ printf "%s-kratos-admin:%d" (include "thymus.fullname" $) (int $.Values.kratos.service.admin.port) }}
- name: KRATOS_PUBLIC_SERVICE_ADDRESS
value: {{ printf "%s-kratos-public:%d" (include "thymus.fullname" $) (int $.Values.kratos.service.public.port) }}
volumeMounts:
- name: user-credentials-volume
mountPath: /user-credentials
Expand Down
40 changes: 32 additions & 8 deletions charts/thymus/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@ thymus:
replicaCount: 1
service:
port: 8080
annotations: []
annotations: [ ]
image:
registry: ghcr.io
repository: carbynestack/thymus/policy-catalogue
tag: latest
pullPolicy: "IfNotPresent"
pullSecrets: []
pullSecrets: [ ]
probes:
liveness:
period: 10
initialDelay: 10
failureThreshold: 3
period: 10
initialDelay: 10
failureThreshold: 3
readiness:
period: 10
initialDelay: 10
failureThreshold: 3
period: 10
initialDelay: 10
failureThreshold: 3

# Overrides for the Kratos subchart
kratos:
Expand Down Expand Up @@ -123,6 +123,13 @@ kratos:
hooks:
- hook: session

verification:
enabled: true
ui_url: http://172.18.1.128.sslip.io/iam/ui/verification
use: code
after:
default_browser_return_url: http://172.18.1.128.sslip.io/iam/ui/

# Logging system configuration
log:
# If set will leak sensitive values (e.g. emails) in the logs.
Expand Down Expand Up @@ -174,6 +181,9 @@ kratos:
"password": {
"identifier": true
}
},
"verification": {
"via": "email"
}
}
}
Expand Down Expand Up @@ -401,3 +411,17 @@ kratos-selfservice-ui-node:

config:
csrfCookieName: cookie_name

# Mailslurper configuration
mailslurper:
image:
registry: docker.io
repository: oryd/mailslurper
tag: latest-smtps
pullPolicy: "IfNotPresent"
pullSecrets: [ ]
service:
annotations: [ ]
uiPort: 4436
apiPort: 4437
smtpPort: 1025

0 comments on commit 9393715

Please sign in to comment.