Don't rely on auth exemption for /api/version
It's really not necessary - the only visible change is absense of Fuel version on the login screen. Also, working with cookies logic was removed from Keystone client and moved to User model - it has nothing to do with the client. Change-Id: I0f75b0fdac022c39cbf6f5d4fdeac2d0749b466f Partial-Bug: #1585137
This commit is contained in:
parent
fe8a4b307d
commit
71738018b0
|
@ -75,10 +75,7 @@ function($, _, i18n, Backbone, React, utils, layoutComponents, Coccyx, models, K
|
|||
// this is needed for IE, which caches requests resulting in wrong results (e.g /ostf/testruns/last/1)
|
||||
$.ajaxSetup({cache: false});
|
||||
|
||||
var keystoneClient = this.keystoneClient = new KeystoneClient('/keystone', {
|
||||
cacheTokenFor: 10 * 60 * 1000,
|
||||
tenant: 'admin'
|
||||
});
|
||||
this.overrideBackboneSyncMethod();
|
||||
|
||||
this.version = new models.FuelVersion();
|
||||
this.settings = new models.FuelSettings();
|
||||
|
@ -86,66 +83,26 @@ function($, _, i18n, Backbone, React, utils, layoutComponents, Coccyx, models, K
|
|||
this.statistics = new models.NodesStatistics();
|
||||
this.notifications = new models.Notifications();
|
||||
|
||||
this.version.fetch().then(_.bind(function() {
|
||||
var keystoneClient = this.keystoneClient = new KeystoneClient('/keystone', {
|
||||
cacheTokenFor: 10 * 60 * 1000,
|
||||
token: this.user.get('token'),
|
||||
tenant: 'admin'
|
||||
});
|
||||
|
||||
this.version.fetch().then(null, _.bind(function(response) {
|
||||
if (response.status == 401) {
|
||||
this.version.set({auth_required: true});
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
}, this)).then(_.bind(function() {
|
||||
this.user.set({authenticated: !this.version.get('auth_required')});
|
||||
|
||||
var originalSync = Backbone.sync;
|
||||
Backbone.sync = function(method, model, options) {
|
||||
// our server doesn't support PATCH, so use PUT instead
|
||||
if (method == 'patch') {
|
||||
method = 'update';
|
||||
}
|
||||
if (app.version.get('auth_required') && !this.authExempt) {
|
||||
// FIXME(vkramskikh): manually moving success/error callbacks
|
||||
// to deferred-style callbacks. Everywhere in the code we use
|
||||
// deferreds, but backbone uses success/error callbacks. It
|
||||
// seems there is a bug somewhere: sometimes in long deferred
|
||||
// chains with .then() success/error callbacks are called when
|
||||
// deferred object is not resolved, so 'sync' event is
|
||||
// triggered but dfd.state() still returns 'pending'. This
|
||||
// leads to various bugs here and there.
|
||||
var callbacks = {};
|
||||
|
||||
return keystoneClient.authenticate()
|
||||
.fail(function() {
|
||||
app.logout();
|
||||
})
|
||||
.then(_.bind(function() {
|
||||
options = options || {};
|
||||
options.headers = options.headers || {};
|
||||
options.headers['X-Auth-Token'] = keystoneClient.token;
|
||||
_.each(['success', 'error'], function(callback) {
|
||||
if (options[callback]) {
|
||||
callbacks[callback] = options[callback];
|
||||
delete options[callback];
|
||||
}
|
||||
});
|
||||
return originalSync.call(this, method, model, options);
|
||||
}, this))
|
||||
.done(function() {
|
||||
if (callbacks.success) {
|
||||
callbacks.success.apply(callbacks.success, arguments);
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
if (callbacks.error) {
|
||||
callbacks.error.apply(callbacks.error, arguments);
|
||||
}
|
||||
})
|
||||
.fail(function(response) {
|
||||
if (response && response.status == 401) {
|
||||
app.logout();
|
||||
}
|
||||
});
|
||||
}
|
||||
return originalSync.call(this, method, model, options);
|
||||
};
|
||||
|
||||
if (app.version.get('auth_required')) {
|
||||
_.extend(keystoneClient, this.user.pick('token'));
|
||||
return keystoneClient.authenticate()
|
||||
.done(function() {
|
||||
.then(function() {
|
||||
app.user.set({authenticated: true});
|
||||
return app.version.fetch({cache: true});
|
||||
});
|
||||
}
|
||||
return $.Deferred().resolve();
|
||||
|
@ -156,6 +113,62 @@ function($, _, i18n, Backbone, React, utils, layoutComponents, Coccyx, models, K
|
|||
Backbone.history.start();
|
||||
}, this));
|
||||
},
|
||||
overrideBackboneSyncMethod: function() {
|
||||
var originalSync = Backbone.sync;
|
||||
if (originalSync.patched) return;
|
||||
Backbone.sync = function(method, model, options) {
|
||||
// our server doesn't support PATCH, so use PUT instead
|
||||
if (method == 'patch') {
|
||||
method = 'update';
|
||||
}
|
||||
if (app.version && app.version.get('auth_required')) {
|
||||
// FIXME(vkramskikh): manually moving success/error callbacks
|
||||
// to deferred-style callbacks. Everywhere in the code we use
|
||||
// deferreds, but backbone uses success/error callbacks. It
|
||||
// seems there is a bug somewhere: sometimes in long deferred
|
||||
// chains with .then() success/error callbacks are called when
|
||||
// deferred object is not resolved, so 'sync' event is
|
||||
// triggered but dfd.state() still returns 'pending'. This
|
||||
// leads to various bugs here and there.
|
||||
var callbacks = {};
|
||||
|
||||
return app.keystoneClient.authenticate()
|
||||
.fail(function() {
|
||||
app.logout();
|
||||
})
|
||||
.then(_.bind(function() {
|
||||
app.user.set('token', app.keystoneClient.token);
|
||||
options = options || {};
|
||||
options.headers = options.headers || {};
|
||||
options.headers['X-Auth-Token'] = app.keystoneClient.token;
|
||||
_.each(['success', 'error'], function(callback) {
|
||||
if (options[callback]) {
|
||||
callbacks[callback] = options[callback];
|
||||
delete options[callback];
|
||||
}
|
||||
});
|
||||
return originalSync.call(this, method, model, options);
|
||||
}, this))
|
||||
.done(function() {
|
||||
if (callbacks.success) {
|
||||
callbacks.success.apply(callbacks.success, arguments);
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
if (callbacks.error) {
|
||||
callbacks.error.apply(callbacks.error, arguments);
|
||||
}
|
||||
})
|
||||
.fail(function(response) {
|
||||
if (response && response.status == 401) {
|
||||
app.logout();
|
||||
}
|
||||
});
|
||||
}
|
||||
return originalSync.call(this, method, model, options);
|
||||
};
|
||||
Backbone.sync.patched = true;
|
||||
},
|
||||
renderLayout: function() {
|
||||
this.rootComponent = utils.universalMount(RootComponent, _.pick(this, 'version', 'user', 'statistics', 'notifications'), $('#main-container'));
|
||||
},
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
**/
|
||||
define(['jquery', 'underscore', 'jquery-cookie'], function($, _) {
|
||||
define(['jquery', 'underscore'], function($, _) {
|
||||
'use strict';
|
||||
|
||||
function KeystoneClient(url, options) {
|
||||
|
@ -56,9 +56,6 @@ define(['jquery', 'underscore', 'jquery-cookie'], function($, _) {
|
|||
this.userId = result.access.user.id;
|
||||
this.token = result.access.token.id;
|
||||
this.tokenUpdateTime = new Date();
|
||||
|
||||
$.cookie('token', result.access.token.id);
|
||||
|
||||
return deferred;
|
||||
} catch(e) {
|
||||
return $.Deferred().reject();
|
||||
|
@ -87,9 +84,6 @@ define(['jquery', 'underscore', 'jquery-cookie'], function($, _) {
|
|||
try {
|
||||
this.token = result.access.token.id;
|
||||
this.tokenUpdateTime = new Date();
|
||||
|
||||
$.cookie('token', result.access.token.id);
|
||||
|
||||
return deferred;
|
||||
} catch(e) {
|
||||
return $.Deferred().reject();
|
||||
|
@ -110,8 +104,6 @@ define(['jquery', 'underscore', 'jquery-cookie'], function($, _) {
|
|||
delete this.token;
|
||||
delete this.tokenUpdateTime;
|
||||
|
||||
$.removeCookie('token');
|
||||
|
||||
this.tokenRemoveRequest = $.ajax(this.url + '/v2.0/tokens/' + token, {
|
||||
type: 'DELETE',
|
||||
dataType: 'json',
|
||||
|
|
|
@ -22,6 +22,7 @@ define([
|
|||
'expression',
|
||||
'expression/objects',
|
||||
'jsx!views/custom_controls',
|
||||
'jquery-cookie',
|
||||
'deepModel'
|
||||
], function($, _, i18n, Backbone, utils, Expression, expressionObjects, customControls) {
|
||||
'use strict';
|
||||
|
@ -48,6 +49,7 @@ define([
|
|||
if (this.cacheFor && options && options.cache && this.lastSyncTime && (this.cacheFor > (new Date() - this.lastSyncTime))) {
|
||||
return $.Deferred().resolve();
|
||||
}
|
||||
if (options) delete options.cache;
|
||||
return this._super('fetch', arguments);
|
||||
},
|
||||
sync: function() {
|
||||
|
@ -901,10 +903,10 @@ define([
|
|||
urlRoot: '/api/ostf'
|
||||
});
|
||||
|
||||
models.FuelVersion = BaseModel.extend({
|
||||
models.FuelVersion = BaseModel.extend(cacheMixin).extend({
|
||||
cacheFor: 60 * 1000,
|
||||
constructorName: 'FuelVersion',
|
||||
urlRoot: '/api/version',
|
||||
authExempt: true
|
||||
urlRoot: '/api/version'
|
||||
});
|
||||
|
||||
models.User = BaseModel.extend({
|
||||
|
@ -924,6 +926,14 @@ define([
|
|||
}
|
||||
});
|
||||
}, this);
|
||||
this.on('change:token', function() {
|
||||
var token = this.get('token');
|
||||
if (_.isUndefined(token)) {
|
||||
$.removeCookie('token');
|
||||
} else {
|
||||
$.cookie('token', token);
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -38,12 +38,6 @@ function($, _, i18n, React) {
|
|||
<LoginForm />
|
||||
</div>
|
||||
</div>
|
||||
<div className='login-copyrights'>
|
||||
{_.contains(app.version.get('feature_groups'), 'mirantis') &&
|
||||
<p className='text-center'>{i18n('common.copyright')}</p>
|
||||
}
|
||||
<p className='text-center'>{i18n('common.version')}: {app.version.get('release')}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -64,7 +58,7 @@ function($, _, i18n, React) {
|
|||
username: username,
|
||||
token: keystoneClient.token
|
||||
});
|
||||
return app.settings.fetch({cache: true});
|
||||
return $.when(app.version.fetch({cache: true}), app.settings.fetch({cache: true}));
|
||||
}, this))
|
||||
.done(_.bind(function() {
|
||||
app.navigate('', {trigger: true});
|
||||
|
|
Loading…
Reference in New Issue