Skip to content

Commit e33863d

Browse files
authored
Merge pull request #657 from kubero-dev/feature/add-user-database
Feature/add user database
2 parents 8e19f0e + 6806315 commit e33863d

35 files changed

Lines changed: 994 additions & 308 deletions

client/src/components/activity/view.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<div class="d-flex">
1515
<!--<strong class="me-4">{{ event.metadata.creationTimestamp }}</strong>-->
1616
<div>
17-
<strong>{{ event.user }}: </strong> {{ event.action }} {{ event.resource }}
17+
<strong>{{ event.users.username }}: </strong> {{ event.action }} {{ event.resource }}
1818
<div class="text-caption">
1919
{{ event.timestamp }} · v{{ event.id }} · {{ event.message }}
2020
</div>
@@ -49,6 +49,13 @@ type AuditEvent = {
4949
severity: string,
5050
color: string,
5151
icon: string,
52+
users: {
53+
id?: string,
54+
username: string,
55+
email?: string,
56+
firstName?: string,
57+
lastName?: string,
58+
},
5259
}
5360
5461
type Audit = {

client/src/components/apps/eventsAudit.vue

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<div>
1919
<!--<strong class="me-4">{{ event.metadata.creationTimestamp }}</strong>-->
2020
<div>
21-
<strong>{{ event.user }}: </strong> {{ event.action }} {{ event.resource }}
21+
<strong>{{ event.users.username }}: </strong> {{ event.action }} {{ event.resource }}
2222
<div class="text-caption">
2323
{{ event.timestamp }} · v{{ event.id }} · {{ event.message }}
2424
</div>
@@ -63,6 +63,13 @@ type AuditEvent = {
6363
severity: string,
6464
color: string,
6565
icon: string,
66+
users: {
67+
id?: string,
68+
username: string,
69+
email?: string,
70+
firstName?: string,
71+
lastName?: string,
72+
},
6673
}
6774
6875
@@ -117,7 +124,7 @@ export default defineComponent({
117124
return "mdi-rocket";
118125
},
119126
loadAudit() {
120-
axios.get('/api/audit', { params: { limit: this.limit, pipeline: this.pipeline, phase: this.phase, app: this.app } }).then(response => {
127+
axios.get(`/api/audit/app/${this.pipeline}/${this.phase}/${this.app}`, { params: { limit: this.limit } }).then(response => {
121128
this.auditEvents = response.data.audit;
122129
this.count = response.data.count;
123130
});

server/.env.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
PORT=2000
22
DEBUG=*.*
3-
DATABASE_URL="file:../db/kubero.db"
3+
DATABASE_URL="file:../db/kubero.sqlite?mode=rwc&_journal=WAL&_busy_timeout=5000"
44
LOGLEVEL=verbose
55
NODE_ENV=production
66

server/package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,16 @@
2020
"test:watch": "jest --watch",
2121
"test:cov": "jest --coverage",
2222
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
23-
"test:e2e": "jest --config ./test/jest-e2e.json"
23+
"test:e2e": "jest --config ./test/jest-e2e.json",
24+
"prisma:init": "npx prisma migrate dev --name init --create-only",
25+
"prisma:generate": "npx prisma generate",
26+
"prisma:studio": "npx prisma studio",
27+
"prisma:reset": "npx prisma migrate reset --force",
28+
"prisma:deploy": "npx prisma migrate deploy",
29+
"prisma:migrate": "npx prisma migrate deploy",
30+
"prisma:push": "npx prisma db push",
31+
"prisma:db:seed": "npx prisma db seed --preview-feature",
32+
"prisma:db:seed:test": "npx prisma db seed --preview-feature --schema=./prisma/schema.prod.prisma"
2433
},
2534
"dependencies": {
2635
"@kubernetes/client-node": "^0.22.3",

server/prisma/dev_qa.db

Whitespace-only changes.

server/prisma/migrations/20250612204421_init/migration.sql

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
-- CreateTable
2+
CREATE TABLE "Audit" (
3+
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
4+
"timestamp" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
5+
"severity" TEXT NOT NULL DEFAULT 'normal',
6+
"action" TEXT NOT NULL,
7+
"namespace" TEXT NOT NULL,
8+
"phase" TEXT NOT NULL,
9+
"app" TEXT NOT NULL,
10+
"pipeline" TEXT NOT NULL,
11+
"resource" TEXT NOT NULL DEFAULT 'unknown',
12+
"message" TEXT NOT NULL,
13+
"user" TEXT NOT NULL,
14+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
15+
"updatedAt" DATETIME NOT NULL,
16+
CONSTRAINT "Audit_user_fkey" FOREIGN KEY ("user") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
17+
);
18+
19+
-- CreateTable
20+
CREATE TABLE "User" (
21+
"id" TEXT NOT NULL PRIMARY KEY,
22+
"username" TEXT NOT NULL,
23+
"firstName" TEXT,
24+
"lastName" TEXT,
25+
"company" TEXT,
26+
"location" TEXT,
27+
"email" TEXT NOT NULL,
28+
"emailVerified" DATETIME,
29+
"password" TEXT NOT NULL,
30+
"twoFaSecret" TEXT,
31+
"twoFaEnabled" BOOLEAN NOT NULL DEFAULT false,
32+
"image" TEXT,
33+
"roleId" TEXT,
34+
"isActive" BOOLEAN NOT NULL DEFAULT true,
35+
"lastLogin" DATETIME,
36+
"lastIp" TEXT,
37+
"provider" TEXT DEFAULT 'local',
38+
"providerId" TEXT,
39+
"providerData" TEXT,
40+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
41+
"updatedAt" DATETIME NOT NULL,
42+
CONSTRAINT "User_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role" ("id") ON DELETE SET NULL ON UPDATE CASCADE
43+
);
44+
45+
-- CreateTable
46+
CREATE TABLE "UserGroup" (
47+
"id" TEXT NOT NULL PRIMARY KEY,
48+
"name" TEXT NOT NULL,
49+
"description" TEXT,
50+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
51+
"updatedAt" DATETIME NOT NULL
52+
);
53+
54+
-- CreateTable
55+
CREATE TABLE "Role" (
56+
"id" TEXT NOT NULL PRIMARY KEY,
57+
"name" TEXT NOT NULL,
58+
"description" TEXT,
59+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
60+
"updatedAt" DATETIME NOT NULL
61+
);
62+
63+
-- CreateTable
64+
CREATE TABLE "Token" (
65+
"id" TEXT NOT NULL PRIMARY KEY,
66+
"userId" TEXT NOT NULL,
67+
"token" TEXT NOT NULL,
68+
"expiresAt" DATETIME NOT NULL,
69+
"isActive" BOOLEAN NOT NULL DEFAULT true,
70+
"lastUsed" DATETIME,
71+
"lastIp" TEXT,
72+
"description" TEXT,
73+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
74+
"updatedAt" DATETIME NOT NULL,
75+
CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
76+
);
77+
78+
-- CreateTable
79+
CREATE TABLE "Permission" (
80+
"id" TEXT NOT NULL PRIMARY KEY,
81+
"resource" TEXT NOT NULL,
82+
"action" TEXT NOT NULL,
83+
"namespace" TEXT,
84+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
85+
"updatedAt" DATETIME NOT NULL
86+
);
87+
88+
-- CreateTable
89+
CREATE TABLE "_UserToUserGroup" (
90+
"A" TEXT NOT NULL,
91+
"B" TEXT NOT NULL,
92+
CONSTRAINT "_UserToUserGroup_A_fkey" FOREIGN KEY ("A") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
93+
CONSTRAINT "_UserToUserGroup_B_fkey" FOREIGN KEY ("B") REFERENCES "UserGroup" ("id") ON DELETE CASCADE ON UPDATE CASCADE
94+
);
95+
96+
-- CreateTable
97+
CREATE TABLE "_PermissionToRole" (
98+
"A" TEXT NOT NULL,
99+
"B" TEXT NOT NULL,
100+
CONSTRAINT "_PermissionToRole_A_fkey" FOREIGN KEY ("A") REFERENCES "Permission" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
101+
CONSTRAINT "_PermissionToRole_B_fkey" FOREIGN KEY ("B") REFERENCES "Role" ("id") ON DELETE CASCADE ON UPDATE CASCADE
102+
);
103+
104+
-- CreateTable
105+
CREATE TABLE "_PermissionToToken" (
106+
"A" TEXT NOT NULL,
107+
"B" TEXT NOT NULL,
108+
CONSTRAINT "_PermissionToToken_A_fkey" FOREIGN KEY ("A") REFERENCES "Permission" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
109+
CONSTRAINT "_PermissionToToken_B_fkey" FOREIGN KEY ("B") REFERENCES "Token" ("id") ON DELETE CASCADE ON UPDATE CASCADE
110+
);
111+
112+
-- CreateIndex
113+
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
114+
115+
-- CreateIndex
116+
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
117+
118+
-- CreateIndex
119+
CREATE UNIQUE INDEX "UserGroup_name_key" ON "UserGroup"("name");
120+
121+
-- CreateIndex
122+
CREATE UNIQUE INDEX "Role_name_key" ON "Role"("name");
123+
124+
-- CreateIndex
125+
CREATE UNIQUE INDEX "Token_token_key" ON "Token"("token");
126+
127+
-- CreateIndex
128+
CREATE UNIQUE INDEX "_UserToUserGroup_AB_unique" ON "_UserToUserGroup"("A", "B");
129+
130+
-- CreateIndex
131+
CREATE INDEX "_UserToUserGroup_B_index" ON "_UserToUserGroup"("B");
132+
133+
-- CreateIndex
134+
CREATE UNIQUE INDEX "_PermissionToRole_AB_unique" ON "_PermissionToRole"("A", "B");
135+
136+
-- CreateIndex
137+
CREATE INDEX "_PermissionToRole_B_index" ON "_PermissionToRole"("B");
138+
139+
-- CreateIndex
140+
CREATE UNIQUE INDEX "_PermissionToToken_AB_unique" ON "_PermissionToToken"("A", "B");
141+
142+
-- CreateIndex
143+
CREATE INDEX "_PermissionToToken_B_index" ON "_PermissionToToken"("B");

server/prisma/schema.prisma

Lines changed: 95 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,22 @@ generator client {
1919
}
2020

2121
model Audit {
22-
id Int @id @default(autoincrement())
23-
timestamp DateTime @default(now())
24-
user String
25-
severity Severity @default(normal)
22+
id Int @id @default(autoincrement())
23+
timestamp DateTime @default(now())
24+
severity Severity @default(normal)
2625
action String
2726
namespace String
2827
phase String
2928
app String
3029
pipeline String
31-
resource ResourceType @default(unknown)
30+
resource ResourceType @default(unknown)
3231
message String
32+
33+
user String
34+
users User @relation(fields: [user], references: [id])
35+
36+
createdAt DateTime @default(now())
37+
updatedAt DateTime @updatedAt
3338
}
3439

3540
enum Severity {
@@ -58,4 +63,88 @@ enum ResourceType {
5863
config
5964
addons
6065
kubernetes
61-
}
66+
}
67+
68+
model User {
69+
id String @id @default(cuid())
70+
username String @unique
71+
firstName String?
72+
lastName String?
73+
email String @unique
74+
emailVerified DateTime?
75+
password String
76+
twoFaSecret String?
77+
twoFaEnabled Boolean @default(false)
78+
image String?
79+
80+
roleId String?
81+
role Role? @relation(fields: [roleId], references: [id])
82+
userGroups UserGroup[] // Many-to-many relationship with UserGroup
83+
84+
isActive Boolean @default(true)
85+
lastLogin DateTime?
86+
lastIp String? // Last known IP address
87+
88+
provider String? @default("local") // e.g., "github", "local", ...
89+
providerId String? // ID from the external provider (e.g., GitHub ID)
90+
providerData String? // JSON string for additional provider data
91+
92+
tokens Token[]
93+
94+
createdAt DateTime @default(now())
95+
updatedAt DateTime @updatedAt
96+
Audit Audit[]
97+
}
98+
99+
model UserGroup {
100+
id String @id @default(uuid())
101+
name String @unique
102+
description String?
103+
104+
users User[]
105+
106+
createdAt DateTime @default(now())
107+
updatedAt DateTime @updatedAt
108+
}
109+
110+
model Role {
111+
id String @id @default(cuid())
112+
name String @unique
113+
description String?
114+
115+
users User[] // Users associated with this role
116+
permissions Permission[] // Permissions directly assigned to this role
117+
118+
createdAt DateTime @default(now())
119+
updatedAt DateTime @updatedAt
120+
}
121+
122+
model Token {
123+
id String @id @default(cuid())
124+
userId String
125+
user User @relation(fields: [userId], references: [id])
126+
token String @unique
127+
expiresAt DateTime
128+
isActive Boolean @default(true)
129+
lastUsed DateTime?
130+
lastIp String? // Last known IP address used for this token
131+
description String? // Description of the token's purpose
132+
133+
permissions Permission[] // Permissions associated with this token
134+
135+
createdAt DateTime @default(now())
136+
updatedAt DateTime @updatedAt
137+
}
138+
139+
model Permission {
140+
id String @id @default(cuid())
141+
resource ResourceType
142+
action String // e.g., "create", "read", "update", "delete"
143+
namespace String? // Optional namespace for scoping permissions
144+
145+
roles Role[] // Roles that have this permission
146+
tokens Token[] // Tokens that have this permission
147+
148+
createdAt DateTime @default(now())
149+
updatedAt DateTime @updatedAt
150+
}

0 commit comments

Comments
 (0)