Skip to content

Commit 4de09d4

Browse files
authored
Merge pull request #1189 from jembi/PLAT-719-fix-user-matadata-importation
Plat 719 fix user metadata importation
2 parents 307172f + 5e6a793 commit 4de09d4

15 files changed

+189
-73
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "openhim-core",
33
"description": "The OpenHIM core application that provides logging and routing of http requests",
4-
"version": "7.2.0",
4+
"version": "7.2.1",
55
"main": "./lib/server.js",
66
"bin": {
77
"openhim-core": "./bin/openhim-core.js"

src/api/metadata.js

+14-14
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {ContactGroupModelAPI} from '../model/contactGroups'
1010
import {KeystoreModelAPI} from '../model/keystore'
1111
import {MediatorModelAPI} from '../model/mediators'
1212
import {UserModelAPI} from '../model/users'
13+
import {PassportModelAPI} from '../model/passport'
1314
import * as polling from '../polling'
1415

1516
// Map string parameters to collections
@@ -18,6 +19,7 @@ const collections = {
1819
Clients: ClientModelAPI,
1920
Mediators: MediatorModelAPI,
2021
Users: UserModelAPI,
22+
Passports: PassportModelAPI,
2123
ContactGroups: ContactGroupModelAPI,
2224
KeystoreModelAPI
2325
}
@@ -39,37 +41,35 @@ function removeProperties(obj) {
3941

4042
// Function to return unique identifier key and value for a collection
4143
function getUniqueIdentifierForCollection(collection, doc) {
42-
let uid
43-
let uidKey
44+
const returnObj = {}
45+
4446
switch (collection) {
4547
case 'Channels':
46-
uidKey = 'name'
47-
uid = doc.name
48+
returnObj['name'] = doc.name
4849
break
4950
case 'Clients':
50-
uidKey = 'clientID'
51-
uid = doc.clientID
51+
returnObj['clientID'] = doc.clientID
5252
break
5353
case 'Mediators':
54-
uidKey = 'urn'
55-
uid = doc.urn
54+
returnObj['urn'] = doc.urn
5655
break
5756
case 'Users':
58-
uidKey = 'email'
59-
uid = doc.email
57+
returnObj['email'] = doc.email
58+
break
59+
case 'Passports':
60+
returnObj['protocol'] = doc.protocol
61+
returnObj['email'] = doc.email
6062
break
6163
case 'ContactGroups':
62-
uidKey = 'groups'
63-
uid = doc.groups
64+
returnObj['groups'] = doc.groups
6465
break
6566
default:
6667
logger.debug(
6768
`Unhandeled case for ${collection} in getUniqueIdentifierForCollection`
6869
)
6970
break
7071
}
71-
const returnObj = {}
72-
returnObj[uidKey] = uid
72+
7373
return returnObj
7474
}
7575

src/api/users.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export async function authenticateToken(ctx, email) {
8787
} else {
8888
const passport = await PassportModelAPI.findOne({
8989
protocol: 'token',
90-
user: user.id
90+
email: user.email
9191
})
9292

9393
if (!passport) {

src/model/passport.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,11 @@ const PassportSchema = new Schema({
6868

6969
// Associations
7070
//
71-
// Associate every passport with one, and only one, user.
72-
user: {type: Schema.Types.ObjectId, ref: 'User'}
71+
// Associate every passport with a user.
72+
email: {
73+
type: String,
74+
required: true
75+
}
7376
})
7477

7578
// compile the Passport Schema into a Model
@@ -90,7 +93,7 @@ export const createPassport = async function (user, passwordInfo) {
9093
let result = {error: null, user: null}
9194
return await PassportModelAPI.create({
9295
protocol: passwordInfo.password ? 'local' : 'token',
93-
user: user.id,
96+
email: user.email,
9497
...passwordInfo
9598
})
9699
.then(async function () {

src/model/users.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export const updateUser = async function (newUserData) {
117117
if (password) {
118118
await PassportModelAPI.findOne({
119119
protocol: 'local',
120-
user: user.id
120+
email: user.email
121121
}).then(async function (passport) {
122122
if (passport) {
123123
passport.password = password
@@ -174,7 +174,7 @@ export const updateTokenUser = async function (newUserData) {
174174
if (passwordHash && passwordAlgorithm && passwordSalt) {
175175
await PassportModelAPI.findOne({
176176
protocol: 'token',
177-
user: user.id
177+
email: user.email
178178
}).then(async function (passport) {
179179
if (passport) {
180180
passport.passwordHash = passwordHash

src/protocols/local.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export const login = async function (email, password, next) {
3333
}
3434
return PassportModelAPI.findOne({
3535
protocol: user.provider === 'token' ? 'token' : 'local',
36-
user: user.id
36+
email: user.email
3737
})
3838
.then(function (passport) {
3939
if (passport) {

src/protocols/openid.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ export const login = async (
9494
tokens,
9595
issuer,
9696
identifier: identifier,
97-
protocol: 'openid'
97+
protocol: 'openid',
98+
email: user.email
9899
}
99100

100101
PassportModelAPI.findOne({
@@ -111,10 +112,7 @@ export const login = async (
111112
return createOrUpdateUser(user)
112113
.then(function (retrievedUser) {
113114
return PassportModelAPI.create(
114-
{
115-
user: retrievedUser.id,
116-
...newPassport
117-
},
115+
newPassport,
118116
function () {
119117
next(null, retrievedUser)
120118
}

src/protocols/token.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export const login = async function (req, next) {
8282

8383
const passport = await PassportModelAPI.findOne({
8484
protocol: 'token',
85-
user: user.id
85+
email: user.email
8686
})
8787

8888
if (passport == null) {

src/upgradeDB.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ upgradeFuncs.push({
252252
passwordHash: user.passwordHash,
253253
passwordAlgorithm: user.passwordAlgorithm,
254254
passwordSalt: user.passwordSalt,
255-
user: user.id,
255+
email: user.email,
256256
protocol: 'token'
257257
}
258258

test/integration/metadataAPITests.js

+120-3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {ClientModelAPI} from '../../src/model/clients'
1616
import {ContactGroupModelAPI} from '../../src/model/contactGroups'
1717
import {MediatorModelAPI} from '../../src/model/mediators'
1818
import {UserModelAPI} from '../../src/model/users'
19+
import {PassportModelAPI} from '../../src/model/passport'
1920
import * as polling from '../../src/polling'
2021

2122
const sampleMetadata = {
@@ -89,6 +90,12 @@ const sampleMetadata = {
8990
groups: ['admin', 'RHIE']
9091
}
9192
],
93+
Passports: [
94+
{
95+
96+
protocol: 'local'
97+
}
98+
],
9299
ContactGroups: [
93100
{
94101
group: 'Group 1',
@@ -101,6 +108,11 @@ const sampleMetadata = {
101108
{user: 'User 6', method: 'email', maxAlerts: '1 per day'}
102109
]
103110
}
111+
],
112+
Keystore: [
113+
{
114+
key: 'Key'
115+
}
104116
]
105117
}
106118

@@ -112,6 +124,7 @@ describe('API Integration Tests', () => {
112124
nonRootCookie = ''
113125

114126
before(async () => {
127+
await PassportModelAPI.deleteMany({})
115128
await promisify(server.start)({apiPort: SERVER_PORTS.apiPort})
116129
await testUtils.setupTestUsers()
117130
})
@@ -216,6 +229,17 @@ describe('API Integration Tests', () => {
216229
})
217230
})
218231

232+
describe('Passports', () => {
233+
it('should fetch passports and return status 200', async () => {
234+
const res = await request(BASE_URL)
235+
.get('/metadata')
236+
.set('Cookie', rootCookie)
237+
.expect(200)
238+
239+
res.body[0].Passports.length.should.equal(2)
240+
})
241+
})
242+
219243
describe('ContactGroups', () => {
220244
beforeEach(async () => {
221245
await new ContactGroupModelAPI(sampleMetadata.ContactGroups[0]).save()
@@ -724,10 +748,103 @@ describe('API Integration Tests', () => {
724748
// POST TO VALIDATE METADATA TESTS
725749
describe('*validateMetadata', () => {
726750
beforeEach(async () => {
751+
await PassportModelAPI.deleteMany()
727752
await testUtils.cleanupAllTestUsers()
728753
await testUtils.setupTestUsers()
729754
})
730755

756+
const sampleMetadata = {
757+
Channels: [
758+
{
759+
name: 'TestChannel1',
760+
urlPattern: 'test/sample',
761+
allow: ['PoC', 'Test1', 'Test2'],
762+
routes: [
763+
{name: 'test route', host: 'localhost', port: 9876, primary: true}
764+
],
765+
txViewAcl: 'group1',
766+
updatedBy: {
767+
id: new ObjectId(),
768+
name: 'Test'
769+
}
770+
}
771+
],
772+
Clients: [
773+
{
774+
clientID: 'YUIAIIIICIIAIA',
775+
clientDomain: 'him.jembi.org',
776+
name: 'OpenMRS Ishmael instance',
777+
roles: ['OpenMRS_PoC', 'PoC'],
778+
passwordHash:
779+
'$2a$10$w8GyqInkl72LMIQNpMM/fenF6VsVukyya.c6fh/GRtrKq05C2.Zgy',
780+
certFingerprint:
781+
'23:37:6A:5E:A9:13:A4:8C:66:C5:BB:9F:0E:0D:68:9B:99:80:10:FC'
782+
}
783+
],
784+
Mediators: [
785+
{
786+
urn: 'urn:uuid:EEA84E13-1C92-467C-B0BD-7C480462D1ED',
787+
version: '1.0.0',
788+
name: 'Save Encounter Mediator',
789+
description: 'A mediator for testing',
790+
endpoints: [
791+
{
792+
name: 'Save Encounter',
793+
host: 'localhost',
794+
port: '8005',
795+
type: 'http'
796+
}
797+
],
798+
defaultChannelConfig: [
799+
{
800+
name: 'Save Encounter 1',
801+
urlPattern: '/encounters',
802+
type: 'http',
803+
allow: [],
804+
routes: [
805+
{
806+
name: 'Save Encounter 1',
807+
host: 'localhost',
808+
port: '8005',
809+
type: 'http'
810+
}
811+
]
812+
}
813+
]
814+
}
815+
],
816+
Users: [
817+
{
818+
firstname: 'Namey',
819+
surname: 'mcTestName',
820+
821+
passwordAlgorithm: 'sha512',
822+
passwordHash: '796a5a8e-4e44-4d9f-9e04-c27ec6374ffa',
823+
passwordSalt: 'bf93caba-6eec-4c0c-a1a3-d968a7533fd7',
824+
groups: ['admin', 'RHIE']
825+
}
826+
],
827+
Passports: [
828+
{
829+
830+
protocol: 'local'
831+
}
832+
],
833+
ContactGroups: [
834+
{
835+
group: 'Group 1',
836+
users: [
837+
{user: 'User 1', method: 'sms', maxAlerts: 'no max'},
838+
{user: 'User 2', method: 'email', maxAlerts: '1 per hour'},
839+
{user: 'User 3', method: 'sms', maxAlerts: '1 per day'},
840+
{user: 'User 4', method: 'email', maxAlerts: 'no max'},
841+
{user: 'User 5', method: 'sms', maxAlerts: '1 per hour'},
842+
{user: 'User 6', method: 'email', maxAlerts: '1 per day'}
843+
]
844+
}
845+
]
846+
}
847+
731848
it('should validate metadata and return status 201', async () => {
732849
const res = await request(BASE_URL)
733850
.post('/metadata/validate')
@@ -741,7 +858,7 @@ describe('API Integration Tests', () => {
741858
statusCheckObj[doc.status] += 1
742859
}
743860

744-
statusCheckObj.Valid.should.equal(5)
861+
statusCheckObj.Valid.should.equal(6)
745862
statusCheckObj.Conflict.should.equal(0)
746863
statusCheckObj.Error.should.equal(0)
747864
})
@@ -762,7 +879,7 @@ describe('API Integration Tests', () => {
762879
statusCheckObj[doc.status] += 1
763880
}
764881

765-
statusCheckObj.Valid.should.equal(4)
882+
statusCheckObj.Valid.should.equal(5)
766883
statusCheckObj.Conflict.should.equal(0)
767884
statusCheckObj.Error.should.equal(1)
768885
})
@@ -787,7 +904,7 @@ describe('API Integration Tests', () => {
787904
statusCheckObj[doc.status] += 1
788905
}
789906

790-
statusCheckObj.Valid.should.equal(4)
907+
statusCheckObj.Valid.should.equal(5)
791908
statusCheckObj.Conflict.should.equal(1)
792909
statusCheckObj.Error.should.equal(0)
793910
ChannelModelAPI.deleteMany({})

0 commit comments

Comments
 (0)