1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155 | 1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
1x
| Channel = require('../model/channels').Channel
Client = require('../model/clients').Client
Mediator = require('../model/mediators').Mediator
User = require('../model/users').User
ContactGroup = require('../model/contactGroups').ContactGroup
Keystore = require('../model/keystore').Keystore
Q = require 'q'
logger = require 'winston'
authorisation = require './authorisation'
utils = require "../utils"
# Map string parameters to collections
collections =
Channels: Channel
Clients: Client
Mediators: Mediator
Users: User
ContactGroups: ContactGroup
Keystore: Keystore
#Function to remove properties from export object
removeProperties = (obj) ->
propertyID = '_id'
propertyV = '__v'
for prop of obj
if (prop == propertyID || prop == propertyV)
delete obj[prop]
else if ( typeof obj[prop] == 'object' || obj[prop] instanceof Array )
removeProperties(obj[prop])
return obj
# Function to return unique identifier key and value for a collection
getUniqueIdentifierForCollection = (collection, doc) ->
switch collection
when 'Channels' then uidKey = 'name'; uid = doc.name
when 'Clients' then uidKey = 'clientID'; uid = doc.clientID
when 'Mediators' then uidKey = 'urn'; uid = doc.urn
when 'Users' then uidKey = 'email'; uid = doc.email
when 'ContactGroups' then uidKey = 'groups'; uid = doc.groups
returnObj = {}
returnObj[uidKey] = uid
return returnObj
# Build response object
buildResponseObject = (model, doc, status, message, uid) ->
return {
model: model
record: doc
status: status
message: message
uid: uid
}
# API endpoint that returns metadata for export
exports.getMetadata = () ->
# Test if the user is authorised
if not authorisation.inGroup 'admin', this.authenticated
return utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to getMetadata denied.", 'info'
try
exportObject = {}
params = this.request.query
# Return all documents from all collections for export
for col of collections
exportObject[col] = yield collections[col].find().lean().exec()
for doc in exportObject[col]
if doc._id
doc = removeProperties doc
this.body = [exportObject]
this.status = 200
catch e
this.body = e.message
utils.logAndSetResponse this, 500, "Could not fetch specified metadata via the API #{e}", 'error'
handleMetadataPost = (action, that) ->
# Test if the user is authorised
if not authorisation.inGroup 'admin', that.authenticated
return utils.logAndSetResponse that, 403, "User #{that.authenticated.email} is not an admin, API access to importMetadata denied.", 'info'
try
returnObject = []
insertObject = that.request.body
for key of insertObject
insertDocuments = insertObject[key]
for doc in insertDocuments
try
if key not of collections
throw new Error "Invalid Collection in Import Object"
# Keystore model does not have a uid other than _id and may not contain more than one entry
if key is 'Keystore'
result = yield collections[key].find().exec()
uid = ''
else
uidObj = getUniqueIdentifierForCollection key, doc
uid = uidObj[Object.keys(uidObj)[0]]
result = yield collections[key].find(uidObj).exec()
if action is 'import'
if result and result.length > 0 and result[0]._id
delete doc._id if doc._id
yield collections[key].findByIdAndUpdate(result[0]._id, doc).exec()
status = 'Updated'
else
doc = new collections[key] doc
result = yield Q.ninvoke doc, 'save'
status = 'Inserted'
if action is 'validate'
if result and result.length > 0 and result[0]._id
status = 'Conflict'
else
doc = new collections[key] doc
error = doc.validateSync()
if error
throw new Error "Document Validation failed: #{error}"
status = 'Valid'
logger.info "User #{that.authenticated.email} performed #{action} action on #{key}, got #{status}"
returnObject.push buildResponseObject key, doc, status, '', uid
catch e
logger.error "Failed to #{action} #{key} with unique identifier #{uid}. #{e.message}"
returnObject.push buildResponseObject key, doc, 'Error', e.message, uid
that.body = returnObject
that.status = 201
catch e
that.body = e.message
utils.logAndSetResponse that, 500, "Could not import metadata via the API #{e}", 'error'
# API endpoint that upserts metadata
exports.importMetadata = () ->
handleMetadataPost 'import', this
# API endpoint that checks for conflicts between import object and database
exports.validateMetadata = () ->
handleMetadataPost 'validate', this
if process.env.NODE_ENV == "test"
exports.buildResponseObject = buildResponseObject
exports.getUniqueIdentifierForCollection = getUniqueIdentifierForCollection
exports.removeProperties = removeProperties
|