WIP authorizationDecision
This commit is contained in:
parent
23ea5046bb
commit
9f923b5f65
|
@ -228,6 +228,201 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
, isIframe: function isIframe () {
|
||||||
|
try {
|
||||||
|
return window.self !== window.top;
|
||||||
|
} catch (e) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, parseUrl: function (url) {
|
||||||
|
var parser = document.createElement('a');
|
||||||
|
parser.href = url;
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
, isRedirectHostSafe: function (referrerUrl, redirectUrl) {
|
||||||
|
var src = browser.parseUrl(referrerUrl);
|
||||||
|
var dst = browser.parseUrl(redirectUrl);
|
||||||
|
|
||||||
|
// TODO how should we handle subdomains?
|
||||||
|
// It should be safe for api.example.com to redirect to example.com
|
||||||
|
// But it may not be safe for to example.com to redirect to aj.example.com
|
||||||
|
// It is also probably not safe for sally.example.com to redirect to john.example.com
|
||||||
|
// The client should have a list of allowed URLs to choose from and perhaps a wildcard will do
|
||||||
|
//
|
||||||
|
// api.example.com.evil.com SHOULD NOT match example.com
|
||||||
|
return dst.hostname !== src.hostname;
|
||||||
|
}
|
||||||
|
, checkRedirect: function (client, query) {
|
||||||
|
console.warn("[security] URL path checking not yet implemented");
|
||||||
|
|
||||||
|
var clientUrl = OAUTH3.core.normalizeUrl(client.url);
|
||||||
|
var redirectUrl = OAUTH3.core.normalizeUrl(query.redirect_uri);
|
||||||
|
|
||||||
|
// General rule:
|
||||||
|
// I can callback to a shorter domain (fewer subs) or a shorter path (on the same domain)
|
||||||
|
// but not a longer (more subs) or different domain or a longer path (on the same domain)
|
||||||
|
|
||||||
|
|
||||||
|
// We can callback to an explicitly listed domain (TODO and path)
|
||||||
|
if (browser.isRedirectHostSafe(clientUrl, redirectUrl)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
, redirect: function (redirect) {
|
||||||
|
if (parser.search) {
|
||||||
|
parser.search += '&';
|
||||||
|
} else {
|
||||||
|
parser.search += '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.search += 'error=E_NO_SESSION';
|
||||||
|
redirectUri = parser.href;
|
||||||
|
|
||||||
|
window.location.href = redirectUri;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
, hackFormSubmit: function (opts) {
|
||||||
|
opts = opts || {};
|
||||||
|
scope.authorizationDecisionUri = DaplieApiConfig.providerUri + '/api/org.oauth3.provider/authorization_decision';
|
||||||
|
scope.updateScope();
|
||||||
|
|
||||||
|
var redirectUri = scope.appQuery.redirect_uri.replace(/^https?:\/\//i, 'https://');
|
||||||
|
var separator;
|
||||||
|
|
||||||
|
// TODO check that we appropriately use '#' for implicit and '?' for code
|
||||||
|
// (server-side) in an OAuth2 backwards-compatible way
|
||||||
|
if ('token' === scope.appQuery.response_type) {
|
||||||
|
separator = '#';
|
||||||
|
}
|
||||||
|
else if ('code' === scope.appQuery.response_type) {
|
||||||
|
separator = '?';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
separator = '#';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scope.pendingScope.length && !opts.allow) {
|
||||||
|
redirectUri += separator + Oauth3.querystringify({
|
||||||
|
error: 'access_denied'
|
||||||
|
, error_description: 'None of the permissions were accepted'
|
||||||
|
, error_uri: 'https://oauth3.org/docs/errors#access_denied'
|
||||||
|
, state: scope.appQuery.state
|
||||||
|
});
|
||||||
|
$window.location.href = redirectUri;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO move to Oauth3? or not?
|
||||||
|
// this could be implementation-specific,
|
||||||
|
// but it may still be nice to provide it as de-facto
|
||||||
|
var url = DaplieApiConfig.apiBaseUri + '/api/org.oauth3.provider/grants/:client_id/:account_id'
|
||||||
|
.replace(/:client_id/g, scope.appQuery.client_id || scope.appQuery.client_uri)
|
||||||
|
.replace(/:account_id/g, scope.selectedAccountId)
|
||||||
|
;
|
||||||
|
|
||||||
|
var account = scope.sessionAccount;
|
||||||
|
var session = { accessToken: account.token, refreshToken: account.refreshToken };
|
||||||
|
var preq = {
|
||||||
|
url: url
|
||||||
|
, method: 'POST'
|
||||||
|
, data: {
|
||||||
|
scope: updateAccepted()
|
||||||
|
, response_type: scope.appQuery.response_type
|
||||||
|
, referrer: document.referrer || document.referer || ''
|
||||||
|
, referer: document.referrer || document.referer || ''
|
||||||
|
, tenant_id: scope.appQuery.tenant_id
|
||||||
|
, client_id: scope.appQuery.client_id
|
||||||
|
, client_uri: scope.appQuery.client_uri
|
||||||
|
}
|
||||||
|
, session: session
|
||||||
|
};
|
||||||
|
preq.clientId = preq.appId = DaplieApiConfig.appId || DaplieApiConfig.clientId;
|
||||||
|
preq.clientUri = preq.appUri = DaplieApiConfig.appUri || DaplieApiConfig.clientUri;
|
||||||
|
console.log('hackFormSubmit preq', preq);
|
||||||
|
// TODO need a way to have middleware in Oauth3.request for TherapySession et al
|
||||||
|
return Oauth3.request(preq).then(function (resp) {
|
||||||
|
console.log('[DEBUG] grant code');
|
||||||
|
console.log(resp);
|
||||||
|
|
||||||
|
var err;
|
||||||
|
var data = resp.data || {};
|
||||||
|
|
||||||
|
if (data.error) {
|
||||||
|
err = new Error(data.error.message || data.errorDescription);
|
||||||
|
err.message = data.error.message || data.errorDescription;
|
||||||
|
err.code = resp.data.error.code || resp.data.error;
|
||||||
|
err.uri = 'https://oauth3.org/docs/errors#' + (resp.data.error.code || resp.data.error);
|
||||||
|
return $q.reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(data.code || data.accessToken)) {
|
||||||
|
err = new Error("No grant code");
|
||||||
|
return $q.reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}).then(function (data) {
|
||||||
|
redirectUri += separator + Oauth3.querystringify({
|
||||||
|
state: scope.appQuery.state
|
||||||
|
|
||||||
|
, code: data.code
|
||||||
|
|
||||||
|
, access_token: data.accessToken
|
||||||
|
, expires_at: data.expiresAt
|
||||||
|
, expires_in: data.expiresIn
|
||||||
|
, scope: data.scope
|
||||||
|
|
||||||
|
, refresh_token: data.refreshToken
|
||||||
|
, refresh_expires_at: data.refreshExpiresAt
|
||||||
|
, refresh_expires_in: data.refreshExpiresIn
|
||||||
|
});
|
||||||
|
|
||||||
|
if ('token' === scope.appQuery.response_type) {
|
||||||
|
$window.location.href = redirectUri;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ('code' === scope.appQuery.response_type) {
|
||||||
|
scope.hackFormSubmitHelper(redirectUri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.warn("Grant Code NOT IMPLEMENTED for '" + scope.appQuery.response_type + "'");
|
||||||
|
console.warn(redirectUri);
|
||||||
|
throw new Error("Grant Code NOT IMPLEMENTED for '" + scope.appQuery.response_type + "'");
|
||||||
|
}
|
||||||
|
}, function (err) {
|
||||||
|
redirectUri += separator + Oauth3.querystringify({
|
||||||
|
error: err.code || 'server_error'
|
||||||
|
, error_description: err.message || "Server Error: It's not your fault"
|
||||||
|
, error_uri: err.uri || 'https://oauth3.org/docs/errors#server_error'
|
||||||
|
, state: scope.appQuery.state
|
||||||
|
});
|
||||||
|
|
||||||
|
console.error('Grant Code Error NOT IMPLEMENTED');
|
||||||
|
console.error(err);
|
||||||
|
console.error(redirectUri);
|
||||||
|
//$window.location.href = redirectUri;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
, hackFormSubmitHelper: function (uri) {
|
||||||
|
// TODO de-jQuerify
|
||||||
|
//$window.location.href = redirectUri;
|
||||||
|
//return;
|
||||||
|
|
||||||
|
// the only way to do a POST that redirects the current window
|
||||||
|
window.jQuery('form.js-hack-hidden-form').attr('action', uri);
|
||||||
|
|
||||||
|
// give time for the apply to take place
|
||||||
|
window.setTimeout(function () {
|
||||||
|
window.jQuery('form.js-hack-hidden-form').submit();
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys(browser).forEach(function (key) {
|
Object.keys(browser).forEach(function (key) {
|
||||||
|
|
Loading…
Reference in New Issue