Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: configure number of users allowed per server #233

Merged
merged 3 commits into from Nov 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions server/package.json
Expand Up @@ -14,8 +14,8 @@
},
"dependencies": {
"@octokit/rest": "18.0.6",
"@prisma/cli": "2.9.0",
"@prisma/client": "2.9.0",
"@prisma/cli": "2.10.2",
"@prisma/client": "2.10.2",
"apollo-server": "2.18.2",
"apollo-server-express": "2.18.2",
"bullmq": "1.9.0",
Expand Down
67 changes: 67 additions & 0 deletions server/prisma/migrations/20201106104236-unlink-user/README.md
@@ -0,0 +1,67 @@
# Migration `20201106104236-unlink-user`

This migration has been generated at 11/6/2020, 10:42:36 AM.
You can check out the [state of the schema](./schema.prisma) after the migration.

## Database Steps

```sql
ALTER TABLE "public"."App" ALTER COLUMN "userId" DROP NOT NULL

ALTER TABLE "public"."AppBuild" ALTER COLUMN "userId" DROP NOT NULL

ALTER TABLE "public"."Database" ALTER COLUMN "userId" DROP NOT NULL

ALTER INDEX "public"."User.githubId" RENAME TO "User.githubId_unique"

ALTER INDEX "public"."User.username" RENAME TO "User.username_unique"
```

## Changes

```diff
diff --git schema.prisma schema.prisma
migration 20200912135606-remove-github-fields..20201106104236-unlink-user
--- datamodel.dml
+++ datamodel.dml
@@ -1,7 +1,7 @@
datasource db {
provider = "postgresql"
- url = "***"
+ url = "***"
}
generator client {
provider = "prisma-client-js"
@@ -25,10 +25,8 @@
id String @default(uuid()) @id
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
name String
- user User @relation(fields: [userId], references: [id])
- userId String
appBuild AppBuild[]
databases Database[] @relation(references: [id])
}
@@ -38,10 +36,8 @@
updatedAt DateTime @default(now())
status AppBuildStatus
app App @relation(fields: [appId], references: [id])
appId String
- user User @relation(fields: [userId], references: [id])
- userId String
}
enum AppBuildStatus {
PENDING
@@ -55,12 +51,9 @@
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
name String
type DbTypes
- user User @relation(fields: [userId], references: [id])
- userId String
apps App[] @relation(references: [id])
-
}
enum DbTypes {
REDIS
```
63 changes: 63 additions & 0 deletions server/prisma/migrations/20201106104236-unlink-user/schema.prisma
@@ -0,0 +1,63 @@
datasource db {
provider = "postgresql"
url = "***"
}

generator client {
provider = "prisma-client-js"
}

model User {
id String @default(uuid()) @id
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
username String @unique
avatarUrl String
email String
githubId String @unique
githubAccessToken String
App App[]
Database Database[]
AppBuild AppBuild[]
}

model App {
id String @default(uuid()) @id
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
name String
appBuild AppBuild[]
databases Database[] @relation(references: [id])
}

model AppBuild {
id String @default(uuid()) @id
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
status AppBuildStatus
app App @relation(fields: [appId], references: [id])
appId String
}

enum AppBuildStatus {
PENDING
IN_PROGRESS
COMPLETED
ERRORED
}

model Database {
id String @default(uuid()) @id
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
name String
type DbTypes
apps App[] @relation(references: [id])
}

enum DbTypes {
REDIS
POSTGRESQL
MONGODB
MYSQL
}
35 changes: 35 additions & 0 deletions server/prisma/migrations/20201106104236-unlink-user/steps.json
@@ -0,0 +1,35 @@
{
"version": "0.3.14-fixed",
"steps": [
{
"tag": "DeleteField",
"model": "App",
"field": "user"
},
{
"tag": "DeleteField",
"model": "App",
"field": "userId"
},
{
"tag": "DeleteField",
"model": "AppBuild",
"field": "user"
},
{
"tag": "DeleteField",
"model": "AppBuild",
"field": "userId"
},
{
"tag": "DeleteField",
"model": "Database",
"field": "user"
},
{
"tag": "DeleteField",
"model": "Database",
"field": "userId"
}
]
}
3 changes: 2 additions & 1 deletion server/prisma/migrations/migrate.lock
Expand Up @@ -2,4 +2,5 @@

20200510152117-init
20200628123314-link-databases-to-app
20200912135606-remove-github-fields
20200912135606-remove-github-fields
20201106104236-unlink-user
7 changes: 0 additions & 7 deletions server/prisma/schema.prisma
Expand Up @@ -26,8 +26,6 @@ model App {
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
name String
user User @relation(fields: [userId], references: [id])
userId String
appBuild AppBuild[]
databases Database[] @relation(references: [id])
}
Expand All @@ -39,8 +37,6 @@ model AppBuild {
status AppBuildStatus
app App @relation(fields: [appId], references: [id])
appId String
user User @relation(fields: [userId], references: [id])
userId String
}

enum AppBuildStatus {
Expand All @@ -56,10 +52,7 @@ model Database {
updatedAt DateTime @default(now())
name String
type DbTypes
user User @relation(fields: [userId], references: [id])
userId String
apps App[] @relation(references: [id])

}

enum DbTypes {
Expand Down
6 changes: 5 additions & 1 deletion server/src/config.ts
Expand Up @@ -3,7 +3,6 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
import { join } from 'path';
import { generateKeyPairSync } from 'crypto';
import sshpk from 'sshpk';
import Redis from 'ioredis';

const envSchema = yup.object({
JWT_SECRET: yup
Expand All @@ -22,6 +21,8 @@ const envSchema = yup.object({
.string()
.required('Please provide a valid DOKKU_SSH_HOST env variable.'),
DOKKU_SSH_PORT: yup.string(),
// Temporary solution until we have proper user management
NUMBER_USERS_ALLOWED: yup.string(),
});

try {
Expand Down Expand Up @@ -90,4 +91,7 @@ export const config = {
dokkuSshPort: process.env.DOKKU_SSH_PORT ? +process.env.DOKKU_SSH_PORT : 22,
privateKey,
sshKeyPath,
numberUsersAllowed: process.env.NUMBER_USERS_ALLOWED
? +process.env.NUMBER_USERS_ALLOWED
: 1,
};
5 changes: 0 additions & 5 deletions server/src/graphql/mutations/createApp.ts
Expand Up @@ -36,11 +36,6 @@ export const createApp: MutationResolvers['createApp'] = async (
const app = await prisma.app.create({
data: {
name: input.name,
user: {
connect: {
id: userId,
},
},
},
});

Expand Down
6 changes: 0 additions & 6 deletions server/src/graphql/mutations/linkDatabase.ts
Expand Up @@ -43,12 +43,6 @@ export const linkDatabase: MutationResolvers['linkDatabase'] = async (
throw new Error(`Database with ID ${databaseId} not found`);
}

if (app.userId !== userId || database.userId !== userId) {
throw new Error(
`App with ID ${appId} or database with ID ${databaseId} does not belong to ${userId}`
);
}

const isLinked = database.apps.length === 1;

if (isLinked) {
Expand Down
2 changes: 1 addition & 1 deletion server/src/graphql/mutations/loginWithGithub.ts
Expand Up @@ -65,7 +65,7 @@ export const loginWithGithub: MutationResolvers['loginWithGithub'] = async (
// We limit to only one user per server for now
// This can be fixed later by allowing user to invite other users for example
const nbUsers = await prisma.user.count();
if (nbUsers >= 1) {
if (nbUsers >= config.numberUsersAllowed) {
throw new Error('Unauthorized');
}

Expand Down
6 changes: 0 additions & 6 deletions server/src/graphql/mutations/unlinkDatabase.ts
Expand Up @@ -40,12 +40,6 @@ export const unlinkDatabase: MutationResolvers['unlinkDatabase'] = async (
throw new Error(`Database with ID ${databaseId} not found`);
}

if (app.userId !== userId || database.userId !== userId) {
throw new Error(
`App with ID ${appId} or database with ID ${databaseId} does not belong to ${userId}`
);
}

const isLinked = database.apps.length === 1;

if (!isLinked) {
Expand Down
3 changes: 2 additions & 1 deletion server/src/graphql/queries/app.ts
Expand Up @@ -9,5 +9,6 @@ export const app: QueryResolvers['app'] = async (_, { appId }, { userId }) => {
const app = await prisma.app.findOne({
where: { id: appId },
});
return app.userId === userId ? app : null;

return app;
};
3 changes: 2 additions & 1 deletion server/src/graphql/queries/database.ts
Expand Up @@ -13,5 +13,6 @@ export const database: QueryResolvers['database'] = async (
const database = await prisma.database.findOne({
where: { id: databaseId },
});
return database.userId === userId ? database : null;

return database;
};
6 changes: 0 additions & 6 deletions server/src/graphql/queries/databaseInfo.ts
Expand Up @@ -23,12 +23,6 @@ export const databaseInfo: QueryResolvers['databaseInfo'] = async (
throw new Error(`Database with ID ${databaseId} not found`);
}

if (database.userId !== userId) {
throw new Error(
`Database with ID ${databaseId} does not belong to ${userId}`
);
}

const dbType = dbTypeToDokkuPlugin(database.type);

const ssh = await sshConnect();
Expand Down
5 changes: 0 additions & 5 deletions server/src/graphql/queries/databaseLogs.ts
Expand Up @@ -22,11 +22,6 @@ export const databaseLogs: QueryResolvers['databaseLogs'] = async (
if (!database) {
throw new Error(`Database with ID ${databaseId} not found`);
}
if (database.userId !== userId) {
throw new Error(
`Database with ID ${databaseId} does not belong to ${userId}`
);
}

const dbType = dbTypeToDokkuPlugin(database.type);

Expand Down
5 changes: 0 additions & 5 deletions server/src/queues/createDatabase.ts
Expand Up @@ -70,11 +70,6 @@ const worker = new Worker(
data: {
name: databaseName,
type: databaseType,
user: {
connect: {
id: userId,
},
},
},
});

Expand Down
10 changes: 0 additions & 10 deletions server/src/queues/synchroniseServer.ts
Expand Up @@ -65,11 +65,6 @@ const worker = new Worker(
await prisma.app.create({
data: {
name: dokkuApp,
user: {
connect: {
id: user.id,
},
},
},
});
}
Expand Down Expand Up @@ -120,11 +115,6 @@ const worker = new Worker(
data: {
name: dokkuDatabase,
type: databaseToCheck,
user: {
connect: {
id: user.id,
},
},
},
});
}
Expand Down
1 change: 1 addition & 0 deletions website/docs/advanced/configuration.md
Expand Up @@ -14,5 +14,6 @@ Here is a list of the variables you can change:
- `REDIS_URL`: Redis connection string.
- `DOKKU_SSH_HOST`: Ip address of the server.
- `DOKKU_SSH_PORT`: Port used to connect to the server via SSH.
- `NUMBER_USERS_ALLOWED`: Temporary solution to allow multiple users to login to your server. By default only one user is allowed to login to your server.

For example if you want to change the `JWT_SECRET` configuration run: `dokku config:set ledokku JWT_SECRET my_new_value`