mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Refactored controllers, moved checkPermission to permission-checker.js middleware
This commit is contained in:
		
							parent
							
								
									29257c2228
								
							
						
					
					
						commit
						9450f6e54a
					
				
							
								
								
									
										29
									
								
								lib/middleware/permission-checker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/middleware/permission-checker.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | const MissingPermission = require('../missing-permission'); | ||||||
|  | const { ADMIN } = require('../permissions'); | ||||||
|  | 
 | ||||||
|  | module.exports = function(config, permission) { | ||||||
|  |     if (!permission || !config.extendedPermissions) { | ||||||
|  |         return (req, res, next) => next(); | ||||||
|  |     } | ||||||
|  |     return (req, res, next) => { | ||||||
|  |         if ( | ||||||
|  |             req.user && | ||||||
|  |             req.user.permissions && | ||||||
|  |             (req.user.permissions.indexOf(ADMIN) !== -1 || | ||||||
|  |                 req.user.permissions.indexOf(permission) !== -1) | ||||||
|  |         ) { | ||||||
|  |             return next(); | ||||||
|  |         } | ||||||
|  |         return res | ||||||
|  |             .status(403) | ||||||
|  |             .json( | ||||||
|  |                 new MissingPermission({ | ||||||
|  |                     permission, | ||||||
|  |                     message: `You require ${permission} to perform this action`, | ||||||
|  |                 }) | ||||||
|  |             ) | ||||||
|  |             .end(); | ||||||
|  |     }; | ||||||
|  | }; | ||||||
| @ -1,10 +1,10 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const test = require('ava'); | const test = require('ava'); | ||||||
| const store = require('./../test/fixtures/store'); | const store = require('../../test/fixtures/store'); | ||||||
| const { requirePermission } = require('./permissions'); | const checkPermission = require('./permission-checker'); | ||||||
| const supertest = require('supertest'); | const supertest = require('supertest'); | ||||||
| const getApp = require('./app'); | const getApp = require('../app'); | ||||||
| 
 | 
 | ||||||
