Merge pull request #609 from yuya-oc/permission-request-handler
Dialog to confirm requested permissions
This commit is contained in:
@@ -25,7 +25,9 @@ const MainPage = createReactClass({
|
||||
useSpellChecker: PropTypes.bool.isRequired,
|
||||
onSelectSpellCheckerLocale: PropTypes.func.isRequired,
|
||||
deeplinkingUrl: PropTypes.string,
|
||||
showAddServerButton: PropTypes.bool.isRequired
|
||||
showAddServerButton: PropTypes.bool.isRequired,
|
||||
requestingPermission: TabBar.propTypes.requestingPermission,
|
||||
onClickPermissionDialog: PropTypes.func
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
@@ -260,6 +262,8 @@ const MainPage = createReactClass({
|
||||
onSelect={this.handleSelect}
|
||||
onAddServer={this.addServer}
|
||||
showAddServerButton={this.props.showAddServerButton}
|
||||
requestingPermission={this.props.requestingPermission}
|
||||
onClickPermissionDialog={this.props.onClickPermissionDialog}
|
||||
/>
|
||||
</Row>
|
||||
);
|
||||
|
89
src/browser/components/PermissionRequestDialog.jsx
Normal file
89
src/browser/components/PermissionRequestDialog.jsx
Normal file
@@ -0,0 +1,89 @@
|
||||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const {Button, Glyphicon, Popover} = require('react-bootstrap');
|
||||
|
||||
const PERMISSIONS = {
|
||||
media: {
|
||||
description: 'Use your camera and microphone',
|
||||
glyph: 'facetime-video'
|
||||
},
|
||||
geolocation: {
|
||||
description: 'Know your location',
|
||||
glyph: 'map-marker'
|
||||
},
|
||||
notifications: {
|
||||
description: 'Show notifications',
|
||||
glyph: 'bell'
|
||||
},
|
||||
midiSysex: {
|
||||
description: 'Use your MIDI devices',
|
||||
glyph: 'music'
|
||||
},
|
||||
pointerLock: {
|
||||
description: 'Lock your mouse cursor',
|
||||
glyph: 'hand-up'
|
||||
},
|
||||
fullscreen: {
|
||||
description: 'Enter full screen',
|
||||
glyph: 'resize-full'
|
||||
},
|
||||
openExternal: {
|
||||
description: 'Open external',
|
||||
glyph: 'new-window'
|
||||
}
|
||||
};
|
||||
|
||||
function glyph(permission) {
|
||||
const data = PERMISSIONS[permission];
|
||||
if (data) {
|
||||
return data.glyph;
|
||||
}
|
||||
return 'alert';
|
||||
}
|
||||
|
||||
function description(permission) {
|
||||
const data = PERMISSIONS[permission];
|
||||
if (data) {
|
||||
return data.description;
|
||||
}
|
||||
return `Be granted "${permission}" permission`;
|
||||
}
|
||||
|
||||
function PermissionRequestDialog(props) {
|
||||
const {origin, permission, onClickAllow, onClickBlock, onClickClose, ...reft} = props;
|
||||
return (
|
||||
<Popover
|
||||
className='PermissionRequestDialog'
|
||||
{...reft}
|
||||
>
|
||||
<div
|
||||
className='PermissionRequestDialog-content'
|
||||
>
|
||||
<p>{`${origin} wants to:`}</p>
|
||||
<p className='PermissionRequestDialog-content-description'>
|
||||
<Glyphicon glyph={glyph(permission)}/>
|
||||
{description(permission)}
|
||||
</p>
|
||||
<p className='PermissionRequestDialog-content-buttons'>
|
||||
<Button onClick={onClickAllow}>{'Allow'}</Button>
|
||||
<Button onClick={onClickBlock}>{'Block'}</Button>
|
||||
</p>
|
||||
<Button
|
||||
className='PermissionRequestDialog-content-close'
|
||||
bsStyle='link'
|
||||
onClick={onClickClose}
|
||||
>{'×'}</Button>
|
||||
</div>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
PermissionRequestDialog.propTypes = {
|
||||
origin: PropTypes.string.isRequired,
|
||||
permission: PropTypes.oneOf(['media', 'geolocation', 'notifications', 'midiSysex', 'pointerLock', 'fullscreen', 'openExternal']).isRequired,
|
||||
onClickAllow: PropTypes.func,
|
||||
onClickBlock: PropTypes.func,
|
||||
onClickClose: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = PermissionRequestDialog;
|
@@ -1,34 +1,68 @@
|
||||
const React = require('react');
|
||||
const {findDOMNode} = require('react-dom');
|
||||
const PropTypes = require('prop-types');
|
||||
const {Glyphicon, Nav, NavItem} = require('react-bootstrap');
|
||||
const {Glyphicon, Nav, NavItem, Overlay} = require('react-bootstrap');
|
||||
const PermissionRequestDialog = require('./PermissionRequestDialog.jsx');
|
||||
|
||||
function TabBar(props) {
|
||||
const tabs = props.teams.map((team, index) => {
|
||||
let unreadCount = 0;
|
||||
if (props.unreadCounts[index] > 0) {
|
||||
unreadCount = props.unreadCounts[index];
|
||||
}
|
||||
if (props.unreadAtActive[index]) {
|
||||
unreadCount += 1;
|
||||
}
|
||||
class TabBar extends React.Component { // need "this"
|
||||
render() {
|
||||
const tabs = this.props.teams.map((team, index) => {
|
||||
let unreadCount = 0;
|
||||
if (this.props.unreadCounts[index] > 0) {
|
||||
unreadCount = this.props.unreadCounts[index];
|
||||
}
|
||||
if (this.props.unreadAtActive[index]) {
|
||||
unreadCount += 1;
|
||||
}
|
||||
|
||||
let mentionCount = 0;
|
||||
if (props.mentionCounts[index] > 0) {
|
||||
mentionCount = props.mentionCounts[index];
|
||||
}
|
||||
if (props.mentionAtActiveCounts[index] > 0) {
|
||||
mentionCount += props.mentionAtActiveCounts[index];
|
||||
}
|
||||
let mentionCount = 0;
|
||||
if (this.props.mentionCounts[index] > 0) {
|
||||
mentionCount = this.props.mentionCounts[index];
|
||||
}
|
||||
if (this.props.mentionAtActiveCounts[index] > 0) {
|
||||
mentionCount += this.props.mentionAtActiveCounts[index];
|
||||
}
|
||||
|
||||
let badgeDiv;
|
||||
if (mentionCount !== 0) {
|
||||
badgeDiv = (
|
||||
<div className='TabBar-badge'>
|
||||
{mentionCount}
|
||||
</div>);
|
||||
}
|
||||
const id = 'teamTabItem' + index;
|
||||
if (unreadCount === 0) {
|
||||
let badgeDiv;
|
||||
if (mentionCount !== 0) {
|
||||
badgeDiv = (
|
||||
<div className='TabBar-badge'>
|
||||
{mentionCount}
|
||||
</div>);
|
||||
}
|
||||
const id = 'teamTabItem' + index;
|
||||
const permissionOverlay = this.props.requestingPermission[index] ? (
|
||||
<Overlay
|
||||
className='TabBar-permissionOverlay'
|
||||
placement='bottom'
|
||||
show={this.props.activeKey === index}
|
||||
target={() => findDOMNode(this.refs[id])}
|
||||
>
|
||||
<PermissionRequestDialog
|
||||
id={`${id}-permissionDialog`}
|
||||
origin={this.props.requestingPermission[index].origin}
|
||||
permission={this.props.requestingPermission[index].permission}
|
||||
onClickAllow={this.props.onClickPermissionDialog.bind(null, index, 'allow')}
|
||||
onClickBlock={this.props.onClickPermissionDialog.bind(null, index, 'block')}
|
||||
onClickClose={this.props.onClickPermissionDialog.bind(null, index, 'close')}
|
||||
/>
|
||||
</Overlay>
|
||||
) : null;
|
||||
if (unreadCount === 0) {
|
||||
return (
|
||||
<NavItem
|
||||
className='teamTabItem'
|
||||
key={id}
|
||||
id={id}
|
||||
eventKey={index}
|
||||
ref={id}
|
||||
>
|
||||
{ team.name }
|
||||
{ ' ' }
|
||||
{ badgeDiv }
|
||||
{permissionOverlay}
|
||||
</NavItem>);
|
||||
}
|
||||
return (
|
||||
<NavItem
|
||||
className='teamTabItem'
|
||||
@@ -36,53 +70,42 @@ function TabBar(props) {
|
||||
id={id}
|
||||
eventKey={index}
|
||||
>
|
||||
{ team.name }
|
||||
<b>{ team.name }</b>
|
||||
{ ' ' }
|
||||
{ badgeDiv }
|
||||
</NavItem>);
|
||||
});
|
||||
if (this.props.showAddServerButton === true) {
|
||||
tabs.push(
|
||||
<NavItem
|
||||
className='TabBar-addServerButton'
|
||||
key='addServerButton'
|
||||
id='addServerButton'
|
||||
eventKey='addServerButton'
|
||||
title='Add new server'
|
||||
>
|
||||
<Glyphicon glyph='plus'/>
|
||||
</NavItem>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<NavItem
|
||||
className='teamTabItem'
|
||||
key={id}
|
||||
id={id}
|
||||
eventKey={index}
|
||||
<Nav
|
||||
className='TabBar'
|
||||
id={this.props.id}
|
||||
bsStyle='tabs'
|
||||
activeKey={this.props.activeKey}
|
||||
onSelect={(eventKey) => {
|
||||
if (eventKey === 'addServerButton') {
|
||||
this.props.onAddServer();
|
||||
} else {
|
||||
this.props.onSelect(eventKey);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<b>{ team.name }</b>
|
||||
{ ' ' }
|
||||
{ badgeDiv }
|
||||
</NavItem>);
|
||||
});
|
||||
if (props.showAddServerButton === true) {
|
||||
tabs.push(
|
||||
<NavItem
|
||||
className='TabBar-addServerButton'
|
||||
key='addServerButton'
|
||||
id='addServerButton'
|
||||
eventKey='addServerButton'
|
||||
title='Add new server'
|
||||
>
|
||||
<Glyphicon glyph='plus'/>
|
||||
</NavItem>
|
||||
{ tabs }
|
||||
</Nav>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Nav
|
||||
className='TabBar'
|
||||
id={props.id}
|
||||
bsStyle='tabs'
|
||||
activeKey={props.activeKey}
|
||||
onSelect={(eventKey) => {
|
||||
if (eventKey === 'addServerButton') {
|
||||
props.onAddServer();
|
||||
} else {
|
||||
props.onSelect(eventKey);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{ tabs }
|
||||
</Nav>
|
||||
);
|
||||
}
|
||||
|
||||
TabBar.propTypes = {
|
||||
@@ -94,8 +117,13 @@ TabBar.propTypes = {
|
||||
unreadAtActive: PropTypes.array,
|
||||
mentionCounts: PropTypes.array,
|
||||
mentionAtActiveCounts: PropTypes.array,
|
||||
showAddServerButton: PropTypes.bool,
|
||||
requestingPermission: PropTypes.arrayOf(PropTypes.shape({
|
||||
origin: PropTypes.string,
|
||||
permission: PropTypes.string
|
||||
})),
|
||||
onAddServer: PropTypes.func,
|
||||
showAddServerButton: PropTypes.bool
|
||||
onClickPermissionDialog: PropTypes.func
|
||||
};
|
||||
|
||||
module.exports = TabBar;
|
||||
|
44
src/browser/css/components/PermissionRequestDialog.css
Normal file
44
src/browser/css/components/PermissionRequestDialog.css
Normal file
@@ -0,0 +1,44 @@
|
||||
.PermissionRequestDialog-content{
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .popover-content {
|
||||
padding: 14px;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content > *:nth-child(1) {
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .PermissionRequestDialog-content-description {
|
||||
text-indent: 0.25em;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .PermissionRequestDialog-content-description .glyphicon {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .PermissionRequestDialog-content-buttons {
|
||||
margin-bottom: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .PermissionRequestDialog-content-buttons > * {
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .PermissionRequestDialog-content-buttons > *:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .PermissionRequestDialog-content-close {
|
||||
position:absolute;
|
||||
top: 0px;
|
||||
right:0px;
|
||||
color: gray;
|
||||
text-decoration-line: none;
|
||||
}
|
||||
|
||||
.PermissionRequestDialog-content .PermissionRequestDialog-content-close:hover {
|
||||
color: black;
|
||||
}
|
@@ -36,4 +36,8 @@
|
||||
margin-left: 5px;
|
||||
margin-top: 5px;
|
||||
border-radius: 50%;
|
||||
};
|
||||
}
|
||||
|
||||
div[id*="-permissionDialog"] {
|
||||
max-width: 350px;
|
||||
}
|
||||
|
@@ -3,5 +3,6 @@
|
||||
@import url("MainPage.css");
|
||||
@import url("MattermostView.css");
|
||||
@import url("NewTeamModal.css");
|
||||
@import url("PermissionRequestDialog.css");
|
||||
@import url("TabBar.css");
|
||||
@import url("TeamListItem.css");
|
||||
|
@@ -15,6 +15,7 @@ const AppConfig = require('./config/AppConfig.js');
|
||||
const url = require('url');
|
||||
|
||||
const badge = require('./js/badge');
|
||||
const utils = require('../utils/util');
|
||||
|
||||
remote.getCurrentWindow().removeAllListeners('focus');
|
||||
|
||||
@@ -86,12 +87,59 @@ function showUnreadBadge(unreadCount, mentionCount) {
|
||||
}
|
||||
}
|
||||
|
||||
const permissionRequestQueue = [];
|
||||
const requestingPermission = new Array(AppConfig.data.teams.length);
|
||||
|
||||
function teamConfigChange(teams) {
|
||||
AppConfig.set('teams', teams);
|
||||
requestingPermission.length = teams.length;
|
||||
ipcRenderer.send('update-menu', AppConfig.data);
|
||||
ipcRenderer.send('update-config');
|
||||
}
|
||||
|
||||
function feedPermissionRequest() {
|
||||
const webviews = document.getElementsByTagName('webview');
|
||||
const webviewOrigins = Array.from(webviews).map((w) => utils.getDomain(w.getAttribute('src')));
|
||||
for (let index = 0; index < requestingPermission.length; index++) {
|
||||
if (requestingPermission[index]) {
|
||||
break;
|
||||
}
|
||||
for (const request of permissionRequestQueue) {
|
||||
if (request.origin === webviewOrigins[index]) {
|
||||
requestingPermission[index] = request;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleClickPermissionDialog(index, status) {
|
||||
const requesting = requestingPermission[index];
|
||||
ipcRenderer.send('update-permission', requesting.origin, requesting.permission, status);
|
||||
if (status === 'allow' || status === 'block') {
|
||||
const newRequests = permissionRequestQueue.filter((request) => {
|
||||
if (request.permission === requesting.permission && request.origin === requesting.origin) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
permissionRequestQueue.splice(0, permissionRequestQueue.length, ...newRequests);
|
||||
} else if (status === 'close') {
|
||||
const i = permissionRequestQueue.findIndex((e) => e.permission === requesting.permission && e.origin === requesting.origin);
|
||||
permissionRequestQueue.splice(i, 1);
|
||||
}
|
||||
requestingPermission[index] = null;
|
||||
feedPermissionRequest();
|
||||
}
|
||||
|
||||
ipcRenderer.on('request-permission', (event, origin, permission) => {
|
||||
if (permissionRequestQueue.length >= 100) {
|
||||
return;
|
||||
}
|
||||
permissionRequestQueue.push({origin, permission});
|
||||
feedPermissionRequest();
|
||||
});
|
||||
|
||||
function handleSelectSpellCheckerLocale(locale) {
|
||||
console.log(locale);
|
||||
AppConfig.set('spellCheckerLocale', locale);
|
||||
@@ -117,6 +165,8 @@ ReactDOM.render(
|
||||
onSelectSpellCheckerLocale={handleSelectSpellCheckerLocale}
|
||||
deeplinkingUrl={deeplinkingUrl}
|
||||
showAddServerButton={AppConfig.data.enableServerManagement}
|
||||
requestingPermission={requestingPermission}
|
||||
onClickPermissionDialog={handleClickPermissionDialog}
|
||||
/>,
|
||||
document.getElementById('content')
|
||||
);
|
||||
|
@@ -37,6 +37,7 @@ const appMenu = require('./main/menus/app');
|
||||
const trayMenu = require('./main/menus/tray');
|
||||
const downloadURL = require('./main/downloadURL');
|
||||
const allowProtocolDialog = require('./main/allowProtocolDialog');
|
||||
const permissionRequestHandler = require('./main/permissionRequestHandler');
|
||||
|
||||
const SpellChecker = require('./main/SpellChecker');
|
||||
|
||||
@@ -577,6 +578,9 @@ app.on('ready', () => {
|
||||
});
|
||||
ipcMain.emit('update-dict');
|
||||
|
||||
const permissionFile = path.join(app.getPath('userData'), 'permission.json');
|
||||
session.defaultSession.setPermissionRequestHandler(permissionRequestHandler(mainWindow, permissionFile));
|
||||
|
||||
// Open the DevTools.
|
||||
// mainWindow.openDevTools();
|
||||
});
|
||||
|
114
src/main/permissionRequestHandler.js
Normal file
114
src/main/permissionRequestHandler.js
Normal file
@@ -0,0 +1,114 @@
|
||||
const {ipcMain} = require('electron');
|
||||
const {URL} = require('url');
|
||||
const fs = require('fs');
|
||||
|
||||
const PERMISSION_GRANTED = 'granted';
|
||||
const PERMISSION_DENIED = 'denied';
|
||||
|
||||
class PermissionManager {
|
||||
constructor(file) {
|
||||
this.file = file;
|
||||
if (fs.existsSync(file)) {
|
||||
this.permissions = JSON.parse(fs.readFileSync(this.file, 'utf-8'));
|
||||
} else {
|
||||
this.permissions = {};
|
||||
}
|
||||
}
|
||||
|
||||
writeFileSync() {
|
||||
fs.writeFileSync(this.file, JSON.stringify(this.permissions, null, ' '));
|
||||
}
|
||||
|
||||
grant(origin, permission) {
|
||||
if (!this.permissions[origin]) {
|
||||
this.permissions[origin] = {};
|
||||
}
|
||||
this.permissions[origin][permission] = PERMISSION_GRANTED;
|
||||
this.writeFileSync();
|
||||
}
|
||||
|
||||
deny(origin, permission) {
|
||||
if (!this.permissions[origin]) {
|
||||
this.permissions[origin] = {};
|
||||
}
|
||||
this.permissions[origin][permission] = PERMISSION_DENIED;
|
||||
this.writeFileSync();
|
||||
}
|
||||
|
||||
clear(origin, permission) {
|
||||
delete this.permissions[origin][permission];
|
||||
}
|
||||
|
||||
isGranted(origin, permission) {
|
||||
if (this.permissions[origin]) {
|
||||
return this.permissions[origin][permission] === PERMISSION_GRANTED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
isDenied(origin, permission) {
|
||||
if (this.permissions[origin]) {
|
||||
return this.permissions[origin][permission] === PERMISSION_DENIED;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function dequeueRequests(requestQueue, permissionManager, origin, permission, status) {
|
||||
switch (status) {
|
||||
case 'allow':
|
||||
permissionManager.grant(origin, permission);
|
||||
break;
|
||||
case 'block':
|
||||
permissionManager.deny(origin, permission);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (status === 'allow' || status === 'block') {
|
||||
const newQueue = requestQueue.filter((request) => {
|
||||
if (request.origin === origin && request.permission === permission) {
|
||||
request.callback(status === 'allow');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
requestQueue.splice(0, requestQueue.length, ...newQueue);
|
||||
} else {
|
||||
const index = requestQueue.findIndex((request) => {
|
||||
return request.origin === origin && request.permission === permission;
|
||||
});
|
||||
requestQueue[index].callback(false);
|
||||
requestQueue.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
function permissionRequestHandler(mainWindow, permissionFile) {
|
||||
const permissionManager = new PermissionManager(permissionFile);
|
||||
const requestQueue = [];
|
||||
ipcMain.on('update-permission', (event, origin, permission, status) => {
|
||||
dequeueRequests(requestQueue, permissionManager, origin, permission, status);
|
||||
});
|
||||
return (webContents, permission, callback) => {
|
||||
const targetURL = new URL(webContents.getURL());
|
||||
if (permissionManager.isDenied(targetURL.origin, permission)) {
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
if (permissionManager.isGranted(targetURL.origin, permission)) {
|
||||
callback(true);
|
||||
return;
|
||||
}
|
||||
|
||||
requestQueue.push({
|
||||
origin: targetURL.origin,
|
||||
permission,
|
||||
callback
|
||||
});
|
||||
mainWindow.webContents.send('request-permission', targetURL.origin, permission);
|
||||
};
|
||||
}
|
||||
|
||||
permissionRequestHandler.PermissionManager = PermissionManager;
|
||||
|
||||
module.exports = permissionRequestHandler;
|
@@ -23,6 +23,7 @@ const mattermostURL = 'http://example.com/team';
|
||||
module.exports = {
|
||||
sourceRootDir,
|
||||
configFilePath,
|
||||
userDataDir,
|
||||
boundsInfoPath,
|
||||
mattermostURL,
|
||||
|
||||
|
80
test/specs/permisson_test.js
Normal file
80
test/specs/permisson_test.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/* eslint-disable no-unused-expressions */
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const env = require('../modules/environment');
|
||||
const {PermissionManager} = require('../../src/main/permissionRequestHandler');
|
||||
|
||||
const permissionFile = path.join(env.userDataDir, 'permission.json');
|
||||
|
||||
describe('PermissionManager', function() {
|
||||
beforeEach(function(done) {
|
||||
fs.unlink(permissionFile, () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should grant a permisson for an origin', function() {
|
||||
const ORIGIN = 'origin';
|
||||
const PERMISSION = 'permission';
|
||||
const manager = new PermissionManager(permissionFile);
|
||||
|
||||
manager.isGranted(ORIGIN, PERMISSION).should.be.false;
|
||||
manager.isDenied(ORIGIN, PERMISSION).should.be.false;
|
||||
|
||||
manager.grant(ORIGIN, PERMISSION);
|
||||
|
||||
manager.isGranted(ORIGIN, PERMISSION).should.be.true;
|
||||
manager.isDenied(ORIGIN, PERMISSION).should.be.false;
|
||||
|
||||
manager.isGranted(ORIGIN + '_another', PERMISSION).should.be.false;
|
||||
manager.isGranted(ORIGIN, PERMISSION + '_another').should.be.false;
|
||||
});
|
||||
|
||||
it('should deny a permisson for an origin', function() {
|
||||
const ORIGIN = 'origin';
|
||||
const PERMISSION = 'permission';
|
||||
const manager = new PermissionManager(permissionFile);
|
||||
|
||||
manager.isGranted(ORIGIN, PERMISSION).should.be.false;
|
||||
manager.isDenied(ORIGIN, PERMISSION).should.be.false;
|
||||
|
||||
manager.deny(ORIGIN, PERMISSION);
|
||||
|
||||
manager.isGranted(ORIGIN, PERMISSION).should.be.false;
|
||||
manager.isDenied(ORIGIN, PERMISSION).should.be.true;
|
||||
|
||||
manager.isDenied(ORIGIN + '_another', PERMISSION).should.be.false;
|
||||
manager.isDenied(ORIGIN, PERMISSION + '_another').should.be.false;
|
||||
});
|
||||
|
||||
it('should save permissons to the file', function() {
|
||||
const ORIGIN = 'origin';
|
||||
const PERMISSION = 'permission';
|
||||
const manager = new PermissionManager(permissionFile);
|
||||
manager.deny(ORIGIN, PERMISSION);
|
||||
manager.grant(ORIGIN + '_another', PERMISSION + '_another');
|
||||
JSON.parse(fs.readFileSync(permissionFile)).should.deep.equal({
|
||||
origin: {
|
||||
permission: 'denied'
|
||||
},
|
||||
origin_another: {
|
||||
permission_another: 'granted'
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should restore permissions from the file', function() {
|
||||
fs.writeFileSync(permissionFile, JSON.stringify({
|
||||
origin: {
|
||||
permission: 'denied'
|
||||
},
|
||||
origin_another: {
|
||||
permission_another: 'granted'
|
||||
}
|
||||
}));
|
||||
const manager = new PermissionManager(permissionFile);
|
||||
manager.isDenied('origin', 'permission').should.be.true;
|
||||
manager.isGranted('origin_another', 'permission_another').should.be.true;
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user