Skip to content

Commit

Permalink
Merge pull request #49 from domapic/release-1.0.0-beta.1
Browse files Browse the repository at this point in the history
Release 1.0.0 beta.1
  • Loading branch information
javierbrea committed Jan 8, 2019
2 parents bbfe726 + 88a86c0 commit 3eac587
Show file tree
Hide file tree
Showing 43 changed files with 1,419 additions and 87 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
### Removed

## [1.0.0-beta.1] - 2019-01-08
### Added
- Add DELETE method to servicePluginConfigs api
- Add DELETE method to services api
- Add PATCH and DELETE methods to users api

### Changed
- Upgrade mongoose version

## [1.0.0-alpha.14] - 2019-01-06
### Added
- Add anonymous default user, which will be used as logged user for requests with authentication disabled. When this user is logged in, services and abilities will be added to user with same name as service, not to logged user. In this way, the services connection process will work when authentication is disabled, and services registered will still be connected if authentication is enabled again.
Expand Down
107 changes: 62 additions & 45 deletions lib/api/servicePluginConfigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,80 @@ const definition = require('./servicePluginConfigs.json')
const { roles } = require('../security/utils')
const events = require('../events')

const LOCATION = 'location'
const LOCATION_ROOT = '/api/service-plugin-configs/'
const EVENT_ENTITY = 'servicePluginConfig'

const Operations = (service, commands) => ({
getServicePluginConfigs: {
handler: (params, body, res) => {
const filter = omitBy({
_service: params.query.service,
pluginPackageName: params.query['plugin-package-name']
}, isUndefined)
return commands.servicePluginConfig.getFiltered(filter)
}
},
getServicePluginConfig: {
handler: (params, body, res) => commands.servicePluginConfig.getById(params.path.id)
},
updateServicePluginConfig: {
auth: (userData, params, body) => {
if (userData.role === roles.PLUGIN || userData.role === roles.ADMIN) {
return Promise.resolve()
}
return commands.servicePluginConfig.getById(params.path.id).then(servicePluginConfigData => {
return commands.service.getById(servicePluginConfigData._service).then(serviceData => {
if (serviceData._user === userData._id) {
return Promise.resolve()
}
return Promise.reject(new service.errors.Forbidden())
})
})
},
handler: (params, body, res) => commands.servicePluginConfig.update(params.path.id, body).then(servicePluginConfigData => {
res.status(204)
res.header('location', `/api/service-plugin-configs/${servicePluginConfigData._id}`)
events.plugin(EVENT_ENTITY, events.OPERATIONS.UPDATE, servicePluginConfigData)
const Operations = (service, commands) => {
const adminPluginOrOwner = (userData, params, body) => {
if (userData.role === roles.PLUGIN || userData.role === roles.ADMIN) {
return Promise.resolve()
})
},
addServicePluginConfig: {
auth: (userData, params, body) => {
if (userData.role === roles.PLUGIN || userData.role === roles.ADMIN) {
return Promise.resolve()
}
return commands.service.getById(body._service).then(serviceData => {
}
return commands.servicePluginConfig.getById(params.path.id).then(servicePluginConfigData => {
return commands.service.getById(servicePluginConfigData._service).then(serviceData => {
if (serviceData._user === userData._id) {
return Promise.resolve()
}
return Promise.reject(new service.errors.Forbidden())
})
})
}

return {
getServicePluginConfigs: {
handler: (params, body, res) => {
const filter = omitBy({
_service: params.query.service,
pluginPackageName: params.query['plugin-package-name']
}, isUndefined)
return commands.servicePluginConfig.getFiltered(filter)
}
},
getServicePluginConfig: {
handler: (params, body, res) => commands.servicePluginConfig.getById(params.path.id)
},
handler: (params, body, res, userData) => commands.servicePluginConfig.add(body)
.then(servicePluginConfigData => {
res.status(201)
res.header('location', `/api/service-plugin-configs/${servicePluginConfigData._id}`)
events.plugin(EVENT_ENTITY, events.OPERATIONS.CREATE, servicePluginConfigData)
updateServicePluginConfig: {
auth: adminPluginOrOwner,
handler: (params, body, res) => commands.servicePluginConfig.update(params.path.id, body).then(servicePluginConfigData => {
res.status(204)
res.header(LOCATION, `${LOCATION_ROOT}${servicePluginConfigData._id}`)
events.plugin(EVENT_ENTITY, events.OPERATIONS.UPDATE, servicePluginConfigData)
return Promise.resolve()
})
},
addServicePluginConfig: {
auth: (userData, params, body) => {
if (userData.role === roles.PLUGIN || userData.role === roles.ADMIN) {
return Promise.resolve()
}
return commands.service.getById(body._service).then(serviceData => {
if (serviceData._user === userData._id) {
return Promise.resolve()
}
return Promise.reject(new service.errors.Forbidden())
})
},
handler: (params, body, res, userData) => commands.servicePluginConfig.add(body)
.then(servicePluginConfigData => {
res.status(201)
res.header(LOCATION, `${LOCATION_ROOT}${servicePluginConfigData._id}`)
events.plugin(EVENT_ENTITY, events.OPERATIONS.CREATE, servicePluginConfigData)
return Promise.resolve()
})
},
deleteServicePluginConfig: {
auth: adminPluginOrOwner,
handler: (params, body, res, userData) => commands.servicePluginConfig.remove(params.path.id)
.then(servicePluginConfigData => {
res.status(204)
events.plugin(EVENT_ENTITY, events.OPERATIONS.DELETE, {
_id: params.path.id
})
return Promise.resolve()
})
}
}
})
}

const openapi = () => [definition]

Expand Down
30 changes: 30 additions & 0 deletions lib/api/servicePluginConfigs.json
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,36 @@
}, {
"apiKey": []
}]
},
"delete": {
"parameters": [
{
"in": "path",
"name": "id",
"schema": {
"type": "string"
},
"required": true,
"description": "Service plugin configuration id"
}
],
"tags": ["service"],
"summary": "Delete service plugin configuration",
"description": "Delete service plugin configuration",
"operationId": "deleteServicePluginConfig",
"responses": {
"204": {
"$ref": "#/components/responses/Deleted"
},
"404": {
"$ref": "#/components/responses/NotFoundError"
}
},
"security": [{
"jwt": []
}, {
"apiKey": []
}]
}
}
}
Expand Down
12 changes: 11 additions & 1 deletion lib/api/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const { omitBy, isUndefined } = require('lodash')

const definition = require('./services.json')
const { roles } = require('../security/utils')
const { roles, onlyAdmin } = require('../security/utils')
const events = require('../events')

const EVENT_ENTITY = 'service'
Expand Down Expand Up @@ -44,6 +44,16 @@ const Operations = (service, commands) => ({
events.plugin(EVENT_ENTITY, events.OPERATIONS.CREATE, serviceData)
return Promise.resolve()
}))
},
deleteService: {
auth: onlyAdmin,
handler: (params, body, res) => commands.composed.removeService(params.path.id).then(() => {
res.status(204)
events.plugin(EVENT_ENTITY, events.OPERATIONS.DELETE, {
_id: params.path.id
})
return Promise.resolve()
})
}
})

