Просмотр исходного кода

refactored rpc service into ajax service with get&post methods, updated ember.js auth views to talk to new /auth/ endpoint

Rafał Pitoń 10 лет назад
Родитель
Сommit
fcfa801d21

+ 1 - 1
misago/conf/defaults.py

@@ -250,7 +250,7 @@ MISAGO_STOP_FORUM_SPAM_MIN_CONFIDENCE = 80
 MISAGO_MAILER_BATCH_SIZE = 20
 
 # Auth paths
-MISAGO_LOGIN_API_URL = 'login'
+MISAGO_LOGIN_API_URL = 'auth'
 
 LOGIN_REDIRECT_URL = 'misago:index'
 LOGIN_URL = 'misago:login'

+ 3 - 3
misago/emberapp/app/adapters/application.js

@@ -11,11 +11,11 @@ export default DRFAdapter.extend({
   // Simple ajax util for RPC requests
   // raison d'etre: because default ones are processing server responses
   // and there isn't response standard to allow that for RPC's
-  rpcAjax: function(url, data) {
+  misagoAjax: function(method, url, data) {
     var adapter = this;
 
     return new Ember.RSVP.Promise(function(resolve, reject) {
-      var hash = adapter.ajaxOptions(url, 'POST', {data: data || null});
+      var hash = adapter.ajaxOptions(url, method, {data: data || null});
 
       hash.success = function(json) {
         Ember.run(null, resolve, json);
@@ -26,6 +26,6 @@ export default DRFAdapter.extend({
       };
 
       Ember.$.ajax(hash);
-    }, 'DS: MisagoAdapter#rpc-ajax POST to ' + url);
+    }, 'DS: MisagoAdapter#misago-ajax ' + method + ' to ' + url);
   }
 });

+ 1 - 1
misago/emberapp/app/components/forms/login-form.js

@@ -29,7 +29,7 @@ export default Ember.Component.extend({
     }
 
     var self = this;
-    this.rpc.ajax(this.get('settings.loginApiUrl'), credentials
+    this.ajax.post(this.get('settings.loginApiUrl'), credentials
     ).then(function() {
       if (self.isDestroyed) { return; }
       self.success(credentials);

+ 1 - 1
misago/emberapp/app/components/forms/register-form.js

@@ -185,7 +185,7 @@ export default Ember.Component.extend({
     this.set('isLoading', true);
 
     var self = this;
-    this.rpc.ajax('users', data
+    this.ajax.post('users', data
     ).then(function(response) {
       if (self.isDestroyed) { return; }
       self.success(response);

+ 1 - 1
misago/emberapp/app/components/forms/request-link-form.js

@@ -25,7 +25,7 @@ export default Ember.Component.extend({
     this.set('isLoading', true);
 
     var self = this;
-    this.rpc.ajax(this.get('url'), {
+    this.ajax.post(this.get('url'), {
       email: email
     }).then(function(requestingUser) {
       if (self.isDestroyed) { return; }

+ 2 - 2
misago/emberapp/app/components/forms/set-new-password-form.js

@@ -11,7 +11,7 @@ export default Ember.Component.extend({
   }.property(),
 
   url: function() {
-    return 'change-password/' + this.get('model.user_id') + '/' + this.get('model.token');
+    return 'auth/change-password/' + this.get('model.user_id') + '/' + this.get('model.token');
   }.property('model'),
 
   submit: function() {
@@ -29,7 +29,7 @@ export default Ember.Component.extend({
     this.set('isLoading', true);
 
     var self = this;
-    this.rpc.ajax(this.get('url'), {
+    this.ajax.post(this.get('url'), {
       password: password
     }).then(function() {
       if (self.isDestroyed) { return; }

+ 16 - 0
misago/emberapp/app/initializers/ajax-service.js

@@ -0,0 +1,16 @@
+import AjaxService from 'misago/services/ajax';
+
+export function initialize(_container, application) {
+  application.register('service:ajax', AjaxService, { singleton: true });
+
+  application.inject('service:ajax', 'store', 'store:main');
+
+  [ 'route', 'controller', 'component' ].forEach((factory) => {
+    application.inject(factory, 'ajax', 'service:ajax');
+  });
+}
+
+export default {
+  name: 'ajax-service',
+  initialize: initialize
+};

+ 0 - 16
misago/emberapp/app/initializers/rpc-service.js

@@ -1,16 +0,0 @@
-import RPCService from 'misago/services/rpc';
-
-export function initialize(_container, application) {
-  application.register('service:rpc', RPCService, { singleton: true });
-
-  application.inject('service:rpc', 'store', 'store:main');
-
-  [ 'route', 'controller', 'component' ].forEach((factory) => {
-    application.inject(factory, 'rpc', 'service:rpc');
-  });
-}
-
-export default {
-  name: 'rpc-service',
-  initialize: initialize
-};

+ 2 - 2
misago/emberapp/app/routes/activation/activate.js

@@ -3,7 +3,7 @@ import ResetScroll from 'misago/mixins/reset-scroll';
 
 export default MisagoRoute.extend(ResetScroll, {
   model: function(params) {
-    return this.rpc.ajax('activation/' + params.user_id + '/' + params.token + '/validate-token');
+    return this.ajax.post('auth/activate-account/' + params.user_id + '/' + params.token);
   },
 
   afterModel: function(model) {
@@ -19,7 +19,7 @@ export default MisagoRoute.extend(ResetScroll, {
     },
 
     error: function(reason) {
-      if (reason.status === 404) {
+      if (reason.status === 400) {
         this.toast.error(reason.responseJSON.detail);
         return this.transitionTo('activation');
       }

+ 2 - 2
misago/emberapp/app/routes/forgotten-password/change-form.js

@@ -3,7 +3,7 @@ import ResetScroll from 'misago/mixins/reset-scroll';
 
 export default MisagoRoute.extend(ResetScroll, {
   model: function(params) {
-    return this.rpc.ajax('change-password/' + params.user_id + '/' + params.token + '/validate-token');
+    return this.ajax.get('auth/change-password/' + params.user_id + '/' + params.token);
   },
 
   actions: {
@@ -12,7 +12,7 @@ export default MisagoRoute.extend(ResetScroll, {
     },
 
     error: function(reason) {
-      if (reason.status === 404) {
+      if (reason.status === 400) {
         this.toast.error(reason.responseJSON.detail);
         return this.transitionTo('forgotten-password');
       }

+ 16 - 4
misago/emberapp/app/services/rpc.js → misago/emberapp/app/services/ajax.js

@@ -1,7 +1,19 @@
 import Ember from 'ember';
 
 export default Ember.Service.extend({
-  ajax: function(recordOrProcedure, dataOrProcedure, data) {
+  get: function(recordOrProperty, recordProperty) {
+    if (typeof recordOrProperty === 'string' || typeof recordProperty !== 'string') {
+      recordProperty = null;
+    }
+
+    return this._ajax('GET', recordOrProperty, recordProperty);
+  },
+
+  post: function(recordOrProcedure, dataOrProcedure, data) {
+    return this._ajax('POST', recordOrProcedure, dataOrProcedure, data);
+  },
+
+  _ajax: function(method, recordOrProcedure, dataOrProcedure, data) {
     // unpack arguments
     var record = null;
     var procedure = null;
@@ -19,7 +31,7 @@ export default Ember.Service.extend({
       model = this.store.modelFor(record.constructor);
     }
 
-    // get adapter to be used for RPC
+    // get adapter to be used for ajax
     // note: in case of Model being null this cheats adapterFor to return
     // 'adapter:application'. we are doing this, because for some reason
     // store.defaultAdapter fails to return django adapter
@@ -33,8 +45,8 @@ export default Ember.Service.extend({
       url = this.buildProcedureURL(adapter, procedure);
     }
 
-    // return RPC promise
-    return adapter.rpcAjax(url, data || null);
+    // return promise
+    return adapter.misagoAjax(method, url, data || null);
   },
 
   buildRecordProcedureURL: function(adapter, model, record, procedure) {

+ 1 - 1
misago/emberapp/app/templates/activation/request-link.hbs

@@ -20,7 +20,7 @@
       <div class="col-md-4">
 
         <div class="well well-form">
-          {{request-link-form action="showSentPage" url="activation/send-link" placeholder=(gettext "Your e-mail address")}}
+          {{request-link-form action="showSentPage" url="auth/send-activation" placeholder=(gettext "Your e-mail address")}}
         </div>
 
       </div>

+ 1 - 1
misago/emberapp/app/templates/forgotten-password/request-link.hbs

@@ -20,7 +20,7 @@
       <div class="col-md-4">
 
         <div class="well well-form">
-          {{request-link-form action="showSentPage" url="change-password/send-link" placeholder=(gettext "Your e-mail address")}}
+          {{request-link-form action="showSentPage" url="auth/send-password-form" placeholder=(gettext "Your e-mail address")}}
         </div>
 
       </div>

+ 11 - 11
misago/emberapp/tests/acceptance/activate-test.js

@@ -46,7 +46,7 @@ test('request activation link with invalid e-mail', function(assert) {
 
   var message = 'Entered e-mail is invalid.';
   Ember.$.mockjax({
-    url: '/api/activation/send-link/',
+    url: '/api/auth/send-activation/',
     status: 400,
     responseText: {
       'detail': message,
@@ -69,7 +69,7 @@ test('request activation link with non-existing e-mail', function(assert) {
 
   var message = 'No user with this e-mail exists.';
   Ember.$.mockjax({
-    url: '/api/activation/send-link/',
+    url: '/api/auth/send-activation/',
     status: 400,
     responseText: {
       'detail': message,
@@ -92,7 +92,7 @@ test('request activation link with user-activated account', function(assert) {
 
   var message = 'You have to activate your account before you will be able to sign in.';
   Ember.$.mockjax({
-    url: '/api/activation/send-link/',
+    url: '/api/auth/send-activation/',
     status: 400,
     responseText: {
       'detail': message,
@@ -115,7 +115,7 @@ test('request activation link with admin-activated account', function(assert) {
 
   var message = 'Your account has to be activated by Administrator before you will be able to sign in.';
   Ember.$.mockjax({
-    url: '/api/activation/send-link/',
+    url: '/api/auth/send-activation/',
     status: 400,
     responseText: {
       'detail': message,
@@ -137,7 +137,7 @@ test('request activation link with banned account', function(assert) {
   assert.expect(2);
 
   Ember.$.mockjax({
-    url: '/api/activation/send-link/',
+    url: '/api/auth/send-activation/',
     status: 400,
     responseText: {
       'detail': {
@@ -168,7 +168,7 @@ test('request activation link', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/activation/send-link/',
+    url: '/api/auth/send-activation/',
     status: 200,
     responseText: {
       'username': 'BobBoberson',
@@ -191,8 +191,8 @@ test('invalid token is handled', function(assert) {
 
   var message = 'Token was rejected.';
   Ember.$.mockjax({
-    url: '/api/activation/1/token/validate-token/',
-    status: 404,
+    url: '/api/auth/activate-account/1/token/',
+    status: 400,
     responseText: {
       'detail': message
     }
@@ -211,7 +211,7 @@ test('permission denied is handled', function(assert) {
 
   var message = 'Token was rejected.';
   Ember.$.mockjax({
-    url: '/api/activation/1/token/validate-token/',
+    url: '/api/auth/activate-account/1/token/',
     status: 403,
     responseText: {
       'detail': message
@@ -228,12 +228,12 @@ test('permission denied is handled', function(assert) {
   });
 });
 
-test('token is validated', function(assert) {
+test('account is activated', function(assert) {
   assert.expect(2);
 
   var message = 'Yur account has been activated!';
   Ember.$.mockjax({
-    url: '/api/activation/1/token/validate-token/',
+    url: '/api/auth/activate-account/1/token/',
     status: 200,
     responseText: {
       'detail': message

+ 134 - 10
misago/emberapp/tests/acceptance/rpc-service-test.js → misago/emberapp/tests/acceptance/ajax-service-test.js

@@ -5,11 +5,11 @@ import startApp from '../helpers/start-app';
 
 var application, container, service;
 
-module('Acceptance: RPC Service', {
+module('Acceptance: Ajax Service', {
   beforeEach: function() {
     application = startApp();
     container = application.__container__;
-    service = container.lookup('service:rpc');
+    service = container.lookup('service:ajax');
   },
 
   afterEach: function() {
@@ -49,7 +49,131 @@ test('buildProcedureURL builds valid url', function(assert) {
   assert.equal(url, '/api/thread/1/close/');
 });
 
-test('successful RPC', function(assert) {
+test('successful get', function(assert) {
+  assert.expect(2);
+  var done = assert.async();
+
+  Ember.$.mockjax({
+    url: '/api/some-value/',
+    status: 200,
+    responseText: {
+      'detail': 'it works'
+    }
+  });
+
+  service.get('some-value').then(function(data) {
+    assert.equal(data.detail, 'it works');
+  }, function() {
+    assert.ok(false, 'get call should pass');
+  }).finally(function() {
+    assert.ok(true, 'finally() was called');
+    done();
+  });
+});
+
+test('failed post', function(assert) {
+  assert.expect(2);
+  var done = assert.async();
+
+  Ember.$.mockjax({
+    url: '/api/some-value/',
+    status: 400,
+    responseText: {
+      'detail': 'it fails'
+    }
+  });
+
+  service.get('some-value').then(function(data) {
+    assert.ok(false, 'get call should fail');
+  }, function(jqXHR) {
+    var rejection = jqXHR.responseJSON;
+    assert.equal(rejection.detail, 'it fails');
+  }).finally(function() {
+    assert.ok(true, 'finally() was called');
+    done();
+  });
+});
+
+test('successful model prop get', function(assert) {
+  assert.expect(2);
+  var done = assert.async();
+
+  Ember.$.mockjax({
+    url: '/api/legal-pages/privacy-policy/',
+    status: 200,
+    responseText: {
+      'id': 'privacy-policy',
+      'title': '',
+      'link': '',
+      'body': ''
+    }
+  });
+
+  Ember.$.mockjax({
+    url: '/api/legal-pages/privacy-policy/some-rpc/',
+    status: 200,
+    responseText: {
+      'detail': 'it works'
+    }
+  });
+
+  Ember.run(function() {
+    var store = container.lookup('store:main');
+
+    store.find('legal-page', 'privacy-policy').then(function(record) {
+      service.get(record, 'some-rpc').then(function(data) {
+        assert.equal(data.detail, 'it works');
+      }, function() {
+        assert.ok(false, 'model get call should pass');
+      }).finally(function() {
+        assert.ok(true, 'finally() was called');
+        done();
+      });
+    });
+  });
+});
+
+test('failed model prop get', function(assert) {
+  assert.expect(2);
+  var done = assert.async();
+
+  Ember.$.mockjax({
+    url: '/api/legal-pages/privacy-policy/',
+    status: 200,
+    responseText: {
+      'id': 'privacy-policy',
+      'title': '',
+      'link': '',
+      'body': ''
+    }
+  });
+
+  Ember.$.mockjax({
+    url: '/api/legal-pages/privacy-policy/some-rpc/',
+    status: 400,
+    responseText: {
+      'detail': 'it failed'
+    }
+  });
+
+  Ember.run(function() {
+    var store = container.lookup('store:main');
+
+    store.find('legal-page', 'privacy-policy').then(function(record) {
+      service.get(record, 'some-rpc').then(function() {
+        assert.ok(false, 'get call should fail');
+      }, function(jqXHR) {
+        var rejection = jqXHR.responseJSON;
+        assert.equal(rejection.detail, 'it failed');
+      }).finally(function() {
+        assert.ok(true, 'finally() was called');
+        done();
+      });
+    });
+  });
+});
+
+test('successful post', function(assert) {
   assert.expect(2);
   var done = assert.async();
 
@@ -61,7 +185,7 @@ test('successful RPC', function(assert) {
     }
   });
 
-  service.ajax('some-rpc').then(function(data) {
+  service.post('some-rpc').then(function(data) {
     assert.equal(data.detail, 'it works');
   }, function() {
     assert.ok(false, 'rpc call should pass');
@@ -71,7 +195,7 @@ test('successful RPC', function(assert) {
   });
 });
 
-test('failed RPC', function(assert) {
+test('failed post', function(assert) {
   assert.expect(2);
   var done = assert.async();
 
@@ -83,7 +207,7 @@ test('failed RPC', function(assert) {
     }
   });
 
-  service.ajax('some-rpc').then(function() {
+  service.post('some-rpc').then(function() {
     assert.ok(false, 'rpc call should fail');
   }, function(jqXHR) {
     var rejection = jqXHR.responseJSON;
@@ -94,7 +218,7 @@ test('failed RPC', function(assert) {
   });
 });
 
-test('successful model RPC', function(assert) {
+test('successful model rpc post', function(assert) {
   assert.expect(2);
   var done = assert.async();
 
@@ -121,7 +245,7 @@ test('successful model RPC', function(assert) {
     var store = container.lookup('store:main');
 
     store.find('legal-page', 'privacy-policy').then(function(record) {
-      service.ajax(record, 'some-rpc').then(function(data) {
+      service.post(record, 'some-rpc').then(function(data) {
         assert.equal(data.detail, 'it works');
       }, function() {
         assert.ok(false, 'rpc call should pass');
@@ -133,7 +257,7 @@ test('successful model RPC', function(assert) {
   });
 });
 
-test('failed model RPC', function(assert) {
+test('failed model rpc post', function(assert) {
   assert.expect(2);
   var done = assert.async();
 
@@ -160,7 +284,7 @@ test('failed model RPC', function(assert) {
     var store = container.lookup('store:main');
 
     store.find('legal-page', 'privacy-policy').then(function(record) {
-      service.ajax(record, 'some-rpc').then(function() {
+      service.post(record, 'some-rpc').then(function() {
         assert.ok(false, 'rpc call should fail');
       }, function(jqXHR) {
         var rejection = jqXHR.responseJSON;

+ 19 - 15
misago/emberapp/tests/acceptance/forgotten-password-test.js

@@ -45,7 +45,7 @@ test('request password change link with invalid e-mail', function(assert) {
 
   var message = 'Entered e-mail is invalid.';
   Ember.$.mockjax({
-    url: '/api/change-password/send-link/',
+    url: '/api/auth/send-password-form/',
     status: 400,
     responseText: {
       'detail': message,
@@ -68,7 +68,7 @@ test('request password change link with non-existing e-mail', function(assert) {
 
   var message = 'No user with this e-mail exists.';
   Ember.$.mockjax({
-    url: '/api/change-password/send-link/',
+    url: '/api/auth/send-password-form/',
     status: 400,
     responseText: {
       'detail': message,
@@ -91,7 +91,7 @@ test('request password change link with user-activated account', function(assert
 
   var message = 'You have to activate your account before you will be able to sign in.';
   Ember.$.mockjax({
-    url: '/api/change-password/send-link/',
+    url: '/api/auth/send-password-form/',
     status: 400,
     responseText: {
       'detail': message,
@@ -114,7 +114,7 @@ test('request password change link with admin-activated account', function(asser
 
   var message = 'Your account has to be activated by Administrator before you will be able to sign in.';
   Ember.$.mockjax({
-    url: '/api/change-password/send-link/',
+    url: '/api/auth/send-password-form/',
     status: 400,
     responseText: {
       'detail': message,
@@ -136,7 +136,7 @@ test('request password change link with banned account', function(assert) {
   assert.expect(2);
 
   Ember.$.mockjax({
-    url: '/api/change-password/send-link/',
+    url: '/api/auth/send-password-form/',
     status: 400,
     responseText: {
       'detail': {
@@ -167,7 +167,7 @@ test('request password change link', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/change-password/send-link/',
+    url: '/api/auth/send-password-form/',
     status: 200,
     responseText: {
       'username': 'BobBoberson',
@@ -190,8 +190,8 @@ test('invalid token is handled', function(assert) {
 
   var message = 'Token was rejected.';
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/validate-token/',
-    status: 404,
+    url: '/api/auth/change-password/1/token/',
+    status: 400,
     responseText: {
       'detail': message
     }
@@ -210,7 +210,7 @@ test('permission denied is handled', function(assert) {
 
   var message = 'Token was rejected.';
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/validate-token/',
+    url: '/api/auth/change-password/1/token/',
     status: 403,
     responseText: {
       'detail': message
@@ -231,7 +231,7 @@ test('token is validated', function(assert) {
   assert.expect(1);
 
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/validate-token/',
+    url: '/api/auth/change-password/1/token/',
     status: 200,
     responseText: {
       'user_id': 1,
@@ -251,7 +251,7 @@ test('no new password is entered', function(assert) {
   assert.expect(2);
 
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/validate-token/',
+    url: '/api/auth/change-password/1/token/',
     status: 200,
     responseText: {
       'user_id': 1,
@@ -272,7 +272,8 @@ test('new password is invalid', function(assert) {
   assert.expect(2);
 
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/validate-token/',
+    url: '/api/auth/change-password/1/token/',
+    type: 'GET',
     status: 200,
     responseText: {
       'user_id': 1,
@@ -282,7 +283,8 @@ test('new password is invalid', function(assert) {
 
   var message = 'Entered password is not allowed.';
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/',
+    url: '/api/auth/change-password/1/token/',
+    type: 'POST',
     status: 400,
     responseText: {
       'detail': message
@@ -303,7 +305,8 @@ test('new password is accepted', function(assert) {
   assert.expect(3);
 
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/validate-token/',
+    url: '/api/auth/change-password/1/token/',
+    type: 'GET',
     status: 200,
     responseText: {
       'user_id': 1,
@@ -312,7 +315,8 @@ test('new password is accepted', function(assert) {
   });
 
   Ember.$.mockjax({
-    url: '/api/change-password/1/token/',
+    url: '/api/auth/change-password/1/token/',
+    type: 'POST',
     status: 200,
     responseText: {'detail': 'ok'}
   });