Add public user support, break API into individual files

This commit is contained in:
2020-11-10 20:57:43 -06:00
parent 37f9c09fe2
commit 4636521d50
16 changed files with 371 additions and 134 deletions

View File

@@ -18,10 +18,6 @@ class FileGroup extends VersionedModel {
}
}
accessible_by(user, mode = 'view') {
return user.can(`files:${this.UUID}:${mode}`)
}
// Static and instance methods can go here
get page() {
const Page = require('./Page.model')

View File

@@ -170,20 +170,17 @@ class Page extends VersionedModel {
}
// ================= SECURITY =================
accessible_by(user, mode = 'view') {
const base_access = user.can(`page:${this.UUID}:${mode}`)
}
async is_accessible_by(user, mode = 'view') {
const can_manage = user.can(`page:${this.UUID}:manage`)
const can_update = user.can(`page:${this.UUID}:update`)
const can_view = user.can(`page:${this.UUID}:view`)
const can_all = user.can(`page:${this.UUID}`)
const can_manage = await user.can(`page:${this.UUID}:manage`)
const can_update = await user.can(`page:${this.UUID}:update`)
const can_view = await user.can(`page:${this.UUID}:view`)
const can_all = await user.can(`page:${this.UUID}`)
// Allow universal access
if ( can_all ) return true
// deny if blocked
else if ( user.can(`page:${this.UUID}:block`) ) return false
else if ( await user.can(`page:${this.UUID}:block`) ) return false
// manage, update, view can view
else if ( mode === 'view' && (can_manage || can_update || can_view) ) return true
// manage, update can update
@@ -236,9 +233,9 @@ class Page extends VersionedModel {
async unshare_with(user) {
// Remove this page from the user's permissions
if ( user.can(`page:${this.UUID}`) ) user.disallow(`page:${this.UUID}`)
if ( await user.can(`page:${this.UUID}`) ) user.disallow(`page:${this.UUID}`)
for ( const level of ['view', 'update', 'manage'] ) {
if ( user.can(`page:${this.UUID}:${level}`) ) user.disallow(`page:${this.UUID}:${level}`)
if ( await user.can(`page:${this.UUID}:${level}`) ) user.disallow(`page:${this.UUID}:${level}`)
}
// Remove the user from this page's access lists

View File

@@ -0,0 +1,99 @@
const User = require('./User.model')
const uuid = require('uuid/v4')
class PublicUserModel extends User {
static get services() {
return [...super.services, 'models']
}
static get schema() {
return {
...super.schema,
RequestData: {
hostname: String,
ips: [String],
ip: String,
date: String,
requests: [{
method: String,
original_url: String,
xhr: Boolean,
user_id: String,
date: { type: Date, default: () => new Date },
}],
},
}
}
static today() {
const date = new Date()
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
}
static async get_for_request(request) {
let user = await this.findOne({
'RequestData.hostname': request.hostname,
'RequestData.ip': request.headers['x-forwarded-for'] || request.connection.remoteAddress,
'RequestData.date': this.today(),
})
if ( !user ) user = await this.create_for_request(request)
await user.record_request(request)
await user.save()
return user
}
static async create_for_request(request) {
const data = {
hostname: request.hostname,
ips: request.ips,
ip: request.headers['x-forwarded-for'] || request.connection.remoteAddress,
date: this.today(),
requests: [],
}
const user = new this({
uid: `public-user-${uuid()}`,
RequestData: data,
})
await user.save()
return user
}
async record_request(request) {
if ( !this.RequestData.requests ) {
this.RequestData.requests = [];
}
this.RequestData.requests.push({
method: request.method,
original_url: request.originalUrl,
xhr: request.xhr,
user_id: request.user ? request.user.id : '',
})
}
async get_root_page() {
const Page = this.models.get('api:Page')
let page = await Page.findOne({OrgUserId: this._id, ParentId: '0'})
if ( !page ) {
page = new Page({
Name: 'Public Root Page',
OrgUserId: this._id,
ParentId: '0',
NodeIds: [],
ChildPageIds: [],
noDelete: true,
virtual: true,
})
await page.save()
}
return page
}
}
module.exports = exports = PublicUserModel

View File

@@ -0,0 +1,26 @@
const { Model } = require('flitter-orm')
const uuid = require('uuid/v4')
class PublicUserPermissionModel extends Model {
static get schema() {
return {
associated_user_id: String,
permission: String,
grant_date: { type: Date, default: () => new Date },
UUID: { type: String, default: uuid },
}
}
static async can(permission) {
const permission_parts = permission.split(':');
const match = await this.findOne({
permission: {
$in: permission_parts
}
})
return !!match
}
}
module.exports = exports = PublicUserPermissionModel