123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- /*
- * Copyright (C) 2024 Puter Technologies Inc.
- *
- * This file is part of Puter.
- *
- * Puter is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- const { APIError } = require("openai");
- const configurable_auth = require("../middleware/configurable_auth");
- const { Endpoint } = require("../util/expressutil");
- const { whatis } = require("../util/langutil");
- const BaseService = require("./BaseService");
- class PermissionAPIService extends BaseService {
- static MODULES = {
- express: require('express'),
- };
- async ['__on_install.routes'] (_, { app }) {
- app.use(require('../routers/auth/get-user-app-token'))
- app.use(require('../routers/auth/grant-user-app'))
- app.use(require('../routers/auth/revoke-user-app'))
- app.use(require('../routers/auth/grant-user-user'));
- app.use(require('../routers/auth/revoke-user-user'));
- app.use(require('../routers/auth/grant-user-group'));
- app.use(require('../routers/auth/revoke-user-group'));
- app.use(require('../routers/auth/list-permissions'))
-
- // track: scoping iife
- const r_group = (() => {
- const require = this.require;
- const express = require('express');
- return express.Router()
- })();
- this.install_group_endpoints_({ router: r_group });
- app.use('/group', r_group);
- }
-
- install_group_endpoints_ ({ router }) {
- Endpoint({
- route: '/create',
- methods: ['POST'],
- mw: [configurable_auth()],
- handler: async (req, res) => {
- const owner_user_id = req.user.id;
-
- const extra = req.body.extra ?? {};
- const metadata = req.body.metadata ?? {};
- if ( whatis(extra) !== 'object' ) {
- throw APIError.create('field_invalid', null, {
- key: 'extra',
- expected: 'object',
- got: whatis(extra),
- })
- }
- if ( whatis(metadata) !== 'object' ) {
- throw APIError.create('field_invalid', null, {
- key: 'metadata',
- expected: 'object',
- got: whatis(metadata),
- })
- }
- const svc_group = this.services.get('group');
- const uid = await svc_group.create({
- owner_user_id,
- // TODO: allow specifying these in request
- extra: {},
- metadata: {},
- });
-
- res.json({ uid });
- }
- }).attach(router);
-
- Endpoint({
- route: '/add-users',
- methods: ['POST'],
- mw: [configurable_auth()],
- handler: async (req, res) => {
- const svc_group = this.services.get('group')
-
- // TODO: validate string and uuid for request
- const group = await svc_group.get(
- { uid: req.body.uid });
-
- if ( ! group ) {
- throw APIError.create('entity_not_found', null, {
- identifier: req.body.uid,
- })
- }
-
- if ( group.owner_user_id !== req.user.id ) {
- throw APIError.create('forbidden');
- }
-
- if ( whatis(req.body.users) !== 'array' ) {
- throw APIError.create('field_invalid', null, {
- key: 'users',
- expected: 'array',
- got: whatis(req.body.users),
- });
- }
-
- for ( let i=0 ; i < req.body.users.length ; i++ ) {
- const value = req.body.users[i];
- if ( whatis(value) === 'string' ) continue;
- throw APIError.create('field_invalid', null, {
- key: `users[${i}]`,
- expected: 'string',
- got: whatis(value),
- });
- }
-
- await svc_group.add_users({
- uid: req.body.uid,
- users: req.body.users,
- });
-
- res.json({});
- }
- }).attach(router);
- // TODO: DRY: add-users is very similar
- Endpoint({
- route: '/remove-users',
- methods: ['POST'],
- mw: [configurable_auth()],
- handler: async (req, res) => {
- const svc_group = this.services.get('group')
-
- // TODO: validate string and uuid for request
- const group = await svc_group.get(
- { uid: req.body.uid });
-
- if ( ! group ) {
- throw APIError.create('entity_not_found', null, {
- identifier: req.body.uid,
- })
- }
- if ( group.owner_user_id !== req.user.id ) {
- throw APIError.create('forbidden');
- }
-
- if ( whatis(req.body.users) !== 'array' ) {
- throw APIError.create('field_invalid', null, {
- key: 'users',
- expected: 'array',
- got: whatis(req.body.users),
- });
- }
-
- for ( let i=0 ; i < req.body.users.length ; i++ ) {
- const value = req.body.users[i];
- if ( whatis(value) === 'string' ) continue;
- throw APIError.create('field_invalid', null, {
- key: `users[${i}]`,
- expected: 'string',
- got: whatis(value),
- });
- }
-
- await svc_group.remove_users({
- uid: req.body.uid,
- users: req.body.users,
- });
-
- res.json({});
- }
- }).attach(router);
- Endpoint({
- route: '/list',
- methods: ['GET'],
- mw: [configurable_auth()],
- handler: async (req, res) => {
- const svc_group = this.services.get('group');
-
- // TODO: validate string and uuid for request
- const owned_groups = await svc_group.list_groups_with_owner(
- { owner_user_id: req.user.id });
- const in_groups = await svc_group.list_groups_with_member(
- { user_id: req.user.id });
- res.json({
- owned_groups: await Promise.all(owned_groups.map(
- g => g.get_client_value())),
- in_groups: await Promise.all(in_groups.map(
- g => g.get_client_value())),
- });
- }
- }).attach(router);
- }
- }
- module.exports = {
- PermissionAPIService,
- };
|