This commit is contained in:
Maks 2019-03-16 18:03:13 +00:00 committed by GitHub
commit b505ecefac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 161 additions and 11 deletions

View File

@ -318,6 +318,9 @@ export default class {
if (!reload && this.getContentById(content.id))
throw { message: `A ${this.contentType} with the ID ${content.id} already exists.` };
if (!reload && readConfig.permissions && readConfig.permissions.length && content.type === 'plugin')
content.savePermissions();
if (reload) this.localContent.splice(index, 1, content);
else this.localContent.push(content);
return content;
@ -336,7 +339,7 @@ export default class {
if (!content) throw {message: `Could not find a ${this.contentType} from ${content}.`};
try {
await Modals.confirm(`Delete ${this.contentType}?`, `Are you sure you want to delete ${content.info.name} ?`, 'Delete').promise;
await Modals.confirm(`Delete ${this.contentType} ?`, `Are you sure you want to delete ${content.info.name} ?`, 'Delete').promise;
} catch (err) {
return false;
}

View File

@ -32,6 +32,10 @@ const PermissionMap = {
JOIN_SERVERS: {
HEADER: 'Join servers for you',
BODY: 'Allows :NAME: to join servers on your behalf.'
},
GET_INSTALLED_COMPONENT: {
HEADER: 'Use installed components',
BODY: 'Allows :NAME: to control other plugins / themes / modules'
}
}
@ -41,4 +45,96 @@ export default class {
return PermissionMap[permission];
}
/**
* Add the passed permission to the plugin with the passed ID
* @param {String} id Plugin's ID
* @param {String} permission Permission to add
* @return {Promise}
*/
static add(id, permission) {
if (!PermissionMap[permission])
return;
if (this.get(id, permission))
return;
if (!this.data)
this.data = [];
if (!this.data[id])
this.data[id] = [];
this.data[id].push(permission);
}
/**
* Add all specified permissions to the plugin with the passed ID
* @param {String} id Plugin's ID
* @param {Array} permissions Array of permission to add
* @return {Promise}
*/
static addMultiple(id, permissions) {
for (const permission of permissions)
this.add(id, permission);
}
/**
* Remove the passed permission from the plugin with the passed ID
* @param {String} id Plugin's ID
* @param {String} permission Permission to remove
* @return {Promise}
*/
static remove(id, permission) {
if (!this.data || !this.data[id])
return;
for (const index in this.data[id]) {
if (this.data[id][index] === permission) {
this.data[id].splice(index, 1);
break;
}
}
}
/**
* Remove all permissions from the plugin with the passed ID
* @param {String} id Plugin's ID
* @return {Promise}
*/
static removeAll(id) {
if (!this.data || !this.data[id])
return;
delete this.data[id];
}
/**
* Checks if the plugin with the passed ID has the passed permission
* @param {String} id Plugin's ID
* @param {String} permission Permission to check
* @return {Boolean}
*/
static get(id, permission) {
if (!this.data || !this.data[id])
return false;
for (const index in this.data[id])
if (this.data[id][index] === permission)
return true;
return false;
}
/**
* Returns an array of permissions of the plugin with the passed ID
* @param {String} id Plugin's ID
* @return {Array}
*/
static getAll(id) {
if (!this.data || !this.data[id])
return [];
return this.data[id];
}
}

View File

@ -10,6 +10,9 @@
import PluginManager from './pluginmanager';
import Content from './content';
import Database from './database';
import { ClientLogger as Logger } from 'common';
import { Permissions } from 'modules';
export default class Plugin extends Content {
@ -26,4 +29,23 @@ export default class Plugin extends Content {
return PluginManager.unloadPlugin(this, force);
}
/**
* Saves the plugin's permissions
*/
savePermissions() {
try {
const permissions = Permissions.getAll(this.id);
if (!permissions.length)
return;
Database.insertOrUpdate({ type: `plugin-permissions`, id: this.id }, {
type: `plugin-permissions`,
id: this.id,
permissions: permissions
});
} catch (err) {
Logger.err(this.name, ['Failed to save permissions', err]);
}
}
}

View File

@ -24,6 +24,7 @@ import Reflection from './reflection/index';
import DiscordApi from './discordapi';
import { ReactComponents, ReactHelpers } from './reactcomponents';
import { Patcher, MonkeyPatch } from './patcher';
import { Permissions } from 'modules';
import GlobalAc from '../ui/autocomplete';
import Vue from 'vue';
import path from 'path';
@ -255,12 +256,13 @@ export default class PluginApi {
}
deleteStyle(id) {
const styleid = `plugin-${this.plugin.id}-${id}`;
this.injectedStyles.splice(this.injectedStyles.indexOf(styleid), 1);
const index = this.injectedStyles.indexOf(id);
if (index !== -1) this.injectedStyles.splice(index, 1);
DOM.deleteStyle(styleid);
}
deleteAllStyles(id) {
for (const id of this.injectedStyles) {
this.deleteStyle(id);
for (let i = this.injectedStyles.length - 1; i >= 0; i--) {
this.deleteStyle(this.injectedStyles[i]);
}
}
get CssUtils() {
@ -500,7 +502,9 @@ export default class PluginApi {
*/
async getPlugin(plugin_id) {
// This should require extra permissions
if (!Permissions.get(this.pluginInfo.id, 'GET_INSTALLED_COMPONENT'))
throw {message: 'Missing GET_INSTALLED_COMPONENT permission'};
return PluginManager.waitForPlugin(plugin_id);
}
listPlugins() {
@ -518,7 +522,9 @@ export default class PluginApi {
*/
async getTheme(theme_id) {
// This should require extra permissions
if (!Permissions.get(this.pluginInfo.id, 'GET_INSTALLED_COMPONENT'))
throw {message: 'Missing GET_INSTALLED_COMPONENT permission'};
return ThemeManager.waitForContent(theme_id);
}
listThemes() {
@ -536,7 +542,9 @@ export default class PluginApi {
*/
async getModule(module_id) {
// This should require extra permissions
if (!Permissions.get(this.pluginInfo.id, 'GET_INSTALLED_COMPONENT'))
throw {message: 'Missing GET_INSTALLED_COMPONENT permission'};
return ExtModuleManager.waitForContent(module_id);
}
listModules() {

View File

@ -18,6 +18,7 @@ import ExtModuleManager from './extmodulemanager';
import Plugin from './plugin';
import PluginApi from './pluginapi';
import Vendor from './vendor';
import Database from './database';
export default class extends ContentManager {
@ -75,12 +76,26 @@ export default class extends ContentManager {
static get loadContent() { return this.loadPlugin }
static async loadPlugin(paths, configs, info, main, dependencies, permissions, mainExport, packed = false) {
if (permissions && permissions.length > 0) {
for (const perm of permissions) {
Logger.log(this.moduleName, `Permission: ${Permissions.permissionText(perm).HEADER} - ${Permissions.permissionText(perm).BODY}`);
try {
const readPermissions = await Database.find({ type: `plugin-permissions`, id: info.id });
if (permissions && permissions.length && readPermissions.length) {
for (const dbPermsIndex in readPermissions[0].permissions) {
for (let i = permissions.length - 1; i >= 0; --i) {
if (readPermissions[0].permissions[dbPermsIndex] === permissions[i]) {
Permissions.add(info.id, permissions[i]);
permissions.splice(i, 1);
break;
}
}
}
}
} catch (err) {
Logger.warn(this.moduleName, [`Failed reading permissions for ${this.contentType} ${info.name} in ${paths.dirName}`, err]);
}
if (permissions && permissions.length) {
try {
const allowed = await Modals.permissions(`${info.name} wants to:`, info.name, permissions).promise;
await Modals.permissions(`${info.name} wants to:`, info.name, permissions).promise;
} catch (err) {
return;
}
@ -116,6 +131,12 @@ export default class extends ContentManager {
instance.userConfig.enabled = false;
instance.start(false);
}
if (permissions && permissions.length)
Permissions.addMultiple(info.id, permissions);
instance.once('unload', () => Permissions.removeAll(instance.id));
return instance;
}