diff --git a/.env.example b/.env.example index 7d06630fc..736efcf50 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,6 @@ DOCKER_HOST_ADDRESS= GRPC_ALLOW_INSECURE=true REDIS_HOST=redis -REDIS_SECRET=changeme LOGS_LEVEL=info LOGS_DRIVER_HOST=fluent LOGS_AGGREGRATOR_HOST=elasticsearch diff --git a/compose.yaml b/compose.yaml index 0a09b1996..f9e789634 100644 --- a/compose.yaml +++ b/compose.yaml @@ -4,15 +4,30 @@ services: webui: image: fonoster/webui:latest - ports: - - 8181:3000 + restart: unless-stopped environment: - LOGS_LEVEL: ${LOGS_LEVEL} WEBUI_APISERVER_ENDPOINT: ${WEBUI_APISERVER_ENDPOINT} + # TODO: Remove this deprecated variable + APISERVER_ENDPOINT: ${WEBUI_APISERVER_ENDPOINT} WEBUI_GITHUB_CLIENT_ID: ${WEBUI_GITHUB_CLIENT_ID} WEBUI_GITHUB_CLIENT_SECRET: ${WEBUI_GITHUB_CLIENT_SECRET} + WEBUI_TEST_PHONE_DOMAIN: ${WEBUI_TEST_PHONE_DOMAIN} + WEBUI_TEST_PHONE_SERVER: ${WEBUI_TEST_PHONE_SERVER} + WEBUI_TEST_PHONE_USERNAME: ${WEBUI_TEST_PHONE_USERNAME} + WEBUI_TEST_PHONE_SECRET: ${WEBUI_TEST_PHONE_SECRET} + WEBUI_TEST_PHONE_DISPLAY_NAME: ${WEBUI_TEST_PHONE_DISPLAY_NAME} + WEBUI_BILLING_URL: ${WEBUI_BILLING_URL} + WEBUI_FEEDBACK_URL: ${WEBUI_FEEDBACK_URL} + WEBUI_APP_URL: ${WEBUI_APP_URL} + NEXTAUTH_URL: ${NEXTAUTH_URL} + LOGS_LEVEL: ${LOGS_LEVEL} + LOGS_TRANSPORT: ${LOGS_TRANSPORT} + GRPC_ALLOW_INSECURE: true + ports: + - 8181:8181 volumes: - - ./etc/config:/home/fonoster/.fonoster/config:ro + - ./etc/config:/home/nextjs/.fonoster/config:ro + - ./etc/rbac.json:/home/fonoster/rbac.json:ro logging: options: tag: fonoster-logs @@ -41,14 +56,19 @@ services: APISERVER_JWT_AUTH_ISS: ${APISERVER_JWT_AUTH_ISS} APISERVER_JWT_PRIVATE_KEY: ${APISERVER_JWT_PRIVATE_KEY} APISERVER_AUTOPILOT_URL: ${APISERVER_AUTOPILOT_URL} + REDIS_HOST: ${REDIS_HOST} LOGS_LEVEL: ${LOGS_LEVEL} + LOGS_TRANSPORT: ${LOGS_TRANSPORT} + LOGS_DRIVER_HOST: ${LOGS_DRIVER_HOST} LOGS_AGGREGRATOR_HOST: ${LOGS_AGGREGRATOR_HOST} LOGS_AGGREGRATOR_PORT: 24224 + GRPC_ALLOW_INSECURE: true ports: - 50052:50052 - 4000:4000 volumes: - ./etc/config:/home/fonoster/.fonoster/config:ro + - ${APISERVER_RBAC_CONFIG}:/home/fonoster/rbac.json:ro logging: options: tag: fonoster-logs @@ -83,6 +103,8 @@ services: logging: options: tag: fonoster-logs + volumes: + - ./etc/log4j2.yml:/opt/routr/config/log4j2.yml:ro # RTPEngine uses a range of ports to handle RTP traffic. Because exposing a large range of ports # is not possible in Docker, we need to use network_mode: host. diff --git a/etc/rbac.json b/etc/rbac.json new file mode 100644 index 000000000..4604ded99 --- /dev/null +++ b/etc/rbac.json @@ -0,0 +1,98 @@ +[ + { + "name": "USER", + "description": "Access to User and Project endpoints", + "access": [ + "/fonoster.users.v1beta1.Users/ListUsers", + "/fonoster.users.v1beta1.Users/GetUser", + "/fonoster.users.v1beta1.Users/UpdateUser", + "/fonoster.users.v1beta1.Users/Login", + "/fonoster.projects.v1beta1.Projects/ListProjects", + "/fonoster.projects.v1beta1.Projects/CreateProject", + "/fonoster.projects.v1beta1.Projects/UpdateProject", + "/fonoster.projects.v1beta1.Projects/GetProject", + "/fonoster.projects.v1beta1.Projects/DeleteProject", + "/fonoster.projects.v1beta1.Projects/RenewAccessKeySecret", + "/fonoster.limiter.v1beta1.Limiter/CheckAuthorized" + ] + }, + { + "name": "PROJECT", + "description": "Access to Project resources", + "access": [ + "/fonoster.apps.v1beta1.Apps/ListApps", + "/fonoster.apps.v1beta1.Apps/CreateApp", + "/fonoster.apps.v1beta1.Apps/GetApp", + "/fonoster.apps.v1beta1.Apps/UpdateApp", + "/fonoster.apps.v1beta1.Apps/DeleteApp", + "/fonoster.monitor.v1beta1.Monitor/SearchEvents", + "/fonoster.storage.v1beta1.Storage/UploadObject", + "/fonoster.storage.v1beta1.Storage/GetObjectURL", + "/fonoster.providers.v1beta1.Providers/ListProviders", + "/fonoster.providers.v1beta1.Providers/CreateProvider", + "/fonoster.providers.v1beta1.Providers/GetProvider", + "/fonoster.providers.v1beta1.Providers/UpdateProvider", + "/fonoster.providers.v1beta1.Providers/DeleteProvider", + "/fonoster.numbers.v1beta1.Numbers/ListNumbers", + "/fonoster.numbers.v1beta1.Numbers/CreateNumber", + "/fonoster.numbers.v1beta1.Numbers/GetIngressInfo", + "/fonoster.numbers.v1beta1.Numbers/GetNumber", + "/fonoster.numbers.v1beta1.Numbers/UpdateNumber", + "/fonoster.numbers.v1beta1.Numbers/DeleteNumber", + "/fonoster.domains.v1beta1.Domains/ListDomains", + "/fonoster.domains.v1beta1.Domains/CreateDomain", + "/fonoster.domains.v1beta1.Domains/GetDomain", + "/fonoster.domains.v1beta1.Domains/UpdateDomain", + "/fonoster.domains.v1beta1.Domains/DeleteDomain", + "/fonoster.callmanager.v1beta1.CallManager/Call", + "/fonoster.agents.v1beta1.Agents/ListAgents", + "/fonoster.agents.v1beta1.Agents/CreateAgent", + "/fonoster.agents.v1beta1.Agents/GetAgent", + "/fonoster.agents.v1beta1.Agents/UpdateAgent", + "/fonoster.agents.v1beta1.Agents/DeleteAgent", + "/fonoster.secrets.v1beta1.Secrets/CreateSecret", + "/fonoster.secrets.v1beta1.Secrets/ListSecretsId", + "/fonoster.secrets.v1beta1.Secrets/DeleteSecret", + "/fonoster.secrets.v1beta1.Secrets/GetSecret", + "/fonoster.limiter.v1beta1.Limiter/CheckAuthorized" + ] + }, + { + "name": "FUNCTION", + "description": "This role is limited only to calling", + "access": [ + "/fonoster.callmanager.v1beta1.CallManager/Call", + "/fonoster.secrets.v1beta1.Secrets/GetSecret", + "/fonoster.auth.v1beta1.Auth/ValidateToken" + ] + }, + { + "name": "SERVICE", + "description": "This role is able to obtain ingress information and create short-live token", + "access": [ + "/fonoster.numbers.v1beta1.Numbers/GetIngressInfo", + "/fonoster.auth.v1beta1.Auth/CreateToken", + "/fonoster.auth.v1beta1.Auth/CreateNoAccessToken", + "/fonoster.auth.v1beta1.Auth/ValidateToken", + "/fonoster.users.v1beta1.Users/CreateUser", + "/fonoster.users.v1beta1.Users/ListUsers", + "/fonoster.users.v1beta1.Users/UpdateUser" + ] + }, + { + "name": "NO_ACCESSS", + "description": "Signature token without any access", + "access": [] + }, + { + "name": "ADMIN", + "description": "Can perform administrative task", + "access": [ + "/fonoster.auth.v1beta1.Auth/CreateToken", + "/fonoster.users.v1beta1.Users/CreateUser", + "/fonoster.users.v1beta1.Users/DeleteUser", + "/fonoster.users.v1beta1.Users/ListUsers", + "/fonoster.users.v1beta1.Users/UpdateUser" + ] + } +] diff --git a/mods/webui/next.config.js b/mods/webui/next.config.js index cfb0cc674..93135ac20 100644 --- a/mods/webui/next.config.js +++ b/mods/webui/next.config.js @@ -10,6 +10,7 @@ module.exports = { reactStrictMode: true, publicRuntimeConfig: { WEBUI_APP_URL: process.env.WEBUI_APP_URL, + WEBUI_APISERVER_ENDPOINT: process.env.WEBUI_APISERVER_ENDPOINT, WEBUI_GITHUB_CLIENT_ID: process.env.WEBUI_GITHUB_CLIENT_ID, WEBUI_GITHUB_CLIENT_SECRET: process.env.WEBUI_GITHUB_CLIENT_SECRET, WEBUI_BILLING_URL: process.env.WEBUI_BILLING_URL, diff --git a/mods/webui/src/pages/api/auth/[...nextauth].ts b/mods/webui/src/pages/api/auth/[...nextauth].ts index bb76055e8..8d35b21a6 100644 --- a/mods/webui/src/pages/api/auth/[...nextauth].ts +++ b/mods/webui/src/pages/api/auth/[...nextauth].ts @@ -82,6 +82,7 @@ export default NextAuth({ async session({ session, token }) { logger.verbose(`webui session [session -> ${JSON.stringify(session)}]`) logger.verbose(`webui session [token -> ${JSON.stringify(token)}]`) + logger.verbose(`webui session.endpoint [${config.WEBUI_APISERVER_ENDPOINT}]`) session.endpoint = config.WEBUI_APISERVER_ENDPOINT