From 588b836d9ab76ac7cc830c1b85845d9e937b6c70 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Mon, 9 Dec 2024 01:04:31 +0100 Subject: [PATCH 01/66] NORY-31: upgrade oryd/kratos image version --- docker/ory-dev/docker-compose.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/ory-dev/docker-compose.yaml b/docker/ory-dev/docker-compose.yaml index e633d31..190a121 100644 --- a/docker/ory-dev/docker-compose.yaml +++ b/docker/ory-dev/docker-compose.yaml @@ -2,7 +2,7 @@ services: ory-kratos-migrate: container_name: ory-kratos-migrate - image: oryd/kratos:v1.1.0 + image: oryd/kratos:v1.3.1 restart: on-failure volumes: - ./ory/kratos:/etc/config/kratos @@ -18,7 +18,7 @@ services: ory-kratos: container_name: ory-kratos - image: oryd/kratos:v1.1.0 + image: oryd/kratos:v1.3.1 restart: unless-stopped ports: - 127.0.0.1:4433:4433 # public -- 2.45.3 From 07c0d3b696b17f2f911f2fdbb1195ca2b09c0c68 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 03:34:50 +0100 Subject: [PATCH 02/66] NORY-36: add Ory Keto to Docker Compose setup --- docker/ory-dev/docker-compose.yaml | 34 +++++++++++++++++++++++ docker/ory-dev/ory/keto/keto.yaml | 43 ++++++++++++++++++++++++++++++ docker/ory-dev/postgres/init.sql | 3 +++ 3 files changed, 80 insertions(+) create mode 100644 docker/ory-dev/ory/keto/keto.yaml diff --git a/docker/ory-dev/docker-compose.yaml b/docker/ory-dev/docker-compose.yaml index 190a121..1b603e5 100644 --- a/docker/ory-dev/docker-compose.yaml +++ b/docker/ory-dev/docker-compose.yaml @@ -70,6 +70,39 @@ services: networks: - internal + ory-keto-migrate: + container_name: ory-keto-migrate + image: oryd/keto:v0.12.0 + restart: on-failure + volumes: + - ./ory/keto:/etc/config/keto + - ory-keto-data:/home/ory + - ory-keto-data:/var/lib/sqlite + command: migrate -c /etc/config/keto/keto.yaml up --yes + depends_on: + ory-postgres: + condition: service_healthy + networks: + - internal + + + ory-keto: + container_name: ory-keto + image: oryd/keto:v0.12.0 + restart: unless-stopped + ports: + - 127.0.0.1:4466:4466 # public + - 127.0.0.1:4467:4467 # admin + volumes: + - ./ory/keto:/etc/config/keto + - ory-keto-data:/home/ory + - ory-keto-data:/var/lib/sqlite + command: serve -c /etc/config/keto/keto.yaml all + depends_on: + ory-keto-migrate: + condition: service_completed_successfully + networks: + - internal ory-mailslurper: container_name: ory-mailslurper @@ -111,4 +144,5 @@ networks: volumes: ory-kratos-data: ory-hydra-data: + ory-keto-data: ory-postgres-data: diff --git a/docker/ory-dev/ory/keto/keto.yaml b/docker/ory-dev/ory/keto/keto.yaml new file mode 100644 index 0000000..21dad3d --- /dev/null +++ b/docker/ory-dev/ory/keto/keto.yaml @@ -0,0 +1,43 @@ +# +# Documentation: https://www.ory.sh/docs/keto/reference/configuration +# Configuration UI: https://www.ory.sh/docs/keto/reference/configuration-editor +# + +# +# Configure the Keto logging +# +log: + level: info + format: text + leak_sensitive_values: true + +# +# Configure the datasource. Alternative for development purposes is 'memory' (not persistent!) +# +dsn: postgres://postgres:postgres@ory-postgres:5432/keto?sslmode=disable&max_conns=20&max_idle_conns=4 + +# +# Set the required namespaces +# +namespaces: + - id: 0 + name: roles + +serve: + read: + host: 0.0.0.0 + port: 4466 + cors: + enabled: true + allowed_origins: + - http://localhost:3000 + - http://localhost:4000 + + write: + host: 0.0.0.0 + port: 4467 + cors: + enabled: true + allowed_origins: + - http://localhost:3000 + - http://localhost:4000 diff --git a/docker/ory-dev/postgres/init.sql b/docker/ory-dev/postgres/init.sql index 1e2b2ed..45836a3 100644 --- a/docker/ory-dev/postgres/init.sql +++ b/docker/ory-dev/postgres/init.sql @@ -3,3 +3,6 @@ GRANT ALL PRIVILEGES ON DATABASE kratos TO postgres; CREATE DATABASE hydra; GRANT ALL PRIVILEGES ON DATABASE hydra TO postgres; + +CREATE DATABASE keto; +GRANT ALL PRIVILEGES ON DATABASE keto TO postgres; -- 2.45.3 From aa037678cb4eb8ae12a9db4300d2dc6abedb3fcd Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 03:37:07 +0100 Subject: [PATCH 03/66] NORY-36: remove webauthn from identity schema --- docker/ory-dev/ory/kratos/identity.schema.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/docker/ory-dev/ory/kratos/identity.schema.json b/docker/ory-dev/ory/kratos/identity.schema.json index b937fc1..c3572c0 100644 --- a/docker/ory-dev/ory/kratos/identity.schema.json +++ b/docker/ory-dev/ory/kratos/identity.schema.json @@ -15,9 +15,6 @@ "credentials": { "password": { "identifier": true - }, - "webauthn": { - "identifier": true } }, "recovery": { -- 2.45.3 From 488cfa59d2f29f618036d7623ab4be3efd85b242 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 03:37:24 +0100 Subject: [PATCH 04/66] NORY-36: add Ory Keto APIs to dashboard project --- dashboard/src/ory/sdk/server/index.ts | 64 ++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/dashboard/src/ory/sdk/server/index.ts b/dashboard/src/ory/sdk/server/index.ts index fb2a176..7649433 100644 --- a/dashboard/src/ory/sdk/server/index.ts +++ b/dashboard/src/ory/sdk/server/index.ts @@ -1,6 +1,14 @@ 'use server'; -import { Configuration, FrontendApi, IdentityApi, MetadataApi, OAuth2Api } from '@ory/client'; +import { + Configuration, + FrontendApi, + IdentityApi, + MetadataApi, + OAuth2Api, + PermissionApi, + RelationshipApi, +} from '@ory/client'; // #################################################################################### @@ -92,3 +100,57 @@ const kratosMetadataApi = new MetadataApi( export async function getKratosMetadataApi() { return kratosMetadataApi; } + + +// #################################################################################### +// Relationship API +// #################################################################################### + +const relationshipApi = new RelationshipApi(new Configuration( + { + basePath: process.env.ORY_KETO_ADMIN_URL, + baseOptions: { + withCredentials: true, + }, + }, +)); + +export async function getRelationshipApi() { + return relationshipApi; +} + + +// #################################################################################### +// Permission API +// #################################################################################### + +const permissionApi = new PermissionApi(new Configuration( + { + basePath: process.env.ORY_KETO_ADMIN_URL, + baseOptions: { + withCredentials: true, + }, + }, +)); + +export async function getPermissionApi() { + return permissionApi; +} + + +// #################################################################################### +// Keto Metadata API +// #################################################################################### + +const ketoMetadataApi = new MetadataApi(new Configuration( + { + basePath: process.env.ORY_KETO_ADMIN_URL, + baseOptions: { + withCredentials: true, + }, + }, +)); + +export async function getKetoMetadataApi() { + return ketoMetadataApi; +} -- 2.45.3 From 9f497ce99dbee869030e028c5c7018915af588d9 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 03:37:35 +0100 Subject: [PATCH 05/66] NORY-36: add Ory Keto to dashboard stack overview --- dashboard/src/app/page.tsx | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/dashboard/src/app/page.tsx b/dashboard/src/app/page.tsx index 72fa7dc..cf379ab 100644 --- a/dashboard/src/app/page.tsx +++ b/dashboard/src/app/page.tsx @@ -1,4 +1,4 @@ -import { getHydraMetadataApi, getKratosMetadataApi } from '@/ory/sdk/server'; +import { getHydraMetadataApi, getKetoMetadataApi, getKratosMetadataApi } from '@/ory/sdk/server'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; @@ -17,6 +17,7 @@ export default async function RootPage() { const kratosDBStatusData = await fetch(process.env.ORY_KRATOS_ADMIN_URL + '/health/ready'); const kratosDBStatus = await kratosDBStatusData.json() as { status: string }; + const hydraMetadataApi = await getHydraMetadataApi(); const hydraVersion = await hydraMetadataApi @@ -30,13 +31,27 @@ export default async function RootPage() { const hydraDBStatusData = await fetch(process.env.ORY_KRATOS_ADMIN_URL + '/health/ready'); const hydraDBStatus = await hydraDBStatusData.json() as { status: string }; + + const ketoMetadataApi = await getKetoMetadataApi(); + + const ketoVersion = await ketoMetadataApi + .getVersion() + .then(res => res.data.version) + .catch(() => ''); + + const ketoStatusData = await fetch(process.env.ORY_KETO_ADMIN_URL + '/health/alive'); + const ketoStatus = await ketoStatusData.json() as { status: string }; + + const ketoDBStatusData = await fetch(process.env.ORY_KETO_ADMIN_URL + '/health/ready'); + const ketoDBStatus = await ketoDBStatusData.json() as { status: string }; + return (