Expand Down
30 changes: 30 additions & 0 deletions lib/api/services.json
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,36 @@
}, {
"apiKey": []
}]
},
"delete": {
"parameters": [
{
"in": "path",
"name": "id",
"schema": {
"type": "string"
},
"required": true,
"description": "Service id"
}
],
"tags": ["service"],
"summary": "Delete service",
"description": "Delete service",
"operationId": "deleteService",
"responses": {
"204": {
"$ref": "#/components/responses/Deleted"
},
"404": {
"$ref": "#/components/responses/NotFoundError"
}
},
"security": [{
"jwt": []
}, {
"apiKey": []
}]
}
}
}
Expand Down
42 changes: 38 additions & 4 deletions lib/api/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
const { omitBy, isUndefined } = require('lodash')

const definition = require('./users.json')
const { roles } = require('../security/utils')
const { roles, onlyAdmin } = require('../security/utils')
const events = require('../events')

const LOCATION = 'location'
const LOCATION_ROOT = '/api/users/'
const EVENT_ENTITY = 'user'

const Operations = (service, commands) => {
Expand All @@ -31,22 +33,54 @@ const Operations = (service, commands) => {
handler: (params, body, res) => commands.user.add(body)
.then(user => {
res.status(201)
res.header('location', `/api/users/${user._id}`)
res.header(LOCATION, `${LOCATION_ROOT}${user._id}`)
events.plugin(EVENT_ENTITY, events.OPERATIONS.CREATE, user)
return Promise.resolve()
})
},
getUser: {
auth: (userData, params) => commands.user.getById(params.path.id)
.then(user => {
if (rolesBasedAuth(userData.role, user.role) || params.path.id === userData._id) {
return Promise.resolve()
}
return Promise.reject(new service.errors.Forbidden())
}),
handler: (params, body, res) => commands.user.getById(params.path.id)
},
updateUser: {
auth: (userData, params, body) => {
return commands.user.getById(params.path.id)
.then(user => {
if (rolesBasedAuth(userData.role, user.role) || params.path.id === userData._id) {
if (
// Only operators and admin users can be modified
[roles.ADMIN, roles.OPERATOR].includes(user.role) &&
// Role can be only modified by administrators
(userData.role === roles.ADMIN || (params.path.id === userData._id && !body.role)) &&
// Role can be modified only to operator or admin roles
(!body.role || [roles.ADMIN, roles.OPERATOR].includes(body.role))
) {
return Promise.resolve()
}
return Promise.reject(new service.errors.Forbidden())
})
},
handler: (params, body, res) => commands.user.getById(params.path.id)
handler: (params, body, res) => commands.user.update(params.path.id, body).then(user => {
res.status(204)
res.header(LOCATION, `${LOCATION_ROOT}${user._id}`)
events.plugin(EVENT_ENTITY, events.OPERATIONS.UPDATE, user)
return Promise.resolve()
})
},
deleteUser: {
auth: onlyAdmin,
handler: (params, body, res) => commands.composed.removeUser(params.path.id).then(() => {
res.status(204)
events.plugin(EVENT_ENTITY, events.OPERATIONS.DELETE, {
_id: params.path.id
})
return Promise.resolve()
})
},
getUserMe: {
handler: (params, body, res, userData) => commands.user.getById(userData._id)
Expand Down

0 comments on commit 3eac587

Please sign in to comment.