Commit 9c048615 authored by Alexandros Georgantas's avatar Alexandros Georgantas

package updates and authsome init

parent 60186f2b
const authsomeMode = async (userId, operation, object, context) =>
// if (!userId) {
// // unauthenticated
// return false
// }
// // It's up to us to retrieve the relevant models for our
// // authorization/authsome mode, e.g.
// const user = await context.models.User.find(userId)
// // Admins can do anything
// if (user && user.admin === true) return true
// if (user) {
// return authenticatedUser(user, operation, object, context)
// }
true
module.exports = authsomeMode
const { pickBy } = require('lodash')
class AuthsomeMode {
/**
* Creates a new instance of AuthsomeMode
*
* @param {string} userId A user's UUID
* @param {string} operation The operation you're authorizing for
* @param {any} object The object of authorization
* @param {any} context Context for authorization, e.g. database access
* @returns {string}
*/
constructor(userId, operation, object, context) {
this.userId = userId
this.operation = AuthsomeMode.mapOperation(operation)
this.object = object
this.context = context
}
/**
* Maps operations from HTTP verbs to semantic verbs
*
* @param {any} operation
* @returns {string}
*/
static mapOperation(operation) {
const operationMap = {
GET: 'read',
POST: 'create',
PATCH: 'update',
DELETE: 'delete',
}
return operationMap[operation] ? operationMap[operation] : operation
}
async isTeamMember(teamType, object) {
let membershipCondition
if (object) {
membershipCondition = team =>
team.teamType === teamType &&
team.object &&
team.object.id === object.id
} else {
membershipCondition = team => team.teamType === teamType
}
const memberships = await Promise.all(
this.user.teams.map(async teamId => {
const teamFound = await this.context.models.Team.find(teamId)
if (teamFound) {
return membershipCondition(teamFound)
}
return false
}),
)
return memberships.includes(true)
}
isAuthor(object) {
return this.isTeamMember('author', object)
}
async findCollectionByObject(object) {
const { type, id, book, object: collection } = object
let collectionId
switch (type) {
case 'fragment':
collectionId = book
break
case 'team':
collectionId = collection.id
break
default:
collectionId = id
break
}
if (id) {
return this.context.models.Collection.find(collectionId)
}
return undefined
}
async canRead() {
this.user = await this.context.models.User.find(this.userId)
// const collection = await this.findCollectionByObject(this.object)
// const permission = await this.isAuthor(collection)
return true
}
async canListCollections() {
this.user = await this.context.models.User.find(this.userId)
return {
filter: async collections => {
const filteredCollections = await Promise.all(
collections.map(async collection => {
const condition = await this.isAuthor(collection)
return condition ? collection : undefined
}, this),
)
return filteredCollections.filter(collection => collection)
},
}
}
async canReadUser() {
this.user = await this.context.models.User.find(this.userId)
if (this.user.id === this.object.id) {
return true
}
return {
filter: user =>
pickBy(user, (_, key) => ['id', 'username', 'type'].includes(key)),
}
}
async canListTeams() {
this.user = await this.context.models.User.find(this.userId)
return {
filter: async teams => {
const filteredTeams = await Promise.all(
teams.map(async team => {
const condition = this.belongsToTeam(team.id)
return condition ? team : undefined
}, this),
)
return filteredTeams.filter(team => team)
},
}
}
belongsToTeam(teamId) {
return this.user.teams.includes(teamId)
}
async canReadTeam() {
this.user = await this.context.models.User.find(this.userId)
return true
}
async canCreateTeam() {
this.user = await this.context.models.User.find(this.userId)
return true
}
async canUpdateTeam() {
this.user = await this.context.models.User.find(this.userId)
return true
}
async canCreateCollection() {
this.user = await this.context.models.User.find(this.userId)
return true
}
}
module.exports = {
before: async (userId, operation, object, context) => {
const user = await context.models.User.find(userId)
return user && user.admin
},
GET: (userId, operation, object, context) => {
// const mode = new AuthsomeMode(userId, operation, object, context)
// GET /api/collections
if (object && object.path === '/collections') {
return true
}
// GET /api/collection
if (object && object.type === 'collection') {
return true
}
// GET /api/collections/:collectionId/fragments
if (object && object.path === '/fragments') {
return true
}
// GET /api/collections/:collectionId/fragments/:fragmentId
if (object && object.type === 'fragment') {
return true
}
// GET /api/users
if (object && object.path === '/users') {
return true
}
// // GET /api/teams
if (object && object.path === '/teams') {
return true
}
// // GET /api/team
if (object && object.type === 'team') {
return true
}
// // GET /api/user
if (object && object.type === 'user') {
return true
}
return false
},
POST: (userId, operation, object, context) => {
const mode = new AuthsomeMode(userId, operation, object, context)
// POST /api/collections
if (object && object.path === '/collections') {
return mode.canCreateCollection()
}
// POST /api/users
if (object && object.path === '/users') {
return true
}
// POST /api/fragments
if (object && object.path === '/collections/:collectionId/fragments') {
return true
}
// POST /api/teams
if (object && object.path === '/teams') {
return true
}
return false
},
PATCH: (userId, operation, object, context) => {
// const mode = new AuthsomeMode(userId, operation, object, context)
// PATCH /api/collections/:id
let data
if (object) {
if (object.current) {
data = object.current
} else {
data = object
}
} else {
return false
}
if (data.type === 'collection') {
return true
}
// PATCH /api/fragments/:id
if (data.type === 'fragment') {
return true
}
// PATCH /api/teams/:id
if (data.current.type === 'team') {
return true
}
return false
},
DELETE: (userId, operation, object, context) => {
// const mode = new AuthsomeMode(userId, operation, object, context)
// DELETE /api/collections/:id
if (object && object.type === 'collection') {
return true
}
// DELETE /api/fragments/:id
if (object && object.type === 'fragment') {
return true
}
// DELETE /api/teams/:id
if (object && object.type === 'team') {
return true
}
return false
},
}
......@@ -13,17 +13,17 @@ module.exports = {
API_ENDPOINT: '/api',
theme: 'PepperTheme',
'login-redirect': '/manage/posts',
'redux-log': true,
'redux-log': false,
},
authsome: {
// this should be either an npm package or an absolute path, not a relative path
mode: path.resolve(__dirname, 'authsome-mode.js'),
mode: path.resolve(__dirname, './authsome-mode.js'),
teams: {
teamContributors: {
name: 'Contributors',
seniorUser: {
name: 'Senior User',
},
teamCoauthors: {
name: 'Coauthors',
simpleUser: {
name: 'Simple User',
},
},
},
......
......@@ -47,6 +47,13 @@
core-js "^2.5.3"
regenerator-runtime "^0.11.1"
"@babel/runtime@^7.0.0-beta.40":
version "7.0.0-beta.46"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.46.tgz#466a9c0498f6d12d054a185981eef742d59d4871"
dependencies:
core-js "^2.5.3"
regenerator-runtime "^0.11.1"
"@babel/template@7.0.0-beta.40":
version "7.0.0-beta.40"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.40.tgz#034988c6424eb5c3268fe6a608626de1f4410fc8"
......@@ -141,6 +148,32 @@
version "2.0.49"
resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0"
"@pubsweet/ui@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@pubsweet/ui/-/ui-4.0.0.tgz#8e6c7a011b3b1607478c9cd51f61daf2f3a1c5fa"
dependencies:
babel-jest "^21.2.0"
classnames "^2.2.5"
enzyme "^3.2.0"
enzyme-adapter-react-16 "^1.1.1"
invariant "^2.2.3"
lodash "^4.17.4"
prop-types "^15.5.10"
react "^16.2.0"
react-dom "^16.2.0"
react-feather "^1.0.8"
react-redux "^5.0.2"
react-router-dom "^4.2.2"
react-tag-autocomplete "^5.5.0"
recompose "^0.26.0"
redux "^3.6.0"
redux-form "^7.0.3"
styled-components "^3.2.5"
"@types/async@2.0.49":
version "2.0.49"
resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.49.tgz#92e33d13f74c895cb9a7f38ba97db8431ed14bc0"
"@types/chalk@^0.4.31":
version "0.4.31"
resolved "https://registry.yarnpkg.com/@types/chalk/-/chalk-0.4.31.tgz#a31d74241a6b1edbb973cf36d97a2896834a51f9"
......@@ -165,6 +198,10 @@
version "0.5.3"
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.3.tgz#91b728599544efbb7386d8b6633693a3c2e7ade5"
"@types/zen-observable@^0.5.3":
version "0.5.3"
resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.5.3.tgz#91b728599544efbb7386d8b6633693a3c2e7ade5"
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
......@@ -408,6 +445,14 @@ apollo-upload-client@^8.0.0:
apollo-link-http-common "^0.2.3"
extract-files "^3.1.0"
apollo-upload-client@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-8.0.0.tgz#0067f3b426b3828f971964799bc31f8073bd0607"
dependencies:
"@babel/runtime" "^7.0.0-beta.40"
apollo-link-http-common "^0.2.3"
extract-files "^3.1.0"
apollo-upload-server@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/apollo-upload-server/-/apollo-upload-server-4.0.2.tgz#1a042e413d09d4bd5529738f9e0af45ba553cc2d"
......@@ -420,6 +465,10 @@ apollo-utilities@^1.0.0, apollo-utilities@^1.0.1, apollo-utilities@^1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.12.tgz#9e2b2a34cf89f3bf0d73a664effd8c1bb5d1b7f7"
apollo-utilities@^1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.12.tgz#9e2b2a34cf89f3bf0d73a664effd8c1bb5d1b7f7"
app-module-path@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5"
......@@ -611,7 +660,7 @@ atob@~1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773"
authsome@0.0.9, authsome@^0.0.9:
authsome@0.0.9:
version "0.0.9"
resolved "https://registry.yarnpkg.com/authsome/-/authsome-0.0.9.tgz#08b34f1797b3539e6a362f0fb11a01ae0613f928"
......@@ -4600,6 +4649,12 @@ invariant@^2.2.0:
dependencies:
loose-envify "^1.0.0"
invariant@^2.2.3:
version "2.2.4"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
dependencies:
loose-envify "^1.0.0"
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
......@@ -4975,6 +5030,10 @@ iterall@^1.1.3, iterall@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
iterall@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7"
jest-docblock@^21.0.0:
version "21.2.0"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414"
......@@ -6932,7 +6991,7 @@ prompt@^1.0.0:
utile "0.3.x"
winston "2.1.x"
prompt@flatiron/prompt#1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87:
"prompt@github:flatiron/prompt#1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87":
version "1.0.0"
resolved "https://codeload.github.com/flatiron/prompt/tar.gz/1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87"
dependencies:
......@@ -7566,6 +7625,19 @@ react-test-renderer@^16.0.0-0:
prop-types "^15.6.0"
react-is "^16.3.2"
react-tag-autocomplete@^5.5.0:
version "5.5.1"
resolved "https://registry.yarnpkg.com/react-tag-autocomplete/-/react-tag-autocomplete-5.5.1.tgz#6b3f253d3d69eb546925118cdf43138a9aafe113"
react-test-renderer@^16.0.0-0:
version "16.3.2"
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.3.2.tgz#3d1ed74fda8db42521fdf03328e933312214749a"
dependencies:
fbjs "^0.8.16"
object-assign "^4.1.1"
prop-types "^15.6.0"
react-is "^16.3.2"
react-transition-group@^1.1.2:
version "1.2.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-1.2.1.tgz#e11f72b257f921b213229a774df46612346c7ca6"
......@@ -8608,6 +8680,10 @@ stylis@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1"
stylis@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1"
supports-color@4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment