feat: add install mode verification

This commit is contained in:
swve 2023-07-12 12:52:25 +01:00
parent 6e9998d45c
commit ce50fa760f
7 changed files with 64 additions and 15 deletions

View file

@ -1,3 +1,4 @@
from gettext import install
from typing import Literal, Optional from typing import Literal, Optional
from pydantic import BaseModel from pydantic import BaseModel
import os import os
@ -16,6 +17,7 @@ class CookieConfig(BaseModel):
class GeneralConfig(BaseModel): class GeneralConfig(BaseModel):
development_mode: bool development_mode: bool
install_mode: bool
class SecurityConfig(BaseModel): class SecurityConfig(BaseModel):
@ -71,6 +73,10 @@ def get_learnhouse_config() -> LearnHouseConfig:
development_mode = env_development_mode or yaml_config.get("general", {}).get( development_mode = env_development_mode or yaml_config.get("general", {}).get(
"development_mode" "development_mode"
) )
env_install_mode = os.environ.get("LEARNHOUSE_INSTALL_MODE")
install_mode = env_install_mode or yaml_config.get("general", {}).get(
"install_mode"
)
# Security Config # Security Config
env_auth_jwt_secret_key = os.environ.get("LEARNHOUSE_AUTH_JWT_SECRET_KEY") env_auth_jwt_secret_key = os.environ.get("LEARNHOUSE_AUTH_JWT_SECRET_KEY")
@ -129,7 +135,7 @@ def get_learnhouse_config() -> LearnHouseConfig:
env_content_delivery_type = os.environ.get("LEARNHOUSE_CONTENT_DELIVERY_TYPE") env_content_delivery_type = os.environ.get("LEARNHOUSE_CONTENT_DELIVERY_TYPE")
content_delivery_type: str = env_content_delivery_type or ( content_delivery_type: str = env_content_delivery_type or (
(yaml_config.get("hosting_config", {}).get("content_delivery", {}).get("type")) (yaml_config.get("hosting_config", {}).get("content_delivery", {}).get("type"))
or "filesystem" or "filesystem"
) # default to filesystem ) # default to filesystem
@ -206,7 +212,9 @@ def get_learnhouse_config() -> LearnHouseConfig:
site_name=site_name, site_name=site_name,
site_description=site_description, site_description=site_description,
contact_email=contact_email, contact_email=contact_email,
general_config=GeneralConfig(development_mode=bool(development_mode)), general_config=GeneralConfig(
development_mode=bool(development_mode), install_mode=bool(install_mode)
),
hosting_config=hosting_config, hosting_config=hosting_config,
database_config=database_config, database_config=database_config,
security_config=SecurityConfig(auth_jwt_secret_key=auth_jwt_secret_key), security_config=SecurityConfig(auth_jwt_secret_key=auth_jwt_secret_key),

View file

@ -3,7 +3,8 @@ site_description: LearnHouse is an open-source platform tailored for learning ex
contact_email: hi@learnhouse.app contact_email: hi@learnhouse.app
general: general:
development_mode: true development_mode: false
install_mode: false
security: security:
auth_jwt_secret_key: secret auth_jwt_secret_key: secret

View file

@ -1,3 +1,4 @@
import { isInstallModeEnabled } from "@services/install/install";
import { LEARNHOUSE_DOMAIN, getDefaultOrg, isMultiOrgModeEnabled } from "./services/config/config"; import { LEARNHOUSE_DOMAIN, getDefaultOrg, isMultiOrgModeEnabled } from "./services/config/config";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import type { NextRequest } from "next/server"; import type { NextRequest } from "next/server";
@ -16,7 +17,7 @@ export const config = {
], ],
}; };
export default function middleware(req: NextRequest) { export default async function middleware(req: NextRequest) {
// Get initial data // Get initial data
const hosting_mode = isMultiOrgModeEnabled() ? "multi" : "single"; const hosting_mode = isMultiOrgModeEnabled() ? "multi" : "single";
const default_org = getDefaultOrg(); const default_org = getDefaultOrg();
@ -30,7 +31,13 @@ export default function middleware(req: NextRequest) {
// Install Page // Install Page
if (pathname.startsWith("/install")) { if (pathname.startsWith("/install")) {
return NextResponse.rewrite(new URL(pathname, req.url)); // Check if install mode is enabled
const install_mode = await isInstallModeEnabled();
if (install_mode) {
return NextResponse.rewrite(new URL(pathname, req.url));
} else {
return NextResponse.redirect(new URL("/", req.url));
}
} }
// Dynamic Pages Editor // Dynamic Pages Editor

View file

@ -30,3 +30,13 @@ export async function createDefaultElements() {
const res = await errorHandling(result); const res = await errorHandling(result);
return res; return res;
} }
export async function isInstallModeEnabled() {
const result = await fetch(`${getAPIUrl()}install/latest`, RequestBody("GET", null, null));
if (result.status === 200) {
return true;
}
else {
return false;
}
}

View file

@ -2,7 +2,8 @@ from fastapi import APIRouter, Depends
from src.routers import blocks, dev, trail, users, auth, orgs, roles from src.routers import blocks, dev, trail, users, auth, orgs, roles
from src.routers.courses import chapters, collections, courses, activities from src.routers.courses import chapters, collections, courses, activities
from src.routers.install import install from src.routers.install import install
from src.services.dev.dev import isDevModeEnabled from src.services.dev.dev import isDevModeEnabled, isDevModeEnabledOrRaise
from src.services.install.install import isInstallModeEnabled
v1_router = APIRouter(prefix="/api/v1") v1_router = APIRouter(prefix="/api/v1")
@ -17,13 +18,20 @@ v1_router.include_router(blocks.router, prefix="/blocks", tags=["blocks"])
v1_router.include_router(courses.router, prefix="/courses", tags=["courses"]) v1_router.include_router(courses.router, prefix="/courses", tags=["courses"])
v1_router.include_router(chapters.router, prefix="/chapters", tags=["chapters"]) v1_router.include_router(chapters.router, prefix="/chapters", tags=["chapters"])
v1_router.include_router(activities.router, prefix="/activities", tags=["activities"]) v1_router.include_router(activities.router, prefix="/activities", tags=["activities"])
v1_router.include_router( collections.router, prefix="/collections", tags=["collections"]) v1_router.include_router(
collections.router, prefix="/collections", tags=["collections"]
)
v1_router.include_router(trail.router, prefix="/trail", tags=["trail"]) v1_router.include_router(trail.router, prefix="/trail", tags=["trail"])
# Dev Routes # Dev Routes
v1_router.include_router( v1_router.include_router(
dev.router, prefix="/dev", tags=["dev"], dependencies=[Depends(isDevModeEnabled)] dev.router, prefix="/dev", tags=["dev"], dependencies=[Depends(isDevModeEnabledOrRaise)]
) )
# Install Routes # Install Routes
v1_router.include_router(install.router, prefix="/install", tags=["install"]) v1_router.include_router(
install.router,
prefix="/install",
tags=["install"],
dependencies=[Depends(isInstallModeEnabled)],
)

View file

@ -7,8 +7,12 @@ def isDevModeEnabled():
if config.general_config.development_mode: if config.general_config.development_mode:
return True return True
else: else:
raise HTTPException( return False
status_code=403,
detail="Development mode is not enabled", def isDevModeEnabledOrRaise():
) config = get_learnhouse_config()
if config.general_config.development_mode:
return True
else:
raise HTTPException(status_code=403, detail="Development mode is not enabled")

View file

@ -3,6 +3,7 @@ from uuid import uuid4
from fastapi import HTTPException, Request, status from fastapi import HTTPException, Request, status
from pydantic import BaseModel from pydantic import BaseModel
import requests import requests
from config.config import get_learnhouse_config
from src.security.security import security_hash_password from src.security.security import security_hash_password
from src.services.courses.activities.activities import Activity, create_activity from src.services.courses.activities.activities import Activity, create_activity
from src.services.courses.chapters import create_coursechapter, CourseChapter from src.services.courses.chapters import create_coursechapter, CourseChapter
@ -31,6 +32,18 @@ class InstallInstance(BaseModel):
data: dict data: dict
async def isInstallModeEnabled():
config = get_learnhouse_config()
if config.general_config.install_mode:
return True
else:
raise HTTPException(
status_code=403,
detail="Install mode is not enabled",
)
async def create_install_instance(request: Request, data: dict): async def create_install_instance(request: Request, data: dict):
installs = request.app.db["installs"] installs = request.app.db["installs"]
@ -432,8 +445,6 @@ async def create_sample_data(org_slug: str, username: str, request: Request):
courses = request.app.db["courses"] courses = request.app.db["courses"]
course = CourseInDB(**course.dict()) course = CourseInDB(**course.dict())
await courses.insert_one(course.dict()) await courses.insert_one(course.dict())