From b17a7f43ae9a94592132a0336248631fe5914508 Mon Sep 17 00:00:00 2001
From: Justin Richer <jricher@mit.edu>
Date: Tue, 17 Jan 2017 17:06:04 -0500
Subject: [PATCH] removed structured scopes

---
 .../org/mitre/oauth2/model/SystemScope.java   | 79 +------------------
 .../oauth2/service/SystemScopeService.java    |  7 +-
 .../db/hsql/hsql_database_tables.sql          |  5 +-
 .../resources/db/hsql/loading_temp_tables.sql |  4 +-
 .../src/main/resources/db/hsql/scopes.sql     | 18 ++---
 .../src/main/webapp/WEB-INF/authz-config.xml  |  2 +-
 .../src/main/webapp/WEB-INF/views/approve.jsp |  4 -
 .../resources/js/locale/en/messages.json      |  3 -
 .../src/main/webapp/resources/js/scope.js     | 21 +----
 .../main/webapp/resources/template/scope.html | 13 ---
 .../impl/DefaultSystemScopeService.java       | 41 +---------
 ...peServiceAwareOAuth2RequestValidator.java} |  4 +-
 .../service/impl/MITREidDataService_1_1.java  |  4 +-
 .../service/impl/MITREidDataService_1_2.java  |  4 +-
 .../service/impl/MITREidDataService_1_3.java  |  8 --
 .../token/TofuUserApprovalHandler.java        | 10 +--
 .../impl/TestDefaultSystemScopeService.java   | 54 ++-----------
 .../impl/TestMITREidDataService_1_1.java      | 10 +--
 .../impl/TestMITREidDataService_1_2.java      | 10 +--
 .../impl/TestMITREidDataService_1_3.java      | 10 +--
 .../service/impl/MITREidDataService_1_2.java  |  6 +-
 21 files changed, 39 insertions(+), 278 deletions(-)
 rename openid-connect-server/src/main/java/org/mitre/oauth2/token/{StructuredScopeAwareOAuth2RequestValidator.java => ScopeServiceAwareOAuth2RequestValidator.java} (93%)

diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java b/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java
index 19e6bcec1..f559ab4d1 100644
--- a/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java
+++ b/openid-connect-common/src/main/java/org/mitre/oauth2/model/SystemScope.java
@@ -53,9 +53,6 @@ public class SystemScope {
 	private String icon; // class of the icon to display on the auth page
 	private boolean defaultScope = false; // is this a default scope for newly-registered clients?
 	private boolean restricted = false; // is this scope restricted to admin-only registration access?
-	private boolean structured = false; // is this a default scope for newly-registered clients?
-	private String structuredParamDescription;
-	private String structuredValue;
 
 	/**
 	 * Make a blank system scope with no value
@@ -162,52 +159,6 @@ public class SystemScope {
 		this.restricted = restricted;
 	}
 
-	/**
-	 * @return the isStructured status
-	 */
-	@Basic
-	@Column(name = "structured")
-	public boolean isStructured() {
-		return structured;
-	}
-
-	/**
-	 * @param structured the structured to set
-	 */
-	public void setStructured(boolean structured) {
-		this.structured = structured;
-	}
-
-	@Basic
-	@Column(name = "structured_param_description")
-	public String getStructuredParamDescription() {
-		return structuredParamDescription;
-	}
-
-	/**
-	 * @param isStructured the isStructured to set
-	 */
-	public void setStructuredParamDescription(String d) {
-		this.structuredParamDescription = d;
-	}
-
-
-	/**
-	 * @return the structuredValue
-	 */
-	@Transient // we don't save the value of a system scope separately
-	public String getStructuredValue() {
-		return structuredValue;
-	}
-
-	/**
-	 * @param structuredValue the structuredValue to set
-	 */
-	public void setStructuredValue(String structuredValue) {
-		this.structuredValue = structuredValue;
-	}
-
-
 	/* (non-Javadoc)
 	 * @see java.lang.Object#hashCode()
 	 */
@@ -221,13 +172,6 @@ public class SystemScope {
 		result = prime * result + ((icon == null) ? 0 : icon.hashCode());
 		result = prime * result + ((id == null) ? 0 : id.hashCode());
 		result = prime * result + (restricted ? 1231 : 1237);
-		result = prime * result + (structured ? 1231 : 1237);
-		result = prime
-				* result
-				+ ((structuredParamDescription == null) ? 0
-						: structuredParamDescription.hashCode());
-		result = prime * result
-				+ ((structuredValue == null) ? 0 : structuredValue.hashCode());
 		result = prime * result + ((value == null) ? 0 : value.hashCode());
 		return result;
 	}
@@ -274,24 +218,6 @@ public class SystemScope {
 		if (restricted != other.restricted) {
 			return false;
 		}
-		if (structured != other.structured) {
-			return false;
-		}
-		if (structuredParamDescription == null) {
-			if (other.structuredParamDescription != null) {
-				return false;
-			}
-		} else if (!structuredParamDescription
-				.equals(other.structuredParamDescription)) {
-			return false;
-		}
-		if (structuredValue == null) {
-			if (other.structuredValue != null) {
-				return false;
-			}
-		} else if (!structuredValue.equals(other.structuredValue)) {
-			return false;
-		}
 		if (value == null) {
 			if (other.value != null) {
 				return false;
@@ -309,10 +235,7 @@ public class SystemScope {
 	public String toString() {
 		return "SystemScope [id=" + id + ", value=" + value + ", description="
 				+ description + ", icon=" + icon + ", defaultScope="
-				+ defaultScope + ", restricted=" + restricted + ", structured="
-				+ structured + ", structuredParamDescription="
-				+ structuredParamDescription + ", structuredValue="
-				+ structuredValue + "]";
+				+ defaultScope + ", restricted=" + restricted + "]";
 	}
 
 }
diff --git a/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java b/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java
index 1b4298634..72f171e09 100644
--- a/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java
+++ b/openid-connect-common/src/main/java/org/mitre/oauth2/service/SystemScopeService.java
@@ -96,12 +96,7 @@ public interface SystemScopeService {
 	public Set<String> toStrings(Set<SystemScope> scope);
 
 	/**
-	 * Test whether the scopes in both sets are compatible, with special
-	 * processing for structured scopes. All scopes in "actual" must exist in
-	 * "expected". If a scope in "expected" is structured and has a value, it
-	 * must be matched exactly by its corresponding scope in "actual". If a
-	 * scope in "expected" is structured but has no value, it may be matched by
-	 * a scope with or without a value in "actual".
+	 * Test whether the scopes in both sets are compatible. All scopes in "actual" must exist in "expected".
 	 */
 	public boolean scopesMatch(Set<String> expected, Set<String> actual);
 
diff --git a/openid-connect-server-webapp/src/main/resources/db/hsql/hsql_database_tables.sql b/openid-connect-server-webapp/src/main/resources/db/hsql/hsql_database_tables.sql
index 90bea3092..23493f0ea 100644
--- a/openid-connect-server-webapp/src/main/resources/db/hsql/hsql_database_tables.sql
+++ b/openid-connect-server-webapp/src/main/resources/db/hsql/hsql_database_tables.sql
@@ -10,7 +10,8 @@ CREATE TABLE IF NOT EXISTS access_token (
 	refresh_token_id BIGINT,
 	client_id BIGINT,
 	auth_holder_id BIGINT,
-	approved_site_id BIGINT
+	approved_site_id BIGINT,
+	UNIQUE(token_value)
 );
 
 CREATE TABLE IF NOT EXISTS access_token_permissions (
@@ -235,8 +236,6 @@ CREATE TABLE IF NOT EXISTS system_scope (
 	icon VARCHAR(256),
 	restricted BOOLEAN DEFAULT false NOT NULL,
 	default_scope BOOLEAN DEFAULT false NOT NULL,
-	structured BOOLEAN DEFAULT false NOT NULL,
-	structured_param_description VARCHAR(256),
 	UNIQUE (scope)
 );
 
diff --git a/openid-connect-server-webapp/src/main/resources/db/hsql/loading_temp_tables.sql b/openid-connect-server-webapp/src/main/resources/db/hsql/loading_temp_tables.sql
index 1d3908ed1..37b0092e7 100644
--- a/openid-connect-server-webapp/src/main/resources/db/hsql/loading_temp_tables.sql
+++ b/openid-connect-server-webapp/src/main/resources/db/hsql/loading_temp_tables.sql
@@ -69,7 +69,5 @@ CREATE TEMPORARY TABLE IF NOT EXISTS system_scope_TEMP (
 	description VARCHAR(4096),
 	icon VARCHAR(256),
 	restricted BOOLEAN,
-	default_scope BOOLEAN,
-	structured BOOLEAN,
-	structured_param_description VARCHAR(256)
+	default_scope BOOLEAN
 );
\ No newline at end of file
diff --git a/openid-connect-server-webapp/src/main/resources/db/hsql/scopes.sql b/openid-connect-server-webapp/src/main/resources/db/hsql/scopes.sql
index 27792880f..8e72c88c7 100644
--- a/openid-connect-server-webapp/src/main/resources/db/hsql/scopes.sql
+++ b/openid-connect-server-webapp/src/main/resources/db/hsql/scopes.sql
@@ -10,23 +10,23 @@ START TRANSACTION;
 -- Insert scope information into the temporary tables.
 -- 
 
-INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES
-  ('openid', 'log in using your identity', 'user', false, true, false, null),
-  ('profile', 'basic profile information', 'list-alt', false, true, false, null),
-  ('email', 'email address', 'envelope', false, true, false, null),
-  ('address', 'physical address', 'home', false, true, false, null),
-  ('phone', 'telephone number', 'bell', false, true, false, null),
-  ('offline_access', 'offline access', 'time', false, false, false, null);
+INSERT INTO system_scope_TEMP (scope, description, icon, restricted, default_scope) VALUES
+  ('openid', 'log in using your identity', 'user', false, true),
+  ('profile', 'basic profile information', 'list-alt', false, true),
+  ('email', 'email address', 'envelope', false, true),
+  ('address', 'physical address', 'home', false, true),
+  ('phone', 'telephone number', 'bell', false, true),
+  ('offline_access', 'offline access', 'time', false, false);
   
 --
 -- Merge the temporary scopes safely into the database. This is a two-step process to keep scopes from being created on every startup with a persistent store.
 --
 
 MERGE INTO system_scope
-	USING (SELECT scope, description, icon, restricted, default_scope, structured, structured_param_description FROM system_scope_TEMP) AS vals(scope, description, icon, restricted, default_scope, structured, structured_param_description)
+	USING (SELECT scope, description, icon, restricted, default_scope  FROM system_scope_TEMP) AS vals(scope, description, icon, restricted, default_scope)
 	ON vals.scope = system_scope.scope
 	WHEN NOT MATCHED THEN
-	  INSERT (scope, description, icon, restricted, default_scope, structured, structured_param_description) VALUES(vals.scope, vals.description, vals.icon, vals.restricted, vals.default_scope, vals.structured, vals.structured_param_description);
+	  INSERT (scope, description, icon, restricted, default_scope) VALUES(vals.scope, vals.description, vals.icon, vals.restricted, vals.default_scope);
 
 COMMIT;
 
diff --git a/openid-connect-server-webapp/src/main/webapp/WEB-INF/authz-config.xml b/openid-connect-server-webapp/src/main/webapp/WEB-INF/authz-config.xml
index 9c72fbbc5..a87e4ddb8 100644
--- a/openid-connect-server-webapp/src/main/webapp/WEB-INF/authz-config.xml
+++ b/openid-connect-server-webapp/src/main/webapp/WEB-INF/authz-config.xml
@@ -52,7 +52,7 @@
 
 	<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />
 
-	<bean id="oauthRequestValidator" class="org.mitre.oauth2.token.StructuredScopeAwareOAuth2RequestValidator" />
+	<bean id="oauthRequestValidator" class="org.mitre.oauth2.token.ScopeServiceAwareOAuth2RequestValidator" />
 
 	<!-- Error page handler. -->
 	<mvc:view-controller path="/error" view-name="error" />
diff --git a/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/approve.jsp b/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/approve.jsp
index 1ef03568f..5624208c4 100644
--- a/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/approve.jsp
+++ b/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/approve.jsp
@@ -218,10 +218,6 @@
 									</span>
 								</c:if>
 								
-								<c:if test="${ scope.structured }">
-									<input name="scopeparam_${ fn:escapeXml(scope.value) }" type="text" value="${ fn:escapeXml(scope.structuredValue) }" placeholder="${ fn:escapeXml(scope.structuredParamDescription) }">
-								</c:if>
-								
 							</label>
 
 						</c:forEach>
diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/locale/en/messages.json b/openid-connect-server-webapp/src/main/webapp/resources/js/locale/en/messages.json
index f787e0d54..0722b93a2 100644
--- a/openid-connect-server-webapp/src/main/webapp/resources/js/locale/en/messages.json
+++ b/openid-connect-server-webapp/src/main/webapp/resources/js/locale/en/messages.json
@@ -306,9 +306,6 @@
             "icon": "Icon",
             "new": "New Scope",
             "select-icon": "Select an icon",
-            "structured": "is a structured scope",
-            "structured-help": "Is the scope structured with structured values like <code>base:extension</code>?",
-            "structured-param-help": "Human-readable description of the structured parameter",
             "subject-type": "Subject Type",
             "value": "Scope value",
             "value-help": "Single string with no spaces",
diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js b/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js
index 496155b03..b2d03f8ef 100644
--- a/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js
+++ b/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js
@@ -23,10 +23,7 @@ var SystemScopeModel = Backbone.Model.extend({
 		icon:null,
 		value:null,
 		defaultScope:false,
-		restricted:false,
-		structured:false,
-		structuredParamDescription:null,
-		structuredValue:null
+		restricted:false
 	},
 	
 	urlRoot: 'api/scopes'
@@ -267,8 +264,7 @@ var SystemScopeFormView = Backbone.View.extend({
 	events:{
 		'click .btn-save':'saveScope',
 		'click .btn-cancel': function() {app.navigate('admin/scope', {trigger: true}); },
-		'click .btn-icon':'selectIcon',
-		'change #isStructured input':'toggleStructuredParamDescription'
+		'click .btn-icon':'selectIcon'
 	},
 	
 	load:function(callback) {
@@ -290,14 +286,6 @@ var SystemScopeFormView = Backbone.View.extend({
 		
 	},
 	
-	toggleStructuredParamDescription:function(e) {
-		if ($('#isStructured input', this.el).is(':checked')) {
-			$('#structuredParamDescription', this.el).show();
-		} else {
-			$('#structuredParamDescription', this.el).hide();
-		}
-	},
-	
 	saveScope:function(e) {
     	e.preventDefault();
 		
@@ -313,9 +301,7 @@ var SystemScopeFormView = Backbone.View.extend({
 			description:$('#description textarea').val(),
 			icon:$('#iconDisplay input').val(),
 			defaultScope:$('#defaultScope input').is(':checked'),
-			restricted:$('#restricted input').is(':checked'),
-			structured:$('#isStructured input').is(':checked'),
-			structuredParamDescription:$('#structuredParamDescription input').val()
+			restricted:$('#restricted input').is(':checked')
 		});
 		
 		if (valid) {
@@ -356,7 +342,6 @@ var SystemScopeFormView = Backbone.View.extend({
 			$("#iconSelector .modal-body", this.el).append(this.iconTemplate({items:items}));
 		}, this);
 		
-		this.toggleStructuredParamDescription();
         $(this.el).i18n();
 		return this;
 	}
diff --git a/openid-connect-server-webapp/src/main/webapp/resources/template/scope.html b/openid-connect-server-webapp/src/main/webapp/resources/template/scope.html
index e210bedaa..766dc4323 100644
--- a/openid-connect-server-webapp/src/main/webapp/resources/template/scope.html
+++ b/openid-connect-server-webapp/src/main/webapp/resources/template/scope.html
@@ -155,19 +155,6 @@
 				</div>
 			</div>
 
-			<div class="control-group">
-				<div class="controls" id="isStructured">
-					<label class="checkbox">
-						<input type="checkbox" <%-structured ? 'checked' : '' %>> <span data-i18n="scope.system-scope-form.structured">is a structured scope</span>
-					</label>
-					<p class="help-block" data-i18n="[html]scope.system-scope-form.structured-help">Is the scope structured with structured values like <code>base:extension</code>?</p>
-				</div>
-				<div class="controls" id="structuredParamDescription">
-					<input type="text" value="<%-structuredParamDescription ? structuredParamDescription : '' %>">
-					<p class="help-block" data-i18n="scope.system-scope-form.structured-param-help">Human-readable description of the structured parameter</p>
-				</div>
-			</div>
-
             <div class="well well-small">
                 <button class="btn btn-small btn-save btn-success"><i class="icon-ok-circle icon-white"></i> <span data-i18n="common.save">Save</span></button> &nbsp; 
                 <button class="btn btn-small btn-cancel"><i class="icon-ban-circle"></i> <span data-i18n="common.cancel">Cancel</span></button>
diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java
index 3efd10a21..62734f34c 100644
--- a/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java
+++ b/openid-connect-server/src/main/java/org/mitre/oauth2/service/impl/DefaultSystemScopeService.java
@@ -76,20 +76,11 @@ public class DefaultSystemScopeService implements SystemScopeService {
 			if (Strings.isNullOrEmpty(input)) {
 				return null;
 			} else {
-				List<String> parts = parseStructuredScopeValue(input);
-				String base = parts.get(0); // the first part is the base
 				// get the real scope if it's available
-				SystemScope s = getByValue(base);
+				SystemScope s = getByValue(input);
 				if (s == null) {
 					// make a fake one otherwise
-					s = new SystemScope(base);
-					if (parts.size() > 1) {
-						s.setStructured(true);
-					}
-				}
-
-				if (s.isStructured() && parts.size() > 1) {
-					s.setStructuredValue(parts.get(1));
+					s = new SystemScope(input);
 				}
 
 				return s;
@@ -103,11 +94,7 @@ public class DefaultSystemScopeService implements SystemScopeService {
 			if (input == null) {
 				return null;
 			} else {
-				if (input.isStructured() && !Strings.isNullOrEmpty(input.getStructuredValue())) {
-					return Joiner.on(":").join(input.getValue(), input.getStructuredValue());
-				} else {
-					return input.getValue();
-				}
+				return input.getValue();
 			}
 		}
 	};
@@ -181,11 +168,6 @@ public class DefaultSystemScopeService implements SystemScopeService {
 		}
 	}
 
-	// parse a structured scope string into its components
-	private List<String> parseStructuredScopeValue(String value) {
-		return Lists.newArrayList(Splitter.on(":").split(value));
-	}
-
 	/* (non-Javadoc)
 	 * @see org.mitre.oauth2.service.SystemScopeService#scopesMatch(java.util.Set, java.util.Set)
 	 */
@@ -198,22 +180,7 @@ public class DefaultSystemScopeService implements SystemScopeService {
 		for (SystemScope actScope : act) {
 			// first check to see if there's an exact match
 			if (!ex.contains(actScope)) {
-				// we didn't find an exact match
-				if (actScope.isStructured() && !Strings.isNullOrEmpty(actScope.getStructuredValue())) {
-					// if we didn't get an exact match but the actual scope is structured, we need to check further
-
-					// first, find the "base" scope for this
-					SystemScope base = getByValue(actScope.getValue());
-					if (!ex.contains(base)) {
-						// if the expected doesn't contain the base scope, fail
-						return false;
-					} else {
-						// we did find an exact match, need to check the rest
-					}
-				} else {
-					// the scope wasn't structured, fail now
-					return false;
-				}
+				return false;
 			} else {
 				// if we did find an exact match, we need to check the rest
 			}
diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/token/StructuredScopeAwareOAuth2RequestValidator.java b/openid-connect-server/src/main/java/org/mitre/oauth2/token/ScopeServiceAwareOAuth2RequestValidator.java
similarity index 93%
rename from openid-connect-server/src/main/java/org/mitre/oauth2/token/StructuredScopeAwareOAuth2RequestValidator.java
rename to openid-connect-server/src/main/java/org/mitre/oauth2/token/ScopeServiceAwareOAuth2RequestValidator.java
index b08fda4e7..af4028ad4 100644
--- a/openid-connect-server/src/main/java/org/mitre/oauth2/token/StructuredScopeAwareOAuth2RequestValidator.java
+++ b/openid-connect-server/src/main/java/org/mitre/oauth2/token/ScopeServiceAwareOAuth2RequestValidator.java
@@ -32,12 +32,12 @@ import org.springframework.security.oauth2.provider.TokenRequest;
 /**
  * 
  * Validates the scopes on a request by comparing them against a client's
- * allowed scopes, but allow structured scopes to function.
+ * allowed scopes, but allow custom scopes to function through the system scopes
  * 
  * @author jricher
  * 
  */
-public class StructuredScopeAwareOAuth2RequestValidator implements OAuth2RequestValidator {
+public class ScopeServiceAwareOAuth2RequestValidator implements OAuth2RequestValidator {
 
 	@Autowired
 	private SystemScopeService scopeService;
diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_1.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_1.java
index 7955ded75..237294324 100644
--- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_1.java
+++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_1.java
@@ -817,9 +817,9 @@ public class MITREidDataService_1_1 extends MITREidDataServiceSupport implements
 					} else if (name.equals("defaultScope")) {
 						scope.setDefaultScope(reader.nextBoolean());
 					} else if (name.equals("structured")) {
-						scope.setStructured(reader.nextBoolean());
+						logger.warn("Found a structured scope, ignoring structure");
 					} else if (name.equals("structuredParameter")) {
-						scope.setStructuredParamDescription(reader.nextString());
+						logger.warn("Found a structured scope, ignoring structure");
 					} else if (name.equals("icon")) {
 						scope.setIcon(reader.nextString());
 					} else {
diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
index da28b5d8f..7b0becc76 100644
--- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
+++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
@@ -808,9 +808,9 @@ public class MITREidDataService_1_2 extends MITREidDataServiceSupport implements
 					} else if (name.equals(ICON)) {
 						scope.setIcon(reader.nextString());
 					} else if (name.equals(STRUCTURED)) {
-						scope.setStructured(reader.nextBoolean());
+						logger.warn("Found a structured scope, ignoring structure");
 					} else if (name.equals(STRUCTURED_PARAMETER)) {
-						scope.setStructuredParamDescription(reader.nextString());
+						logger.warn("Found a structured scope, ignoring structure");
 					} else {
 						logger.debug("found unexpected entry");
 						reader.skipValue();
diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_3.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_3.java
index ed0503110..e465175f4 100644
--- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_3.java
+++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_3.java
@@ -80,8 +80,6 @@ import com.nimbusds.jwt.JWTParser;
 public class MITREidDataService_1_3 extends MITREidDataServiceSupport implements MITREidDataService {
 
 	private static final String DEFAULT_SCOPE = "defaultScope";
-	private static final String STRUCTURED_PARAMETER = "structuredParameter";
-	private static final String STRUCTURED = "structured";
 	private static final String RESTRICTED = "restricted";
 	private static final String ICON = "icon";
 	private static final String DYNAMICALLY_REGISTERED = "dynamicallyRegistered";
@@ -525,8 +523,6 @@ public class MITREidDataService_1_3 extends MITREidDataServiceSupport implements
 				writer.name(ICON).value(sysScope.getIcon());
 				writer.name(VALUE).value(sysScope.getValue());
 				writer.name(RESTRICTED).value(sysScope.isRestricted());
-				writer.name(STRUCTURED).value(sysScope.isStructured());
-				writer.name(STRUCTURED_PARAMETER).value(sysScope.getStructuredParamDescription());
 				writer.name(DEFAULT_SCOPE).value(sysScope.isDefaultScope());
 				writer.endObject();
 				logger.debug("Wrote system scope {}", sysScope.getId());
@@ -1180,10 +1176,6 @@ public class MITREidDataService_1_3 extends MITREidDataServiceSupport implements
 						scope.setDefaultScope(reader.nextBoolean());
 					} else if (name.equals(ICON)) {
 						scope.setIcon(reader.nextString());
-					} else if (name.equals(STRUCTURED)) {
-						scope.setStructured(reader.nextBoolean());
-					} else if (name.equals(STRUCTURED_PARAMETER)) {
-						scope.setStructuredParamDescription(reader.nextString());
 					} else {
 						logger.debug("found unexpected entry");
 						reader.skipValue();
diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java
index 91489ba1c..f1319c07c 100644
--- a/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java
+++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/token/TofuUserApprovalHandler.java
@@ -204,15 +204,7 @@ public class TofuUserApprovalHandler implements UserApprovalHandler {
 					//Make sure this scope is allowed for the given client
 					if (systemScopes.scopesMatch(client.getScope(), approveSet)) {
 
-						// If it's structured, assign the user-specified parameter
-						SystemScope systemScope = systemScopes.getByValue(scope);
-						if (systemScope != null && systemScope.isStructured()){
-							String paramValue = approvalParams.get("scopeparam_" + scope);
-							allowedScopes.add(scope + ":"+paramValue);
-							// .. and if it's unstructured, we're all set
-						} else {
-							allowedScopes.add(scope);
-						}
+						allowedScopes.add(scope);
 					}
 
 				}
diff --git a/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultSystemScopeService.java b/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultSystemScopeService.java
index b68082db1..f1c6d6936 100644
--- a/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultSystemScopeService.java
+++ b/openid-connect-server/src/test/java/org/mitre/oauth2/service/impl/TestDefaultSystemScopeService.java
@@ -52,8 +52,6 @@ public class TestDefaultSystemScopeService {
 	private SystemScope defaultScope2;
 	private SystemScope dynScope1;
 	private SystemScope restrictedScope1;
-	private SystemScope structuredScope1;
-	private SystemScope structuredScope1Value;
 
 	private String defaultDynScope1String = "defaultDynScope1";
 	private String defaultDynScope2String = "defaultDynScope2";
@@ -61,8 +59,6 @@ public class TestDefaultSystemScopeService {
 	private String defaultScope2String = "defaultScope2";
 	private String dynScope1String = "dynScope1";
 	private String restrictedScope1String = "restrictedScope1";
-	private String structuredScope1String = "structuredScope1";
-	private String structuredValue = "structuredValue";
 
 	private Set<SystemScope> allScopes;
 	private Set<String> allScopeStrings;
@@ -105,20 +101,11 @@ public class TestDefaultSystemScopeService {
 		restrictedScope1.setRestricted(true);
 
 
-		// structuredScope1 : structured scope
-		structuredScope1 = new SystemScope(structuredScope1String);
-		structuredScope1.setStructured(true);
+		allScopes = Sets.newHashSet(defaultDynScope1, defaultDynScope2, defaultScope1, defaultScope2, dynScope1, restrictedScope1);
+		allScopeStrings = Sets.newHashSet(defaultDynScope1String, defaultDynScope2String, defaultScope1String, defaultScope2String, dynScope1String, restrictedScope1String);
 
-		// structuredScope1Value : structured scope with value
-		structuredScope1Value = new SystemScope(structuredScope1String);
-		structuredScope1Value.setStructured(true);
-		structuredScope1Value.setStructuredValue(structuredValue);
-
-		allScopes = Sets.newHashSet(defaultDynScope1, defaultDynScope2, defaultScope1, defaultScope2, dynScope1, restrictedScope1, structuredScope1);
-		allScopeStrings = Sets.newHashSet(defaultDynScope1String, defaultDynScope2String, defaultScope1String, defaultScope2String, dynScope1String, restrictedScope1String, structuredScope1String);
-
-		allScopesWithValue = Sets.newHashSet(defaultDynScope1, defaultDynScope2, defaultScope1, defaultScope2, dynScope1, restrictedScope1, structuredScope1, structuredScope1Value);
-		allScopeStringsWithValue = Sets.newHashSet(defaultDynScope1String, defaultDynScope2String, defaultScope1String, defaultScope2String, dynScope1String, restrictedScope1String, structuredScope1String, structuredScope1String + ":" + structuredValue);
+		allScopesWithValue = Sets.newHashSet(defaultDynScope1, defaultDynScope2, defaultScope1, defaultScope2, dynScope1, restrictedScope1);
+		allScopeStringsWithValue = Sets.newHashSet(defaultDynScope1String, defaultDynScope2String, defaultScope1String, defaultScope2String, dynScope1String, restrictedScope1String);
 
 		Mockito.when(repository.getByValue(defaultDynScope1String)).thenReturn(defaultDynScope1);
 		Mockito.when(repository.getByValue(defaultDynScope2String)).thenReturn(defaultDynScope2);
@@ -126,16 +113,6 @@ public class TestDefaultSystemScopeService {
 		Mockito.when(repository.getByValue(defaultScope2String)).thenReturn(defaultScope2);
 		Mockito.when(repository.getByValue(dynScope1String)).thenReturn(dynScope1);
 		Mockito.when(repository.getByValue(restrictedScope1String)).thenReturn(restrictedScope1);
-		// we re-use this value so we've got to use thenAnswer instead
-		Mockito.when(repository.getByValue(structuredScope1String)).thenAnswer(new Answer<SystemScope>() {
-			@Override
-			public SystemScope answer(InvocationOnMock invocation) throws Throwable {
-				SystemScope s = new SystemScope(structuredScope1String);
-				s.setStructured(true);
-				return s;
-			}
-
-		});
 
 		Mockito.when(repository.getAll()).thenReturn(allScopes);
 	}
@@ -157,7 +134,7 @@ public class TestDefaultSystemScopeService {
 	@Test
 	public void getUnrestricted() {
 
-		Set<SystemScope> unrestricted = Sets.newHashSet(defaultDynScope1, defaultDynScope2, dynScope1, structuredScope1);
+		Set<SystemScope> unrestricted = Sets.newHashSet(defaultDynScope1, defaultDynScope2, dynScope1);
 
 		assertThat(service.getUnrestricted(), equalTo(unrestricted));
 	}
@@ -210,25 +187,4 @@ public class TestDefaultSystemScopeService {
 		assertThat(service.scopesMatch(expected, actualBad), is(false));
 	}
 
-	@Test
-	public void scopesMatch_structured() {
-		Set<String> expected = Sets.newHashSet("foo", "bar", "baz");
-		Set<String> actualGood = Sets.newHashSet("foo:value", "baz", "bar");
-		Set<String> actualBad = Sets.newHashSet("foo:value", "bar:value");
-
-		// note: we have to use "thenAnswer" here to mimic the repository not serializing the structuredValue field
-		Mockito.when(repository.getByValue("foo")).thenAnswer(new Answer<SystemScope>() {
-			@Override
-			public SystemScope answer(InvocationOnMock invocation) throws Throwable {
-				SystemScope foo = new SystemScope("foo");
-				foo.setStructured(true);
-				return foo;
-			}
-
-		});
-
-		assertThat(service.scopesMatch(expected, actualGood), is(true));
-
-		assertThat(service.scopesMatch(expected, actualBad), is(false));
-	}
 }
diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java
index cb2f58904..bcff4aa96 100644
--- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java
+++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_1.java
@@ -782,8 +782,6 @@ public class TestMITREidDataService_1_1 {
 		scope3.setRestricted(false);
 		scope3.setDefaultScope(true);
 		scope3.setIcon("road");
-		scope3.setStructured(true);
-		scope3.setStructuredParamDescription("Structured Parameter");
 
 		String configJson = "{" +
 				"\"" + MITREidDataService.CLIENTS + "\": [], " +
@@ -797,7 +795,7 @@ public class TestMITREidDataService_1_1 {
 
 				"{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"allowDynReg\":false,\"defaultScope\":false}," +
 				"{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"allowDynReg\":true,\"defaultScope\":false}," +
-				"{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"allowDynReg\":true,\"defaultScope\":true,\"structured\":true,\"structuredParameter\":\"Structured Parameter\"}" +
+				"{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"allowDynReg\":true,\"defaultScope\":true}" +
 
 				"  ]" +
 				"}";
@@ -817,24 +815,18 @@ public class TestMITREidDataService_1_1 {
 		assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon()));
 		assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope()));
 		assertThat(savedScopes.get(0).isRestricted(), equalTo(scope1.isRestricted()));
-		assertThat(savedScopes.get(0).isStructured(), equalTo(scope1.isStructured()));
-		assertThat(savedScopes.get(0).getStructuredParamDescription(), equalTo(scope1.getStructuredParamDescription()));
 
 		assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue()));
 		assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription()));
 		assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon()));
 		assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope()));
 		assertThat(savedScopes.get(1).isRestricted(), equalTo(scope2.isRestricted()));
-		assertThat(savedScopes.get(1).isStructured(), equalTo(scope2.isStructured()));
-		assertThat(savedScopes.get(1).getStructuredParamDescription(), equalTo(scope2.getStructuredParamDescription()));
 
 		assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue()));
 		assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription()));
 		assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon()));
 		assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope()));
 		assertThat(savedScopes.get(2).isRestricted(), equalTo(scope3.isRestricted()));
-		assertThat(savedScopes.get(2).isStructured(), equalTo(scope3.isStructured()));
-		assertThat(savedScopes.get(2).getStructuredParamDescription(), equalTo(scope3.getStructuredParamDescription()));
 
 	}
 
diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_2.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_2.java
index 44264eb33..6f2832a7f 100644
--- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_2.java
+++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_2.java
@@ -797,8 +797,6 @@ public class TestMITREidDataService_1_2 {
 		scope3.setRestricted(false);
 		scope3.setDefaultScope(true);
 		scope3.setIcon("road");
-		scope3.setStructured(true);
-		scope3.setStructuredParamDescription("Structured Parameter");
 
 		String configJson = "{" +
 				"\"" + MITREidDataService.CLIENTS + "\": [], " +
@@ -812,7 +810,7 @@ public class TestMITREidDataService_1_2 {
 
 				"{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"restricted\":true,\"defaultScope\":false}," +
 				"{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"restricted\":false,\"defaultScope\":false}," +
-				"{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"restricted\":false,\"defaultScope\":true,\"structured\":true,\"structuredParameter\":\"Structured Parameter\"}" +
+				"{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"restricted\":false,\"defaultScope\":true}" +
 
 				"  ]" +
 				"}";
@@ -832,24 +830,18 @@ public class TestMITREidDataService_1_2 {
 		assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon()));
 		assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope()));
 		assertThat(savedScopes.get(0).isRestricted(), equalTo(scope1.isRestricted()));
-		assertThat(savedScopes.get(0).isStructured(), equalTo(scope1.isStructured()));
-		assertThat(savedScopes.get(0).getStructuredParamDescription(), equalTo(scope1.getStructuredParamDescription()));
 
 		assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue()));
 		assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription()));
 		assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon()));
 		assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope()));
 		assertThat(savedScopes.get(1).isRestricted(), equalTo(scope2.isRestricted()));