Software Stack

See the list of all applications in your stack

-
+
@@ -73,7 +88,24 @@ export default async function RootPage() { -
+ + + + Ory Keto + + + Version {ketoVersion} + + + + + Keto {ketoStatus.status.toUpperCase()} + + + Database {ketoDBStatus.status.toUpperCase()} + + +
-- 2.45.3 From 66775a001e08208ada1f95e7414c3c3e7328d403 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 04:28:26 +0100 Subject: [PATCH 06/66] NORY-36: add error page for unauthorised users --- .../app/{ => (inside)}/application/page.tsx | 0 dashboard/src/app/(inside)/layout.tsx | 37 +++++++++++++++++++ dashboard/src/app/{ => (inside)}/page.tsx | 0 .../src/app/{ => (inside)}/user/[id]/page.tsx | 0 .../src/app/{ => (inside)}/user/action.ts | 0 .../app/{ => (inside)}/user/data-table.tsx | 4 +- .../src/app/{ => (inside)}/user/page.tsx | 2 +- .../src/app/(outside)/unauthorised/page.tsx | 11 ++++++ dashboard/src/app/layout.tsx | 31 +--------------- dashboard/src/components/error.tsx | 4 +- 10 files changed, 54 insertions(+), 35 deletions(-) rename dashboard/src/app/{ => (inside)}/application/page.tsx (100%) create mode 100644 dashboard/src/app/(inside)/layout.tsx rename dashboard/src/app/{ => (inside)}/page.tsx (100%) rename dashboard/src/app/{ => (inside)}/user/[id]/page.tsx (100%) rename dashboard/src/app/{ => (inside)}/user/action.ts (100%) rename dashboard/src/app/{ => (inside)}/user/data-table.tsx (99%) rename dashboard/src/app/{ => (inside)}/user/page.tsx (97%) create mode 100644 dashboard/src/app/(outside)/unauthorised/page.tsx diff --git a/dashboard/src/app/application/page.tsx b/dashboard/src/app/(inside)/application/page.tsx similarity index 100% rename from dashboard/src/app/application/page.tsx rename to dashboard/src/app/(inside)/application/page.tsx diff --git a/dashboard/src/app/(inside)/layout.tsx b/dashboard/src/app/(inside)/layout.tsx new file mode 100644 index 0000000..5c8f890 --- /dev/null +++ b/dashboard/src/app/(inside)/layout.tsx @@ -0,0 +1,37 @@ +import '../globals.css'; +import { Toaster } from '@/components/ui/sonner'; +import React from 'react'; +import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'; +import { AppSidebar } from '@/components/app-sidebar'; +import { Separator } from '@/components/ui/separator'; +import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList } from '@/components/ui/breadcrumb'; + +export default function InsideLayout({ children }: Readonly<{ children: React.ReactNode }>) { + return ( + + + +
+ + + { + // TODO: implement dynamic Breadcrumbs + } + + + + + Ory Dashboard + + + + +
+
+ {children} +
+
+ +
+ ); +} diff --git a/dashboard/src/app/page.tsx b/dashboard/src/app/(inside)/page.tsx similarity index 100% rename from dashboard/src/app/page.tsx rename to dashboard/src/app/(inside)/page.tsx diff --git a/dashboard/src/app/user/[id]/page.tsx b/dashboard/src/app/(inside)/user/[id]/page.tsx similarity index 100% rename from dashboard/src/app/user/[id]/page.tsx rename to dashboard/src/app/(inside)/user/[id]/page.tsx diff --git a/dashboard/src/app/user/action.ts b/dashboard/src/app/(inside)/user/action.ts similarity index 100% rename from dashboard/src/app/user/action.ts rename to dashboard/src/app/(inside)/user/action.ts diff --git a/dashboard/src/app/user/data-table.tsx b/dashboard/src/app/(inside)/user/data-table.tsx similarity index 99% rename from dashboard/src/app/user/data-table.tsx rename to dashboard/src/app/(inside)/user/data-table.tsx index 5819331..6476d7f 100644 --- a/dashboard/src/app/user/data-table.tsx +++ b/dashboard/src/app/(inside)/user/data-table.tsx @@ -6,7 +6,7 @@ import { DataTable } from '@/components/ui/data-table'; import { CircleCheck, CircleX, Copy, MoreHorizontal, Trash, UserCheck, UserMinus, UserPen, UserX } from 'lucide-react'; import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card'; import React, { useEffect, useRef, useState } from 'react'; -import { FetchIdentityPageProps } from '@/app/user/page'; +import { FetchIdentityPageProps } from '@/app/(inside)/user/page'; import { Spinner } from '@/components/ui/spinner'; import { DropdownMenu, @@ -29,7 +29,7 @@ import { AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; -import { blockIdentity, deleteIdentity, deleteIdentitySessions, unblockIdentity } from '@/app/user/action'; +import { blockIdentity, deleteIdentity, deleteIdentitySessions, unblockIdentity } from '@/app/(inside)/user/action'; interface IdentityDataTableProps { data: Identity[]; diff --git a/dashboard/src/app/user/page.tsx b/dashboard/src/app/(inside)/user/page.tsx similarity index 97% rename from dashboard/src/app/user/page.tsx rename to dashboard/src/app/(inside)/user/page.tsx index 6fe3108..f02c636 100644 --- a/dashboard/src/app/user/page.tsx +++ b/dashboard/src/app/(inside)/user/page.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { IdentityDataTable } from '@/app/user/data-table'; +import { IdentityDataTable } from '@/app/(inside)/user/data-table'; import { getIdentityApi } from '@/ory/sdk/server'; import { SearchInput } from '@/components/search-input'; diff --git a/dashboard/src/app/(outside)/unauthorised/page.tsx b/dashboard/src/app/(outside)/unauthorised/page.tsx new file mode 100644 index 0000000..dcd45fb --- /dev/null +++ b/dashboard/src/app/(outside)/unauthorised/page.tsx @@ -0,0 +1,11 @@ +import { ErrorDisplay } from '@/components/error'; + +export default async function UnauthorizedPage() { + return ( +
+ +
+ ); +} diff --git a/dashboard/src/app/layout.tsx b/dashboard/src/app/layout.tsx index 8fda46d..6c716cf 100644 --- a/dashboard/src/app/layout.tsx +++ b/dashboard/src/app/layout.tsx @@ -2,13 +2,8 @@ import type { Viewport } from 'next'; import { Inter } from 'next/font/google'; import './globals.css'; import { cn } from '@/lib/utils'; -import { Toaster } from '@/components/ui/sonner'; import React from 'react'; import { ThemeProvider } from 'next-themes'; -import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar'; -import { AppSidebar } from '@/components/app-sidebar'; -import { Separator } from '@/components/ui/separator'; -import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList } from '@/components/ui/breadcrumb'; const inter = Inter({ subsets: ['latin'] }); @@ -56,31 +51,7 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac enableSystem disableTransitionOnChange > - - - -
- - - { - // TODO: implement dynamic Breadcrumbs - } - - - - - Ory Dashboard - - - - -
-
- {children} -
-
- -
+ {children} diff --git a/dashboard/src/components/error.tsx b/dashboard/src/components/error.tsx index e264180..246431d 100644 --- a/dashboard/src/components/error.tsx +++ b/dashboard/src/components/error.tsx @@ -5,9 +5,9 @@ interface ErrorDisplayProps { export async function ErrorDisplay({ title, message }: ErrorDisplayProps) { return ( -
+ <>

{title}

{message}

-
+ ); } \ No newline at end of file -- 2.45.3 From 9ff25c4a6e5887c9b0834ddeb9ed7202361e1a1b Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 04:28:58 +0100 Subject: [PATCH 07/66] NORY-36: add permission check to dashboard middleware --- dashboard/src/middleware.ts | 39 +++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/dashboard/src/middleware.ts b/dashboard/src/middleware.ts index 4ef97c3..27c3d02 100644 --- a/dashboard/src/middleware.ts +++ b/dashboard/src/middleware.ts @@ -1,13 +1,13 @@ -import { NextResponse } from 'next/server'; +import { NextRequest, NextResponse } from 'next/server'; import { cookies } from 'next/headers'; -import { getFrontendApi } from '@/ory/sdk/server'; +import { getFrontendApi, getPermissionApi } from '@/ory/sdk/server'; -export async function middleware() { +export async function middleware(request: NextRequest) { - const api = await getFrontendApi(); + const frontendApi = await getFrontendApi(); const cookie = await cookies(); - const session = await api + const session = await frontendApi .toSession({ cookie: 'ory_kratos_session=' + cookie.get('ory_kratos_session')?.value }) .then((response) => response.data) .catch(() => null); @@ -25,7 +25,34 @@ export async function middleware() { return NextResponse.redirect(url); } - return NextResponse.next(); + if (request.nextUrl.pathname === '/unauthorised') { + return NextResponse.next(); + } + + const permissionApi = await getPermissionApi(); + const isAdmin = await permissionApi.checkPermission({ + namespace: 'roles', + object: 'admin', + relation: 'member', + subjectId: session!.identity!.id, + }) + .then(({ data: { allowed } }) => { + console.log('is_admin', session!.identity!.id, allowed); + return allowed; + }) + .catch((response) => { + console.log('is_admin', session!.identity!.id, response, 'check failed'); + return false; + }); + + if (isAdmin) { + return NextResponse.next(); + } else { + console.log('MISSING PERMISSION'); + const url = `${process.env.NEXT_PUBLIC_DASHBOARD_NODE_URL}/unauthorised`; + console.log('REDIRECT TO', url); + return NextResponse.redirect(url!); + } } export const config = { -- 2.45.3 From 08e65e0ec3f14ce9a59f8000bb92c06564e49dbd Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 16:37:12 +0100 Subject: [PATCH 08/66] NORY-36: remove async from error display --- dashboard/src/components/error.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dashboard/src/components/error.tsx b/dashboard/src/components/error.tsx index 246431d..5e5ac12 100644 --- a/dashboard/src/components/error.tsx +++ b/dashboard/src/components/error.tsx @@ -3,7 +3,7 @@ interface ErrorDisplayProps { message: string; } -export async function ErrorDisplay({ title, message }: ErrorDisplayProps) { +export function ErrorDisplay({ title, message }: ErrorDisplayProps) { return ( <>

{title}

-- 2.45.3 From faa3485ca87d8932107e1e22414b73cf4fd80479 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 16:37:33 +0100 Subject: [PATCH 09/66] NORY-36: add logout button to /unauthorised --- dashboard/src/app/(outside)/unauthorised/page.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/dashboard/src/app/(outside)/unauthorised/page.tsx b/dashboard/src/app/(outside)/unauthorised/page.tsx index dcd45fb..538882b 100644 --- a/dashboard/src/app/(outside)/unauthorised/page.tsx +++ b/dashboard/src/app/(outside)/unauthorised/page.tsx @@ -1,11 +1,20 @@ -import { ErrorDisplay } from '@/components/error'; +'use client'; -export default async function UnauthorizedPage() { +import { ErrorDisplay } from '@/components/error'; +import { Button } from '@/components/ui/button'; +import { LogoutLink } from '@/ory'; +import { LogOut } from 'lucide-react'; + +export default function UnauthorizedPage() { return (
+
); } -- 2.45.3 From 40a46f6457e50a67e3d19688799f662a91b3ec04 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sun, 15 Dec 2024 16:37:51 +0100 Subject: [PATCH 10/66] NORY-36: improve permission check in middleware --- dashboard/src/middleware.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/dashboard/src/middleware.ts b/dashboard/src/middleware.ts index 27c3d02..52d7714 100644 --- a/dashboard/src/middleware.ts +++ b/dashboard/src/middleware.ts @@ -25,10 +25,6 @@ export async function middleware(request: NextRequest) { return NextResponse.redirect(url); } - if (request.nextUrl.pathname === '/unauthorised') { - return NextResponse.next(); - } - const permissionApi = await getPermissionApi(); const isAdmin = await permissionApi.checkPermission({ namespace: 'roles', @@ -46,15 +42,25 @@ export async function middleware(request: NextRequest) { }); if (isAdmin) { + if (request.nextUrl.pathname === '/unauthorised') { + return redirect('/', 'HAS PERMISSION BUT ACCESSING /unauthorized'); + } return NextResponse.next(); } else { - console.log('MISSING PERMISSION'); - const url = `${process.env.NEXT_PUBLIC_DASHBOARD_NODE_URL}/unauthorised`; - console.log('REDIRECT TO', url); - return NextResponse.redirect(url!); + if (request.nextUrl.pathname === '/unauthorised') { + return NextResponse.next(); + } + return redirect('/unauthorised', 'MISSING SESSION'); } } +function redirect(path: string, reason: string) { + console.log(reason); + const url = `${process.env.NEXT_PUBLIC_DASHBOARD_NODE_URL}${path}`; + console.log('REDIRECT TO', url); + return NextResponse.redirect(url!); +} + export const config = { matcher: '/((?!api|_next/static|_next/image|favicon.png|sitemap.xml|robots.txt).*)', }; -- 2.45.3 From 67758135c39f2b44b296d906eab96b0b715a44a9 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Mon, 16 Dec 2024 00:25:47 +0100 Subject: [PATCH 11/66] NORY-36: add script to assign admin role to identity --- docker/ory-dev/keto-make-admin.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 docker/ory-dev/keto-make-admin.sh diff --git a/docker/ory-dev/keto-make-admin.sh b/docker/ory-dev/keto-make-admin.sh new file mode 100644 index 0000000..cb60efe --- /dev/null +++ b/docker/ory-dev/keto-make-admin.sh @@ -0,0 +1,19 @@ +# this script gives the referenced identity the admin role +# make sure to provide the id of the identity + +# check if a identity id argument was provided +if [ -z "$1" ]; then + echo "Error: please provide an identity id." + exit 1 +fi + +# set user id variable +IDENTITY_ID=$1 + +# execute Ory Keto CLI command to make user an admin +docker compose exec ory-keto \ + ory create relation-tuples \ + \{'namespace':'roles','object':'admin','relation':'member','subject_id':IDENTITY_ID} + +# respond with success message +echo "Identity $IDENTITY_ID was given the admin role." \ No newline at end of file -- 2.45.3 From 1e93ced78bd0dfabcee81c936cda851b8f9ad34c Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Tue, 17 Dec 2024 17:36:16 +0100 Subject: [PATCH 12/66] NORY-36: show user ID on /unauthorized page --- .../src/app/(outside)/unauthorised/page.tsx | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/dashboard/src/app/(outside)/unauthorised/page.tsx b/dashboard/src/app/(outside)/unauthorised/page.tsx index 538882b..21905ef 100644 --- a/dashboard/src/app/(outside)/unauthorised/page.tsx +++ b/dashboard/src/app/(outside)/unauthorised/page.tsx @@ -2,15 +2,34 @@ import { ErrorDisplay } from '@/components/error'; import { Button } from '@/components/ui/button'; -import { LogoutLink } from '@/ory'; +import { kratos, LogoutLink } from '@/ory'; import { LogOut } from 'lucide-react'; +import { useEffect, useState } from 'react'; +import { Session } from '@ory/client'; +import { Skeleton } from '@/components/ui/skeleton'; export default function UnauthorizedPage() { + + const [session, setSession] = useState(undefined); + + useEffect(() => { + kratos.toSession() + .then((response) => setSession(response.data)); + }, []); + return (
+ + { + session ? +

USER ID {session.identity?.id}

+ : + + } +
); -- 2.45.3 From bc30c83dcb1a1862a2c937eda21067cd93344a36 Mon Sep 17 00:00:00 2001 From: Markus Thielker Date: Sat, 28 Dec 2024 23:10:45 +0100 Subject: [PATCH 23/66] NORY-47: add shadcn textarea component --- dashboard/src/components/ui/textarea.tsx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 dashboard/src/components/ui/textarea.tsx diff --git a/dashboard/src/components/ui/textarea.tsx b/dashboard/src/components/ui/textarea.tsx new file mode 100644 index 0000000..fcbdc98 --- /dev/null +++ b/dashboard/src/components/ui/textarea.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; + +import { cn } from '@/lib/utils'; + +const Textarea = React.forwardRef< + HTMLTextAreaElement, + React.ComponentProps<'textarea'> +>(({ className, ...props }, ref) => { + return ( +