| const { EventEmitter } = require('events'); | const { EventEmitter } = require('events'); | ||||||
| const eventBus = new EventEmitter(); | const eventBus = new EventEmitter(); | ||||||
| @ -16,13 +16,12 @@ function getSetup(preRouterHook) { | |||||||
|         baseUriPath: base, |         baseUriPath: base, | ||||||
|         stores, |         stores, | ||||||
|         eventBus, |         eventBus, | ||||||
|         extendedPermissions: true, |  | ||||||
|         preRouterHook(_app) { |         preRouterHook(_app) { | ||||||
|             preRouterHook(_app); |             preRouterHook(_app); | ||||||
| 
 | 
 | ||||||
|             _app.get( |             _app.get( | ||||||
|                 `${base}/protectedResource`, |                 `${base}/protectedResource`, | ||||||
|                 requirePermission('READ'), |                 checkPermission({ extendedPermissions: true }, 'READ'), | ||||||
|                 (req, res) => { |                 (req, res) => { | ||||||
|                     res.status(200) |                     res.status(200) | ||||||
|                         .json({ message: 'OK' }) |                         .json({ message: 'OK' }) | ||||||
| @ -1,7 +1,5 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const MissingPermission = require('./missing-permission'); |  | ||||||
| 
 |  | ||||||
| const ADMIN = 'ADMIN'; | const ADMIN = 'ADMIN'; | ||||||
| const CREATE_FEATURE = 'CREATE_FEATURE'; | const CREATE_FEATURE = 'CREATE_FEATURE'; | ||||||
| const UPDATE_FEATURE = 'UPDATE_FEATURE'; | const UPDATE_FEATURE = 'UPDATE_FEATURE'; | ||||||
| @ -11,30 +9,7 @@ const UPDATE_STRATEGY = 'UPDATE_STRATEGY'; | |||||||
| const DELETE_STRATEGY = 'DELETE_STRATEGY'; | const DELETE_STRATEGY = 'DELETE_STRATEGY'; | ||||||
| const UPDATE_APPLICATION = 'UPDATE_APPLICATION'; | const UPDATE_APPLICATION = 'UPDATE_APPLICATION'; | ||||||
| 
 | 
 | ||||||
| function requirePermission(permission) { |  | ||||||
|     return (req, res, next) => { |  | ||||||
|         if ( |  | ||||||
|             req.user && |  | ||||||
|             req.user.permissions && |  | ||||||
|             (req.user.permissions.indexOf(ADMIN) !== -1 || |  | ||||||
|                 req.user.permissions.indexOf(permission) !== -1) |  | ||||||
|         ) { |  | ||||||
|             return next(); |  | ||||||
|         } |  | ||||||
|         return res |  | ||||||
|             .status(403) |  | ||||||
|             .json( |  | ||||||
|                 new MissingPermission({ |  | ||||||
|                     permission, |  | ||||||
|                     message: `You require ${permission} to perform this action`, |  | ||||||
|                 }) |  | ||||||
|             ) |  | ||||||
|             .end(); |  | ||||||
|     }; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| module.exports = { | module.exports = { | ||||||
|     requirePermission, |  | ||||||
|     ADMIN, |     ADMIN, | ||||||
|     CREATE_FEATURE, |     CREATE_FEATURE, | ||||||
|     UPDATE_FEATURE, |     UPDATE_FEATURE, | ||||||
|  | |||||||
| @ -8,10 +8,10 @@ const extractUser = require('../../extract-user'); | |||||||
| const { UPDATE_FEATURE } = require('../../permissions'); | const { UPDATE_FEATURE } = require('../../permissions'); | ||||||
| 
 | 
 | ||||||
| class ArchiveController extends Controller { | class ArchiveController extends Controller { | ||||||
|     constructor(extendedPerms, { featureToggleStore, eventStore }) { |     constructor(config) { | ||||||
|         super(extendedPerms); |         super(config); | ||||||
|         this.featureToggleStore = featureToggleStore; |         this.featureToggleStore = config.stores.featureToggleStore; | ||||||
|         this.eventStore = eventStore; |         this.eventStore = config.stores.eventStore; | ||||||
| 
 | 
 | ||||||
|         this.get('/features', this.getArchivedFeatures); |         this.get('/features', this.getArchivedFeatures); | ||||||
|         this.post('/revive/:name', this.reviveFeatureToggle, UPDATE_FEATURE); |         this.post('/revive/:name', this.reviveFeatureToggle, UPDATE_FEATURE); | ||||||
|  | |||||||
| @ -6,9 +6,9 @@ const eventDiffer = require('../../event-differ'); | |||||||
| const version = 1; | const version = 1; | ||||||
| 
 | 
 | ||||||
| class EventController extends Controller { | class EventController extends Controller { | ||||||
|     constructor({ eventStore }) { |     constructor(config) { | ||||||
|         super(); |         super(config); | ||||||
|         this.eventStore = eventStore; |         this.eventStore = config.stores.eventStore; | ||||||
|         this.get('/', this.getEvents); |         this.get('/', this.getEvents); | ||||||
|         this.get('/:name', this.getEventsForToggle); |         this.get('/:name', this.getEventsForToggle); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -20,10 +20,10 @@ const { featureShema, nameSchema } = require('./feature-schema'); | |||||||
| const version = 1; | const version = 1; | ||||||
| 
 | 
 | ||||||
| class FeatureController extends Controller { | class FeatureController extends Controller { | ||||||
|     constructor(extendedPerms, { featureToggleStore, eventStore }) { |     constructor(config) { | ||||||
|         super(extendedPerms); |         super(config); | ||||||
|         this.featureToggleStore = featureToggleStore; |         this.featureToggleStore = config.stores.featureToggleStore; | ||||||
|         this.eventStore = eventStore; |         this.eventStore = config.stores.eventStore; | ||||||
| 
 | 
 | ||||||
|         this.get('/', this.getAllToggles); |         this.get('/', this.getAllToggles); | ||||||
|         this.post('/', this.createToggle, CREATE_FEATURE); |         this.post('/', this.createToggle, CREATE_FEATURE); | ||||||
|  | |||||||
| @ -11,21 +11,15 @@ const apiDef = require('./api-def.json'); | |||||||
| 
 | 
 | ||||||
| class AdminApi extends Controller { | class AdminApi extends Controller { | ||||||
|     constructor(config) { |     constructor(config) { | ||||||
|         super(); |         super(config); | ||||||
| 
 |  | ||||||
|         const stores = config.stores; |  | ||||||
|         const perms = config.extendedPermissions; |  | ||||||
| 
 | 
 | ||||||
|         this.app.get('/', this.index); |         this.app.get('/', this.index); | ||||||
|         this.app.use('/features', new FeatureController(perms, stores).router); |         this.app.use('/features', new FeatureController(config).router); | ||||||
|         this.app.use('/archive', new ArchiveController(perms, stores).router); |         this.app.use('/archive', new ArchiveController(config).router); | ||||||
|         this.app.use( |         this.app.use('/strategies', new StrategyController(config).router); | ||||||
|             '/strategies', |         this.app.use('/events', new EventController(config).router); | ||||||
|             new StrategyController(perms, stores).router |         this.app.use('/metrics', new MetricsController(config).router); | ||||||
|         ); |         this.app.use('/user', new UserController(config).router); | ||||||
|         this.app.use('/events', new EventController(stores).router); |  | ||||||
|         this.app.use('/metrics', new MetricsController(perms, stores).router); |  | ||||||
|         this.app.use('/user', new UserController(perms).router); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     index(req, res) { |     index(req, res) { | ||||||
|  | |||||||
| @ -8,17 +8,16 @@ const schema = require('./metrics-schema'); | |||||||
| const { UPDATE_APPLICATION } = require('../../permissions'); | const { UPDATE_APPLICATION } = require('../../permissions'); | ||||||
| 
 | 
 | ||||||
| class MetricsController extends Controller { | class MetricsController extends Controller { | ||||||
|     constructor( |     constructor(config) { | ||||||
|         extendedPerms, |         super(config); | ||||||
|         { |         const { | ||||||
|             clientMetricsStore, |             clientMetricsStore, | ||||||
|             clientInstanceStore, |             clientInstanceStore, | ||||||
|             clientApplicationsStore, |             clientApplicationsStore, | ||||||
|             strategyStore, |             strategyStore, | ||||||
|             featureToggleStore, |             featureToggleStore, | ||||||
|         } |         } = config.stores; | ||||||
|     ) { | 
 | ||||||
|         super(extendedPerms); |  | ||||||
|         this.metrics = new ClientMetrics(clientMetricsStore); |         this.metrics = new ClientMetrics(clientMetricsStore); | ||||||
|         this.clientInstanceStore = clientInstanceStore; |         this.clientInstanceStore = clientInstanceStore; | ||||||
|         this.clientApplicationsStore = clientApplicationsStore; |         this.clientApplicationsStore = clientApplicationsStore; | ||||||
|  | |||||||
| @ -16,10 +16,10 @@ const { | |||||||
| const version = 1; | const version = 1; | ||||||
| 
 | 
 | ||||||
| class StrategyController extends Controller { | class StrategyController extends Controller { | ||||||
|     constructor(extendedPerms, { strategyStore, eventStore }) { |     constructor(config) { | ||||||
|         super(extendedPerms); |         super(config); | ||||||
|         this.strategyStore = strategyStore; |         this.strategyStore = config.stores.strategyStore; | ||||||
|         this.eventStore = eventStore; |         this.eventStore = config.stores.eventStore; | ||||||
| 
 | 
 | ||||||
|         this.get('/', this.getAllStratgies); |         this.get('/', this.getAllStratgies); | ||||||
|         this.get('/:name', this.getStrategy); |         this.get('/:name', this.getStrategy); | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ | |||||||
| const Controller = require('../controller'); | const Controller = require('../controller'); | ||||||
| 
 | 
 | ||||||
| class UserController extends Controller { | class UserController extends Controller { | ||||||
|     constructor(perms) { |     constructor(config) { | ||||||
|         super(perms); |         super(config); | ||||||
|         this.get('/', this.getUser); |         this.get('/', this.getUser); | ||||||
|         this.get('/logout', this.logout); |         this.get('/logout', this.logout); | ||||||
|     } |     } | ||||||
| @ -12,8 +12,10 @@ class UserController extends Controller { | |||||||
|     getUser(req, res) { |     getUser(req, res) { | ||||||
|         if (req.user) { |         if (req.user) { | ||||||
|             const user = Object.assign({}, req.user); |             const user = Object.assign({}, req.user); | ||||||
|             if (!this.extendedPermissions) { |             if (!this.config.extendedPermissions) { | ||||||
|                 delete user.permissions; |                 delete user.permissions; | ||||||
|  |             } else if (!Array.isArray(user.permissions)) { | ||||||
|  |                 user.permissions = []; | ||||||
|             } |             } | ||||||
|             return res |             return res | ||||||
|                 .status(200) |                 .status(200) | ||||||
|  | |||||||
| @ -1,28 +1,21 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| const { Router } = require('express'); | const { Router } = require('express'); | ||||||
| const { requirePermission } = require('./../permissions'); | const checkPermission = require('../middleware/permission-checker'); | ||||||
| /** | /** | ||||||
|  * Base class for Controllers to standardize binding to express Router. |  * Base class for Controllers to standardize binding to express Router. | ||||||
|  */ |  */ | ||||||
| class Controller { | class Controller { | ||||||
|     constructor(extendedPermissions) { |     constructor(config) { | ||||||
|         const router = Router(); |         const router = Router(); | ||||||
|         this.app = router; |         this.app = router; | ||||||
|         this.extendedPermissions = extendedPermissions; |         this.config = config; | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     checkPermission(permission) { |  | ||||||
|         if (this.extendedPermissions && permission) { |  | ||||||
|             return requirePermission(permission); |  | ||||||
|         } |  | ||||||
|         return (res, req, next) => next(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     get(path, handler, permission) { |     get(path, handler, permission) { | ||||||
|         this.app.get( |         this.app.get( | ||||||
|             path, |             path, | ||||||
|             this.checkPermission(permission), |             checkPermission(this.config, permission), | ||||||
|             handler.bind(this) |             handler.bind(this) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| @ -30,7 +23,7 @@ class Controller { | |||||||
|     post(path, handler, permission) { |     post(path, handler, permission) { | ||||||
|         this.app.post( |         this.app.post( | ||||||
|             path, |             path, | ||||||
|             this.checkPermission(permission), |             checkPermission(this.config, permission), | ||||||
|             handler.bind(this) |             handler.bind(this) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| @ -38,7 +31,7 @@ class Controller { | |||||||
|     put(path, handler, permission) { |     put(path, handler, permission) { | ||||||
|         this.app.put( |         this.app.put( | ||||||
|             path, |             path, | ||||||
|             this.checkPermission(permission), |             checkPermission(this.config, permission), | ||||||
|             handler.bind(this) |             handler.bind(this) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| @ -46,7 +39,7 @@ class Controller { | |||||||
|     delete(path, handler, permission) { |     delete(path, handler, permission) { | ||||||
|         this.app.delete( |         this.app.delete( | ||||||
|             path, |             path, | ||||||
|             this.checkPermission(permission), |             checkPermission(this.config, permission), | ||||||
|             handler.bind(this) |             handler.bind(this) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user