Skip to content
Snippets Groups Projects
Verified Commit f4992993 authored by Dominik Frantisek Bucik's avatar Dominik Frantisek Bucik
Browse files

refactor: :bulb: Remove unused UI - dynreg

parent 399240a7
No related branches found
No related tags found
1 merge request!401feat: 🎸 token, introspect and revocation endpoint auth methods
......@@ -28,7 +28,6 @@
<value>resources/js/grant.js</value>
<value>resources/js/scope.js</value>
<value>resources/js/whitelist.js</value>
<value>resources/js/dynreg.js</value>
<value>resources/js/rsreg.js</value>
<value>resources/js/token.js</value>
<value>resources/js/blacklist.js</value>
......
/*******************************************************************************
* Copyright 2018 The MIT Internet Trust Consortium
*
* Portions copyright 2011-2013 The MITRE Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
var DynRegClient = Backbone.Model.extend({
idAttribute: "client_id",
defaults: {
client_id: null,
client_secret: null,
redirect_uris: [],
client_name: null,
client_uri: null,
contacts: [],
tos_uri: null,
token_endpoint_auth_method: null,
introspection_endpoint_auth_method: null,
revocation_endpoint_auth_method: null,
device_endpoint_auth_method: null,
scope: null,
grant_types: [],
response_types: [],
policy_uri: null,
jwks_uri: null,
jwks: null,
jwksType: "URI",
application_type: null,
sector_identifier_uri: null,
subject_type: null,
request_object_signing_alg: null,
userinfo_signed_response_alg: null,
userinfo_encrypted_response_alg: null,
userinfo_encrypted_response_enc: null,
id_token_signed_response_alg: null,
id_token_encrypted_response_alg: null,
id_token_encrypted_response_enc: null,
default_max_age: null,
require_auth_time: false,
default_acr_values: null,
initiate_login_uri: null,
post_logout_redirect_uris: null,
claims_redirect_uris: [],
request_uris: [],
software_statement: null,
software_id: null,
software_version: null,
code_challenge_method: null,
registration_access_token: null,
registration_client_uri: null,
},
sync: function (method, model, options) {
if (model.get("registration_access_token")) {
var headers = options.headers ? options.headers : {};
headers["Authorization"] =
"Bearer " + model.get("registration_access_token");
options.headers = headers;
}
return this.constructor.__super__.sync(method, model, options);
},
urlRoot: "register",
});
var DynRegRootView = Backbone.View.extend({
tagName: "span",
initialize: function (options) {
this.options = options;
},
events: {
"click #newreg": "newReg",
"click #editreg": "editReg",
},
load: function (callback) {
if (this.options.systemScopeList.isFetched) {
callback();
return;
}
$("#loadingbox").sheet("show");
$("#loading").html(
'<span class="label" id="loading-scopes">' +
$.t("common.scopes") +
"</span> ",
);
$.when(
this.options.systemScopeList.fetchIfNeeded({
success: function (e) {
$("#loading-scopes").addClass("label-success");
},
error: app.errorHandlerView.handleError(),
}),
).done(function () {
$("#loadingbox").sheet("hide");
callback();
});
},
render: function () {
$(this.el).html($("#tmpl-dynreg").html());
$(this.el).i18n();
return this;
},
newReg: function (e) {
e.preventDefault();
this.remove();
app.navigate("dev/dynreg/new", {
trigger: true,
});
},
editReg: function (e) {
e.preventDefault();
var clientId = $("#clientId").val();
var token = $("#regtoken").val();
var client = new DynRegClient({
client_id: clientId,
registration_access_token: token,
});
var self = this;
client.fetch({
success: function () {
var userInfo = getUserInfo();
var contacts = client.get("contacts");
if (
userInfo != null &&
userInfo.email != null &&
!_.contains(contacts, userInfo.email)
) {
contacts.push(userInfo.email);
}
client.set(
{
contacts: contacts,
},
{
silent: true,
},
);
if (client.get("jwks")) {
client.set(
{
jwksType: "VAL",
},
{
silent: true,
},
);
} else {
client.set(
{
jwksType: "URI",
},
{
silent: true,
},
);
}
var view = new DynRegEditView({
model: client,
systemScopeList: app.systemScopeList,
});
view.load(function () {
$("#content").html(view.render().el);
view.delegateEvents();
setPageTitle($.t("dynreg.edit-dynamically-registered"));
app.navigate("dev/dynreg/edit", {
trigger: true,
});
self.remove();
});
},
error: app.errorHandlerView.handleError({
message: $.t("dynreg.invalid-access-token"),
}),
});
},
});
var DynRegEditView = Backbone.View.extend({
tagName: "span",
initialize: function (options) {
this.options = options;
if (!this.template) {
this.template = _.template($("#tmpl-dynreg-client-form").html());
}
this.redirectUrisCollection = new Backbone.Collection();
this.scopeCollection = new Backbone.Collection();
this.contactsCollection = new Backbone.Collection();
this.defaultAcrValuesCollection = new Backbone.Collection();
this.requestUrisCollection = new Backbone.Collection();
this.resourceIdsCollection = new Backbone.Collection();
this.postLogoutRedirectUrisCollection = new Backbone.Collection();
this.claimsRedirectUrisCollection = new Backbone.Collection();
this.listWidgetViews = [];
},
load: function (callback) {
if (this.options.systemScopeList.isFetched) {
callback();
return;
}
$("#loadingbox").sheet("show");
$("#loading").html(
'<span class="label" id="loading-scopes">' +
$.t("common.scopes") +
"</span> ",
);
$.when(
this.options.systemScopeList.fetchIfNeeded({
success: function (e) {
$("#loading-scopes").addClass("label-success");
},
error: app.errorHandlerView.handleError(),
}),
).done(function () {
$("#loadingbox").sheet("hide");
callback();
});
},
events: {
"click .btn-save": "saveClient",
"click .btn-cancel": "cancel",
"click .btn-delete": "deleteClient",
"change #jwkSelector input:radio": "toggleJWKSetType",
},
cancel: function (e) {
e.preventDefault();
app.navigate("dev/dynreg", {
trigger: true,
});
},
deleteClient: function (e) {
e.preventDefault();
if (confirm($.t("client.client-table.confirm"))) {
var self = this;
this.model.destroy({
dataType: false,
processData: false,
success: function () {
self.remove();
app.navigate("dev/dynreg", {
trigger: true,
});
},
error: app.errorHandlerView.handleError({
log: "An error occurred when deleting a client",
}),
});
}
return false;
},
/**
* Set up the form based on the JWK Set selector
*/
toggleJWKSetType: function () {
var jwkSelector = $("#jwkSelector input:radio", this.el)
.filter(":checked")
.val();
if (jwkSelector == "URI") {
$("#jwksUri", this.el).show();
$("#jwks", this.el).hide();
} else if (jwkSelector == "VAL") {
$("#jwksUri", this.el).hide();
$("#jwks", this.el).show();
} else {
$("#jwksUri", this.el).hide();
$("#jwks", this.el).hide();
}
},
disableUnsupportedJOSEItems: function (serverSupported, query) {
var supported = ["default"];
if (serverSupported) {
supported = _.union(supported, serverSupported);
}
$(query, this.$el).each(function (idx) {
if (_.contains(supported, $(this).val())) {
$(this).prop("disabled", false);
} else {
$(this).prop("disabled", true);
}
});
},
// returns "null" if given the value "default" as a string,
// otherwise returns input value. useful for parsing the JOSE
// algorithm dropdowns
defaultToNull: function (value) {
if (value == "default") {
return null;
} else {
return value;
}
},
// returns "null" if the given value is falsy
emptyToNull: function (value) {
if (value) {
return value;
} else {
return null;
}
},
// maps from a form-friendly name to the real grant parameter name
grantMap: {
authorization_code: "authorization_code",
password: "password",
implicit: "implicit",
client_credentials: "client_credentials",
redelegate: "urn:ietf:params:oauth:grant_type:redelegate",
refresh_token: "refresh_token",
},
// maps from a form-friendly name to the real response type
// parameter name
responseMap: {
code: "code",
token: "token",
idtoken: "id_token",
"token-idtoken": "token id_token",
"code-idtoken": "code id_token",
"code-token": "code token",
"code-token-idtoken": "code token id_token",
},
saveClient: function (e) {
e.preventDefault();
$(".control-group").removeClass("error");
// sync any leftover collection items
_.each(this.listWidgetViews, function (v) {
v.addItem($.Event("click"));
});
// build the scope object
var scopes = this.scopeCollection.pluck("item").join(" ");
// build the grant type object
var grantTypes = [];
$.each(this.grantMap, function (index, type) {
if ($("#grantTypes-" + index).is(":checked")) {
grantTypes.push(type);
}
});
// build the response type object
var responseTypes = [];
$.each(this.responseMap, function (index, type) {
if ($("#responseTypes-" + index).is(":checked")) {
responseTypes.push(type);
}
});
var contacts = this.contactsCollection.pluck("item");
var userInfo = getUserInfo();
if (userInfo && userInfo.email) {
if (!_.contains(contacts, userInfo.email)) {
contacts.push(userInfo.email);
}
}
// make sure that the subject identifier is consistent with the
// redirect URIs
var subjectType = $("#subjectType input").filter(":checked").val();
var redirectUris = this.redirectUrisCollection.pluck("item");
var sectorIdentifierUri = $("#sectorIdentifierUri input").val();
if (
subjectType == "PAIRWISE" &&
redirectUris.length > 1 &&
sectorIdentifierUri == ""
) {
// Display an alert with an error message
app.errorHandlerView.showErrorMessage(
$.t("client.client-form.error.consistency"),
$.t("client.client-form.error.pairwise-sector"),
);
return false;
}
// process the JWKS
var jwksUri = null;
var jwks = null;
var jwkSelector = $("#jwkSelector input:radio", this.el)
.filter(":checked")
.val();
if (jwkSelector == "URI") {
jwksUri = $("#jwksUri input").val();
jwks = null;
} else if (jwkSelector == "VAL") {
jwksUri = null;
try {
jwks = JSON.parse($("#jwks textarea").val());
} catch (e) {
console.log("An error occurred when parsing the JWK Set");
app.errorHandlerView.showErrorMessage(
$.t("client.client-form.error.jwk-set"),
$.t("client.client-form.error.jwk-set-parse"),
);
return false;
}
} else {
jwksUri = null;
jwks = null;
}
var attrs = {
client_name: this.emptyToNull($("#clientName input").val()),
redirect_uris: redirectUris,
grant_types: grantTypes,
scope: scopes,
client_secret: null, // never send a client secret
tos_uri: this.emptyToNull($("#tosUri input").val()),
policy_uri: this.emptyToNull($("#policyUri input").val()),
client_uri: this.emptyToNull($("#clientUri input").val()),
application_type: $("#applicationType input").filter(":checked").val(),
jwks_uri: jwksUri,
jwks: jwks,
subject_type: subjectType,
software_statement: this.emptyToNull(
$("#softwareStatement textarea").val(),
),
softwareId: this.emptyToNull($("#softwareId input").val()),
softwareVersion: this.emptyToNull($("#softwareVersion input").val()),
token_endpoint_auth_method: $("#tokenEndpointAuthMethod input")
.filter(":checked")
.val(),
introspection_endpoint_auth_method: $(
"#introspectionEndpointAuthMethod input",
)
.filter(":checked")
.val(),
revocation_endpoint_auth_method: $("#revocationEndpointAuthMethod input")
.filter(":checked")
.val(),
device_endpoint_auth_method: $("#deviceEndpointAuthMethod input")
.filter(":checked")
.val(),
response_types: responseTypes,
sector_identifier_uri: sectorIdentifierUri,
initiate_login_uri: this.emptyToNull($("#initiateLoginUri input").val()),
post_logout_redirect_uris:
this.postLogoutRedirectUrisCollection.pluck("item"),
claims_redirect_uris: this.claimsRedirectUrisCollection.pluck("item"),
require_auth_time: $("#requireAuthTime input").is(":checked"),
default_max_age: parseInt($("#defaultMaxAge input").val()),
contacts: contacts,
request_uris: this.requestUrisCollection.pluck("item"),
resource_ids: this.resourceIdsCollection.pluck("item"),
default_acr_values: this.defaultAcrValuesCollection.pluck("item"),
request_object_signing_alg: this.defaultToNull(
$("#requestObjectSigningAlg select").val(),
),
userinfo_signed_response_alg: this.defaultToNull(
$("#userInfoSignedResponseAlg select").val(),
),
userinfo_encrypted_response_alg: this.defaultToNull(
$("#userInfoEncryptedResponseAlg select").val(),
),
userinfo_encrypted_response_enc: this.defaultToNull(
$("#userInfoEncryptedResponseEnc select").val(),
),
id_token_signed_response_alg: this.defaultToNull(
$("#idTokenSignedResponseAlg select").val(),
),
id_token_encrypted_response_alg: this.defaultToNull(
$("#idTokenEncryptedResponseAlg select").val(),
),
id_token_encrypted_response_enc: this.defaultToNull(
$("#idTokenEncryptedResponseEnc select").val(),
),
token_endpoint_auth_signing_alg: this.defaultToNull(
$("#tokenEndpointAuthSigningAlg select").val(),
),
code_challenge_method: this.defaultToNull(
$("#codeChallengeMethod select").val(),
),
};
// set all empty strings to nulls
for (var key in attrs) {
if (attrs[key] === "") {
attrs[key] = null;
}
}
var _self = this;
this.model.save(attrs, {
success: function () {
// switch to an "edit" view
app.navigate("dev/dynreg/edit", {
trigger: true,
});
_self.remove();
var userInfo = getUserInfo();
var contacts = _self.model.get("contacts");
if (
userInfo != null &&
userInfo.email != null &&
!_.contains(contacts, userInfo.email)
) {
contacts.push(userInfo.email);
}
_self.model.set(
{
contacts: contacts,
},
{
silent: true,
},
);
if (_self.model.get("jwks")) {
_self.model.set(
{
jwksType: "VAL",
},
{
silent: true,
},
);
} else {
_self.model.set(
{
jwksType: "URI",
},
{
silent: true,
},
);
}
var view = new DynRegEditView({
model: _self.model,
systemScopeList: _self.options.systemScopeList,
});
view.load(function () {
// reload
$("#content").html(view.render().el);
view.delegateEvents();
});
},
error: app.errorHandlerView.handleError({
log: "An error occurred when saving a client",
}),
});
return false;
},
render: function () {
var data = {
client: this.model.toJSON(),
userInfo: getUserInfo(),
heartMode: heartMode,
};
$(this.el).html(this.template(data));
this.listWidgetViews = [];
var _self = this;
// build and bind registered redirect URI collection and view
_.each(this.model.get("redirect_uris"), function (redirectUri) {
_self.redirectUrisCollection.add(
new URIModel({
item: redirectUri,
}),
);
});
var redirectUriView = new ListWidgetView({
type: "uri",
placeholder: "https://",
helpBlockText: $.t("client.client-form.redirect-uris-help"),
collection: this.redirectUrisCollection,
});
$("#redirectUris .controls", this.el).html(redirectUriView.render().el);
this.listWidgetViews.push(redirectUriView);
// build and bind scopes
var scopes = this.model.get("scope");
var scopeSet = scopes ? scopes.split(" ") : [];
_.each(scopeSet, function (scope) {
_self.scopeCollection.add(
new Backbone.Model({
item: scope,
}),
);
});
var scopeView = new ListWidgetView({
placeholder: $.t("client.client-form.scope-placeholder"),
autocomplete: _.uniq(
_.flatten(
this.options.systemScopeList.unrestrictedScopes().pluck("value"),
),
),
helpBlockText: $.t("client.client-form.scope-help"),
collection: this.scopeCollection,
});
$("#scope .controls", this.el).html(scopeView.render().el);
this.listWidgetViews.push(scopeView);
// build and bind contacts
_.each(this.model.get("contacts"), function (contact) {
_self.contactsCollection.add(
new Backbone.Model({
item: contact,
}),
);
});
var contactView = new ListWidgetView({
placeholder: $.t("client.client-form.contacts-placeholder"),
helpBlockText: $.t("client.client-form.contacts-help"),
collection: this.contactsCollection,
});
$("#contacts .controls div", this.el).html(contactView.render().el);
this.listWidgetViews.push(contactView);
// build and bind post-logout redirect URIs
_.each(
this.model.get("post_logout_redirect_uris"),
function (postLogoutRedirectUri) {
_self.postLogoutRedirectUrisCollection.add(
new URIModel({
item: postLogoutRedirectUri,
}),
);
},
);
var postLogoutRedirectUrisView = new ListWidgetView({
type: "uri",
placeholder: "https://",
helpBlockText: $.t("client.client-form.post-logout-help"),
collection: this.postLogoutRedirectUrisCollection,
});
$("#postLogoutRedirectUris .controls", this.el).html(
postLogoutRedirectUrisView.render().el,
);
this.listWidgetViews.push(postLogoutRedirectUrisView);
// build and bind claims redirect URIs
_.each(this.model.get("claimsRedirectUris"), function (claimsRedirectUri) {
_self.claimsRedirectUrisCollection.add(
new URIModel({
item: claimsRedirectUri,
}),
);
});
var claimsRedirectUrisView = new ListWidgetView({
type: "uri",
placeholder: "https://",
helpBlockText: $.t("client.client-form.claims-redirect-uris-help"),
collection: this.claimsRedirectUrisCollection,
});
$("#claimsRedirectUris .controls", this.el).html(
claimsRedirectUrisView.render().el,
);
this.listWidgetViews.push(claimsRedirectUrisView);
// build and bind request URIs
_.each(this.model.get("request_uris"), function (requestUri) {
_self.requestUrisCollection.add(
new URIModel({
item: requestUri,
}),
);
});
var requestUriView = new ListWidgetView({
type: "uri",
placeholder: "https://",
helpBlockText: $.t("client.client-form.request-uri-help"),
collection: this.requestUrisCollection,
});
$("#requestUris .controls", this.el).html(requestUriView.render().el);
this.listWidgetViews.push(requestUriView);
// build and bind resource IDs
_.each(this.model.get("resource_ids"), function (resource) {
_self.resourceIdsCollection.add(
new Backbone.Model({
item: resource,
}),
);
});
var resourceIdsView = new ListWidgetView({
placeholder: $.t("client.client-form.resource-ids-placeholder"),
helpBlockText: $.t("client.client-form.resource-ids-help"),
collection: this.resourceIdsCollection,
});
$("#resourceIds .controls div", this.el).html(resourceIdsView.render().el);
this.listWidgetViews.push(resourceIdsView);
// build and bind default ACR values
_.each(this.model.get("default_acr_values"), function (defaultAcrValue) {
_self.defaultAcrValuesCollection.add(
new Backbone.Model({
item: defaultAcrValue,
}),
);
});
var defaultAcrView = new ListWidgetView({
placeholder: $.t("client.client-form.acr-values-placeholder"),
// TODO: autocomplete from spec
helpBlockText: $.t("client.client-form.acr-values-help"),
collection: this.defaultAcrValuesCollection,
});
$("#defaultAcrValues .controls", this.el).html(defaultAcrView.render().el);
this.listWidgetViews.push(defaultAcrView);
this.toggleJWKSetType();
// disable unsupported JOSE algorithms
this.disableUnsupportedJOSEItems(
app.serverConfiguration.request_object_signing_alg_values_supported,
"#requestObjectSigningAlg option",
);
this.disableUnsupportedJOSEItems(
app.serverConfiguration.userinfo_signing_alg_values_supported,
"#userInfoSignedResponseAlg option",
);
this.disableUnsupportedJOSEItems(
app.serverConfiguration.userinfo_encryption_alg_values_supported,
"#userInfoEncryptedResponseAlg option",
);
this.disableUnsupportedJOSEItems(
app.serverConfiguration.userinfo_encryption_enc_values_supported,
"#userInfoEncryptedResponseEnc option",
);
this.disableUnsupportedJOSEItems(
app.serverConfiguration.id_token_signing_alg_values_supported,
"#idTokenSignedResponseAlg option",
);
this.disableUnsupportedJOSEItems(
app.serverConfiguration.id_token_encryption_alg_values_supported,
"#idTokenEncryptedResponseAlg option",
);
this.disableUnsupportedJOSEItems(
app.serverConfiguration.id_token_encryption_enc_values_supported,
"#idTokenEncryptedResponseEnc option",
);
this.disableUnsupportedJOSEItems(
app.serverConfiguration.token_endpoint_auth_signing_alg_values_supported,
"#tokenEndpointAuthSigningAlg option",
);
this.$(".nyi").clickover({
placement: "right",
title: $.t("common.not-yet-implemented"),
content: $.t("common.not-yet-implemented-content"),
});
$(this.el).i18n();
return this;
},
});
ui.routes.push({
path: "dev/dynreg",
name: "dynReg",
callback: function () {
this.breadCrumbView.collection.reset();
this.breadCrumbView.collection.add([
{
text: $.t("admin.home"),
href: "",
},
{
text: $.t("admin.self-service-client"),
href: "manage/#dev/dynreg",
},
]);
var view = new DynRegRootView({
systemScopeList: this.systemScopeList,
});
this.updateSidebar("dev/dynreg");
view.load(function () {
$("#content").html(view.render().el);
setPageTitle($.t("admin.self-service-client"));
});
},
});
ui.routes.push({
path: "dev/dynreg/new",
name: "newDynReg",
callback: function () {
this.breadCrumbView.collection.reset();
this.breadCrumbView.collection.add([
{
text: $.t("admin.home"),
href: "",
},
{
text: $.t("admin.self-service-client"),
href: "manage/#dev/dynreg",
},
{
text: $.t("dynreg.new-client"),
href: "manage/#dev/dynreg/new",
},
]);
this.updateSidebar("dev/dynreg");
var client = new DynRegClient();
var view = new DynRegEditView({
model: client,
systemScopeList: this.systemScopeList,
});
view.load(function () {
var userInfo = getUserInfo();
var contacts = [];
if (userInfo != null && userInfo.email != null) {
contacts.push(userInfo.email);
}
if (heartMode) {
client.set(
{
require_auth_time: true,
default_max_age: 60000,
scope: _.uniq(
_.flatten(
app.systemScopeList.defaultUnrestrictedScopes().pluck("value"),
),
).join(" "),
token_endpoint_auth_method: "private_key_jwt",
grant_types: ["authorization_code"],
response_types: ["code"],
subject_type: "public",
contacts: contacts,
},
{
silent: true,
},
);
} else {
client.set(
{
require_auth_time: true,
default_max_age: 60000,
scope: _.uniq(
_.flatten(
app.systemScopeList.defaultUnrestrictedScopes().pluck("value"),
),
).join(" "),
token_endpoint_auth_method: "client_secret_basic",
introspection_endpoint_auth_method: "client_secret_basic",
revocation_endpoint_auth_method: "client_secret_basic",
device_endpoint_auth_method: "client_secret_basic",
grant_types: ["authorization_code"],
response_types: ["code"],
subject_type: "public",
contacts: contacts,
},
{
silent: true,
},
);
}
$("#content").html(view.render().el);
view.delegateEvents();
setPageTitle($.t("dynreg.new-client"));
});
},
});
ui.routes.push({
path: "dev/dynreg/edit",
name: "editDynReg",
callback: function () {
this.breadCrumbView.collection.reset();
this.breadCrumbView.collection.add([
{
text: $.t("admin.home"),
href: "",
},
{
text: $.t("admin.self-service-client"),
href: "manage/#dev/dynreg",
},
{
text: $.t("dynreg.edit-existing"),
href: "manage/#dev/dynreg/edit",
},
]);
this.updateSidebar("dev/dynreg");
setPageTitle($.t("dynreg.edit-existing"));
// note that this doesn't actually load the client, that's supposed to
// happen elsewhere...
},
});
ui.templates.push("resources/template/dynreg.html");
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment