Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
Fixes for user CRUD when using Google Auth
Browse files Browse the repository at this point in the history
Fixes #323
  • Loading branch information
jkleinsc committed Mar 2, 2016
1 parent 373f405 commit 624047e
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 59 deletions.
37 changes: 18 additions & 19 deletions app/adapters/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import Ember from 'ember';
import DS from 'ember-data';
import UserSession from 'hospitalrun/mixins/user-session';
export default DS.RESTAdapter.extend(UserSession, {
database: Ember.inject.service(),
session: Ember.inject.service(),
endpoint: '/db/_users/',

defaultSerializer: 'couchdb',
PouchOauthXHR: Ember.computed.alias('database.PouchOauthXHR'),
requestHeaders: null,

ajaxError: function(jqXHR) {
var error = this._super(jqXHR);
Expand All @@ -29,6 +31,12 @@ export default DS.RESTAdapter.extend(UserSession, {
ajaxOptions: function(url, type, hash) {
hash = hash || {};
hash.xhrFields = { withCredentials: true };
let PouchOauthXHR = this.get('PouchOauthXHR');
if (PouchOauthXHR) {
hash.xhr = function() {
return new PouchOauthXHR();
};
}
return this._super(url, type, hash);
},

Expand All @@ -54,18 +62,14 @@ export default DS.RESTAdapter.extend(UserSession, {

/**
Called by the store when a record is deleted.
The `deleteRecord` method makes an Ajax (HTTP DELETE) request to a URL computed by `buildURL`.
@method deleteRecord
@param {DS.Store} store
@param {subclass of DS.Model} type
@param {DS.Snapshot} record
@returns {Promise} promise
*/
deleteRecord: function(store, type, record) {
var deleteURL = this._getItemUrl(record);
return this.ajax(deleteURL, 'DELETE');
deleteRecord: function(store, type, snapshot) {
return this.updateRecord(store, type, snapshot, true);
},

/**
Expand Down Expand Up @@ -102,13 +106,19 @@ export default DS.RESTAdapter.extend(UserSession, {
@param {DS.Store} store
@param {subclass of DS.Model} type
@param {DS.Snapshot} record
@param {boolean} deleteUser true if we are deleting the user.
@returns {Promise} promise
*/
updateRecord: function(store, type, record) {
updateRecord: function(store, type, record, deleteUser) {
var data = {};
var serializer = store.serializerFor(record.modelName);
serializer.serializeIntoHash(data, type, record, { includeId: true });
data.type = 'user';
if (deleteUser) {
data.deleted = true;
delete data.oauth;
data.roles = ['deleted'];
}
if (Ember.isEmpty(data._rev)) {
delete data._rev;
}
Expand Down Expand Up @@ -164,17 +174,6 @@ export default DS.RESTAdapter.extend(UserSession, {
return data;
},

_getItemUrl: function(record) {
var urlArray = [this.endpoint];
urlArray.push(Ember.get(record, 'id'));
var rev = record.attr('rev');
if (rev) {
urlArray.push('?rev=');
urlArray.push(rev);
}
return urlArray.join('');
},

shouldReloadAll: function() {
return true;
}
Expand Down
1 change: 1 addition & 0 deletions app/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Ember from 'ember';
import EmberValidations from 'ember-validations';
var User = DS.Model.extend(EmberValidations, {
derived_key: DS.attr('string'),
deleted: DS.attr('boolean'),
displayName: DS.attr('string'),
email: DS.attr('string'),
iterations: DS.attr(),
Expand Down
4 changes: 3 additions & 1 deletion app/services/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import PouchAdapterUtils from 'hospitalrun/mixins/pouch-adapter-utils';
export default Ember.Service.extend(PouchAdapterUtils, {
config: Ember.inject.service(),
mainDB: null, // Server DB
PouchOauthXHR: null,
setMainDB: false,

setup(configs) {
Expand All @@ -29,8 +30,9 @@ export default Ember.Service.extend(PouchAdapterUtils, {
Ember.isEmpty(configs.config_token_secret)) {
throw Error('login required');
}
this.set('PouchOauthXHR', createPouchOauthXHR(configs));
pouchOptions.ajax = {
xhr: createPouchOauthXHR(configs),
xhr: this.get('PouchOauthXHR'),
timeout: 30000
};
}
Expand Down
34 changes: 18 additions & 16 deletions app/users/index/template.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,24 @@
{{/if}}
</tr>
{{#each model as |user|}}
<tr {{action 'editItem' user}}>
<td class="user-display-name">{{user.displayName}}</td>
<td class="user-name">{{user.name}}</td>
<td class="user-email">{{user.email}}</td>
<td class="user-role">{{user.displayRole}}</td>
{{#if showActions}}
<td>
{{#if canAdd}}
<button class="btn btn-default" {{action 'editItem' user bubbles=false }}>{{t 'labels.edit'}}</button>
{{/if}}
{{#if canDelete}}
<button class="btn btn-default" {{action 'deleteItem' user bubbles=false }}>{{t 'labels.delete'}}</button>
{{/if}}
</td>
{{/if}}
</tr>
{{#unless user.deleted}}
<tr {{action 'editItem' user}}>
<td class="user-display-name">{{user.displayName}}</td>
<td class="user-name">{{user.name}}</td>
<td class="user-email">{{user.email}}</td>
<td class="user-role">{{user.displayRole}}</td>
{{#if showActions}}
<td>
{{#if canAdd}}
<button class="btn btn-default" {{action 'editItem' user bubbles=false }}>{{t 'labels.edit'}}</button>
{{/if}}
{{#if canDelete}}
<button class="btn btn-default" {{action 'deleteItem' user bubbles=false }}>{{t 'labels.delete'}}</button>
{{/if}}
</td>
{{/if}}
</tr>
{{/unless}}
{{/each}}
</table>
{{else}}
Expand Down
38 changes: 20 additions & 18 deletions app/utils/pouch-oauth-xhr.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,26 @@ export default function(configs) {
this.requestHeaders = {
};
this.upload = this.internalXHR.upload;
return this;
}

PouchOauthXHR.prototype = {
_createCallback: function(functionName) {
if (this[functionName] !== undefined) {
let xhrwrapper = this;
this.internalXHR[functionName] = function() {
xhrwrapper.readyState = this.readyState;
xhrwrapper.response = this.response;
xhrwrapper.responseText = this.responseText;
xhrwrapper.responseType = this.responseType;
xhrwrapper.responseXML = this.responseXML;
xhrwrapper.status = this.status;
xhrwrapper.statusText = this.statusText;
xhrwrapper[functionName]();
};
}
},

_decodeParameters: function(paramString, currentParams) {
var returnParams = currentParams || {},
params = decodeURIComponent(paramString).split('&'),
Expand Down Expand Up @@ -85,24 +102,9 @@ export default function(configs) {
}
this.readyState = this.internalXHR.readyState;
this.status = this.internalXHR.status;
if (this.onreadystatechange !== undefined) {
var xhrwrapper = this;
this.internalXHR.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 0) {
console.log('wrapper readystatechange fired with xhr state and status:', this.readyState, this.status);
console.log('URL WAS: ' + xhrwrapper.url, xhrwrapper);
console.trace();
}
xhrwrapper.readyState = this.readyState;
xhrwrapper.response = this.response;
xhrwrapper.responseText = this.responseText;
xhrwrapper.responseType = this.responseType;
xhrwrapper.responseXML = this.responseXML;
xhrwrapper.status = this.status;
xhrwrapper.statusText = this.statusText;
xhrwrapper.onreadystatechange();
};
}
this._createCallback('onreadystatechange');
this._createCallback('onload');
this._createCallback('onerror');
this.internalXHR.send(data);
},

Expand Down
22 changes: 17 additions & 5 deletions tests/acceptance/users-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ test('create new user', function(assert) {
authenticateUser();
addAllUsers(assert);
visit('/admin/users');

stubRequest('put', '/db/_users/org.couchdb.user:[email protected]', function(request) {
var expectedBody = {
_id: 'org.couchdb.user:[email protected]',
deleted: false,
displayName: 'Jane Bagadonuts',
email: '[email protected]',
name: '[email protected]',
Expand Down Expand Up @@ -129,11 +129,23 @@ test('delete user', function(assert) {
runWithPouchDump('default', function() {
authenticateUser();
addAllUsers(assert);
stubRequest('delete', '/db/_users/org.couchdb.user:[email protected]', function(request) {
let expectedQuery = {
rev: '1-ef3d54502f2cc8e8f73d8547881f0836'
stubRequest('put', '/db/_users/org.couchdb.user:[email protected]', function(request) {
let expectedBody = {
_id: 'org.couchdb.user:[email protected]',
derived_key: 'derivedkeyhere',
deleted: true,
displayName: 'Joe Bagadonuts',
email: '[email protected]',
iterations: 10,
name: '[email protected]',
password_scheme: 'pbkdf2',
_rev: '1-ef3d54502f2cc8e8f73d8547881f0836',
roles: ['deleted'],
salt: 'saltgoeshere',
userPrefix: 'p01',
type: 'user'
};
assert.equal(JSON.stringify(request.queryParams), JSON.stringify(expectedQuery), 'Delete user request sent to the server');
assert.equal(request.requestBody, JSON.stringify(expectedBody), 'Delete user request sent to the server');
request.ok({
'ok': true,
'id': 'org.couchdb.user:[email protected]',
Expand Down

0 comments on commit 624047e

Please sign in to comment.