Skip to content

Commit

Permalink
feat(saml): saml 2.0 implementation
Browse files Browse the repository at this point in the history
Signed-off-by: sebferrer <[email protected]>

Co-authored-by: ThibaultHerard <[email protected]>
  • Loading branch information
sebferrer and ThibHrrd committed Nov 16, 2022
1 parent e34203f commit 18f8055
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 3 deletions.
86 changes: 84 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/react-components/ory/helpers/node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const Node = ({

const isSocial =
(attrs.name === "provider" || attrs.name === "link") &&
node.group === "oidc"
(node.group === "oidc" || node.group === "saml")

const submit: ButtonSubmit = {
type: attrs.type as "submit" | "reset" | "button" | undefined,
Expand Down
2 changes: 2 additions & 0 deletions src/react-components/ory/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { UiNode } from "@ory/client"

export const hasOidc = (nodes: UiNode[]) =>
nodes.some(({ group }) => group === "oidc")
export const hasSaml = (nodes: UiNode[]) =>
nodes.some(({ group }) => group === "saml")
export const hasPassword = (nodes: UiNode[]) =>
nodes.some(({ group }) => group === "password")
export const hasWebauthn = (nodes: UiNode[]) =>
Expand Down
36 changes: 36 additions & 0 deletions src/react-components/ory/sections/saml-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { filterNodesByGroups } from "@ory/integrations/ui"
import { gridStyle } from "../../../theme"
import { FilterFlowNodes } from "../helpers/filter-flow-nodes"
import { SelfServiceFlow } from "../helpers/types"
import { hasSaml } from "../helpers/utils"

export const SAMLSection = (flow: SelfServiceFlow): JSX.Element | null => {
return hasSaml(flow.ui.nodes) ? (
<div className={gridStyle({ gap: 32 })}>
{filterNodesByGroups({
nodes: flow.ui.nodes,
groups: "saml",
withoutDefaultGroup: true,
}).some((node) => node.messages.length > 0) && (
<div className={gridStyle({ gap: 16 })}>
{/* we need other SAML fields here such as input fields when an SAML registration flow occured and it redirects us back to complete the missing traits */}
<FilterFlowNodes
filter={{
nodes: flow.ui.nodes,
groups: ["saml"],
excludeAttributes: "submit",
}}
/>
</div>
)}

<FilterFlowNodes
filter={{
nodes: flow.ui.nodes,
groups: "saml",
attributes: "submit",
}}
/>
</div>
) : null
}
28 changes: 28 additions & 0 deletions src/react-components/ory/sections/saml-settings-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { SelfServiceSettingsFlow } from "@ory/client"
import { gridStyle } from "../../../theme"
import { FilterFlowNodes } from "../helpers/filter-flow-nodes"
import { hasSaml } from "../helpers/utils"

export type SAMLSettingsProps = {
flow: SelfServiceSettingsFlow
title?: string
}

export const SAMLSettingsSection = ({
flow,
}: SAMLSettingsProps): JSX.Element | null => {
const filter = {
nodes: flow.ui.nodes,
groups: "saml",
withoutDefaultGroup: true,
}

return hasSaml(flow.ui.nodes) ? (
<div className={gridStyle({ gap: 32 })}>
<FilterFlowNodes
filter={filter}
buttonOverrideProps={{ fullWidth: false }}
/>
</div>
) : null
}
10 changes: 10 additions & 0 deletions src/react-components/ory/user-auth-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
import { LinkSection } from "./sections/link-section"
import { LoginSection } from "./sections/login-section"
import { OIDCSection } from "./sections/oidc-section"
import { SAMLSection } from "./sections/saml-section"
import { PasswordlessSection } from "./sections/passwordless-section"
import { RegistrationSection } from "./sections/registration-section"

Expand Down Expand Up @@ -90,6 +91,7 @@ export const UserAuthCard = ({

let $flow = null
let $oidc = null
let $saml = null
let $passwordless: JSX.Element | null = null
let message: MessageSectionProps | null = null

Expand Down Expand Up @@ -200,6 +202,7 @@ export const UserAuthCard = ({
case "login":
$passwordless = PasswordlessSection(flow)
$oidc = OIDCSection(flow)
$saml = SAMLSection(flow)

$flow = LoginSection({
nodes: flow.ui.nodes,
Expand All @@ -223,6 +226,7 @@ export const UserAuthCard = ({
case "registration":
$passwordless = PasswordlessSection(flow)
$oidc = OIDCSection(flow)
$saml = SAMLSection(flow)
$flow = RegistrationSection({
nodes: flow.ui.nodes,
})
Expand Down Expand Up @@ -272,6 +276,12 @@ export const UserAuthCard = ({
<div className={gridStyle({ gap: 32 })}>
{subtitle && <Message severity="default">{subtitle}</Message>}
<NodeMessages uiMessages={flow.ui.messages} />
{$saml && (
<>
<Divider />
<UserAuthForm flow={flow}>{$saml}</UserAuthForm>
</>
)}
{$oidc && (
<>
<Divider />
Expand Down
10 changes: 10 additions & 0 deletions src/react-components/ory/user-settings-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import {
import {
hasLookupSecret,
hasOidc,
hasSaml,
hasPassword,
hasTotp,
hasWebauthn,
} from "./helpers/utils"
import { LookupSecretSettingsSection } from "./sections/lookup-secret-settings-section"
import { OIDCSettingsSection } from "./sections/oidc-settings-section"
import { SAMLSettingsSection } from "./sections/saml-settings-section"
import { PasswordSettingsSection } from "./sections/password-settings-section"
import { ProfileSettingsSection } from "./sections/profile-settings-section"
import { TOTPSettingsSection } from "./sections/totp-settings-section"
Expand All @@ -26,6 +28,7 @@ export type UserSettingsFlowType =
| "totp"
| "webauthn"
| "oidc"
| "saml"
| "lookupSecret"

export type UserSettingsCardProps = {
Expand Down Expand Up @@ -84,6 +87,13 @@ export const UserSettingsCard = ({
$flow = <OIDCSettingsSection flow={flow} />
}
break
case "saml":
if (hasSaml(flow.ui.nodes)) {
hasFlow = true
cardTitle = title || "SSO Sign In"
$flow = <SAMLSettingsSection flow={flow} />
}
break
case "totp":
if (hasTotp(flow.ui.nodes)) {
hasFlow = true
Expand Down
7 changes: 7 additions & 0 deletions src/stories/Ory/AuthSettings.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ UserSettingsOidcCard.args = {
flowType: "oidc",
flow: settingsFlow as SelfServiceSettingsFlow,
}

export const UserSettingsSamlCard = Template.bind({})

UserSettingsSamlCard.args = {
flowType: "saml",
flow: settingsFlow as SelfServiceSettingsFlow,
}

0 comments on commit 18f8055

Please sign in to comment.