-		assertThat(savedScopes.get(1).isStructured(), equalTo(scope2.isStructured()));
-		assertThat(savedScopes.get(1).getStructuredParamDescription(), equalTo(scope2.getStructuredParamDescription()));
 
 		assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue()));
 		assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription()));
 		assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon()));
 		assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope()));
 		assertThat(savedScopes.get(2).isRestricted(), equalTo(scope3.isRestricted()));
-		assertThat(savedScopes.get(2).isStructured(), equalTo(scope3.isStructured()));
-		assertThat(savedScopes.get(2).getStructuredParamDescription(), equalTo(scope3.getStructuredParamDescription()));
 
 	}
 
diff --git a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_3.java b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_3.java
index 4d2e71b72..d2cefc594 100644
--- a/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_3.java
+++ b/openid-connect-server/src/test/java/org/mitre/openid/connect/service/impl/TestMITREidDataService_1_3.java
@@ -1669,8 +1669,6 @@ public class TestMITREidDataService_1_3 {
 		scope3.setRestricted(false);
 		scope3.setDefaultScope(true);
 		scope3.setIcon("road");
-		scope3.setStructured(true);
-		scope3.setStructuredParamDescription("Structured Parameter");
 
 		String configJson = "{" +
 				"\"" + MITREidDataService.CLIENTS + "\": [], " +
@@ -1684,7 +1682,7 @@ public class TestMITREidDataService_1_3 {
 
 				"{\"id\":1,\"description\":\"Scope 1\",\"icon\":\"glass\",\"value\":\"scope1\",\"restricted\":true,\"defaultScope\":false}," +
 				"{\"id\":2,\"description\":\"Scope 2\",\"icon\":\"ball\",\"value\":\"scope2\",\"restricted\":false,\"defaultScope\":false}," +
-				"{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"restricted\":false,\"defaultScope\":true,\"structured\":true,\"structuredParameter\":\"Structured Parameter\"}" +
+				"{\"id\":3,\"description\":\"Scope 3\",\"icon\":\"road\",\"value\":\"scope3\",\"restricted\":false,\"defaultScope\":true}" +
 
 				"  ]" +
 				"}";
@@ -1704,24 +1702,18 @@ public class TestMITREidDataService_1_3 {
 		assertThat(savedScopes.get(0).getIcon(), equalTo(scope1.getIcon()));
 		assertThat(savedScopes.get(0).isDefaultScope(), equalTo(scope1.isDefaultScope()));
 		assertThat(savedScopes.get(0).isRestricted(), equalTo(scope1.isRestricted()));
-		assertThat(savedScopes.get(0).isStructured(), equalTo(scope1.isStructured()));
-		assertThat(savedScopes.get(0).getStructuredParamDescription(), equalTo(scope1.getStructuredParamDescription()));
 
 		assertThat(savedScopes.get(1).getValue(), equalTo(scope2.getValue()));
 		assertThat(savedScopes.get(1).getDescription(), equalTo(scope2.getDescription()));
 		assertThat(savedScopes.get(1).getIcon(), equalTo(scope2.getIcon()));
 		assertThat(savedScopes.get(1).isDefaultScope(), equalTo(scope2.isDefaultScope()));
 		assertThat(savedScopes.get(1).isRestricted(), equalTo(scope2.isRestricted()));
-		assertThat(savedScopes.get(1).isStructured(), equalTo(scope2.isStructured()));
-		assertThat(savedScopes.get(1).getStructuredParamDescription(), equalTo(scope2.getStructuredParamDescription()));
 
 		assertThat(savedScopes.get(2).getValue(), equalTo(scope3.getValue()));
 		assertThat(savedScopes.get(2).getDescription(), equalTo(scope3.getDescription()));
 		assertThat(savedScopes.get(2).getIcon(), equalTo(scope3.getIcon()));
 		assertThat(savedScopes.get(2).isDefaultScope(), equalTo(scope3.isDefaultScope()));
 		assertThat(savedScopes.get(2).isRestricted(), equalTo(scope3.isRestricted()));
-		assertThat(savedScopes.get(2).isStructured(), equalTo(scope3.isStructured()));
-		assertThat(savedScopes.get(2).getStructuredParamDescription(), equalTo(scope3.getStructuredParamDescription()));
 
 	}
 
diff --git a/uma-server-webapp/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java b/uma-server-webapp/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
index 01cdb2f74..38295ba6b 100644
--- a/uma-server-webapp/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
+++ b/uma-server-webapp/src/main/java/org/mitre/openid/connect/service/impl/MITREidDataService_1_2.java
@@ -726,8 +726,6 @@ public class MITREidDataService_1_2 extends MITREidDataServiceSupport implements
 				writer.name(ICON).value(sysScope.getIcon());
 				writer.name(VALUE).value(sysScope.getValue());
 				writer.name(RESTRICTED).value(sysScope.isRestricted());
-				writer.name(STRUCTURED).value(sysScope.isStructured());
-				writer.name(STRUCTURED_PARAMETER).value(sysScope.getStructuredParamDescription());
 				writer.name(DEFAULT_SCOPE).value(sysScope.isDefaultScope());
 				writer.endObject();
 				logger.debug("Wrote system scope {}", sysScope.getId());
@@ -1710,9 +1708,9 @@ public class MITREidDataService_1_2 extends MITREidDataServiceSupport implements
 					} else if (name.equals(ICON)) {
 						scope.setIcon(reader.nextString());
 					} else if (name.equals(STRUCTURED)) {
-						scope.setStructured(reader.nextBoolean());
+						logger.debug("Found a structured scope, ignoring structure");
 					} else if (name.equals(STRUCTURED_PARAMETER)) {
-						scope.setStructuredParamDescription(reader.nextString());
+						logger.debug("Found a structured scope, ignoring structure");
 					} else {
 						logger.debug("found unexpected entry");
 						reader.skipValue();