Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
module.exports = do ->
Dependencies
ld = require 'lodash'
cuid = require 'cuid'
common = require './common.js'
storage = require '../storage.js'
PPREFIX = storage.DBPREFIX.PAD
UPREFIX = storage.DBPREFIX.USER
GPREFIX = storage.DBPREFIX.GROUP
The pad module contains business logic for private pads. These belong to groups and can have their own visibility settings.
A pad can be viewed as an object like :
var pad = { _id: 'autoGeneratedUniqueString', name: 'title', group: 'idOfTheLinkedGroup', visibility: 'restricted', users: ['u1', 'u2'], password: null, readonly: true };
pad = {}
These functions are not private like with closures, for testing purposes, but they are expected be used only internally by other MyPads functions. They are tested through public functions and API.
pad.fn = {}
assignProps
takes params object and assign defaults if needed.
It creates :
users
array, empty if visibility
is not 'restricted', with given
keys otherwisevisibility
string, null or with restricted, private or publicpassword
string, null by defaultreadonly
boolean, null by defaultnull fields are intented to tell MyPads that group properties should be
applied here. assignProps
returns the pad object.
pad.fn.assignProps = (params) ->
p = params
u = name: p.name, group: p.group
if p.visibility is 'restricted' and ld.isArray(p.users)
u.users = ld.filter p.users, ld.isString
else
u.users = []
vVal = ['restricted', 'private', 'public']
v = p.visibility
isValidVisib = ld.isString(v) and ld.includes(vVal, v)
u.visibility = if isValidVisib then v else null
u.password = if ld.isString p.password then p.password else null
u.readonly = if ld.isBoolean p.readonly then p.readonly else null
return u
checkSet
is an async function that ensures that all given users exist.
If true, it calls fn.set
, else it will return an Error. It takes :
p
pad objectcallback
function returning an Error or null and the p
object. pad.fn.checkSet = (p, callback) ->
keys = ld.map p.users, (v) -> UPREFIX + v
keys.push GPREFIX + p.group
common.checkMultiExist keys, (err, res) ->
return callback err if err
e = 'pad group or at least one of the users are not found'
return callback new Error e if not res
pad.fn.set p, callback
indexGroups
is an asynchronous function which handles secondary indexes
for group.pads after pad creation, update, removal. It takes :
del
boolean to know if we have to delete key from index or add itpad
objectcallback
function, returning Error or null if succeeded pad.fn.indexGroups = (del, pad, callback) ->
_set = (g) ->
storage.db.set GPREFIX + g._id, g, (err) ->
return callback err if err
callback null
storage.db.get GPREFIX + pad.group, (err, g) ->
return callback err if err
if del
ld.pull g.pads, pad._id
_set g
else
if not ld.includes g.pads, pad._id
g.pads.push pad._id
_set g
else
callback null
set
is internal function that sets the pad into the database.
It takes, as arguments :
p
pad objectcallback
function returning an Error or null and the p
object. pad.fn.set = (p, callback) ->
storage.db.set PPREFIX + p._id, p, (err) ->
return callback err if err
pad.fn.indexGroups false, p, (err) ->
return callback err if err
callback null, p
This function uses common.getDel
with del
to false and PPREFIX
fixed. It will takes mandatory key string and callback function. See
common.getDel
for documentation.
pad.get = ld.partial common.getDel, false, PPREFIX
This function adds a new pad or updates properties of an existing one. It checks the fields, throws error if needed, sets defaults options. As arguments, it takes mandatory :
params
object, with
a name
string that can't be empty
group
string, the unique key identifying the linked required groupvisibility
, password
, readonly
the same strings as for
model.group
, but optional : it will takes the group value if not
definedusers
array, with ids of users invited to read and/or edit the pad, for
restricted visibility onlycallback
function returning Error if error, null otherwise and the
pad objectedit
boolean, defaults to false for reusing the function for
set (edit) an existing pad.TODO: ensure user has the right to link this group (admin)
pad.set = (params, callback) ->
common.addSetInit params, callback, ['name', 'group']
p = pad.fn.assignProps params
if params._id
p._id = params._id
common.checkExistence PPREFIX + p._id, (err, res) ->
return callback err if err
return callback new Error 'pad does not exist' if not res
pad.fn.checkSet p, callback
else
p._id = cuid()
pad.fn.checkSet p, callback
This function uses common.getDel
with del
to false and PPREFIX
fixed. It will takes mandatory key string and callback function. See
common.getDel
for documentation.
It uses the callback
function to handle secondary indexes for groups.
pad.del = (key, callback) ->
if not ld.isFunction callback
throw new TypeError 'callback must be a function'
common.getDel true, PPREFIX, key, (err, p) ->
return callback err if err
pad.fn.indexGroups true, p, callback
TODO Helper here are public functions created to facilitate interaction with the API and improve performance avoiding extra checking.
return pad