changeset 231:eb87674844fd

Add default realm authorizer Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2017-August/024600.html
author Jie Kang <jkang@redhat.com>
date Mon, 21 Aug 2017 16:44:08 -0400
parents e18145dc173b
children 8fe9127fb648
files common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizer.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/InvalidRoleException.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/RealmAuthorizer.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/Role.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/RoleFactory.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/InvalidRoleException.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/KeycloakRealmAuthorizer.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RealmAuthorizer.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/Role.java common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RoleFactory.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizerTest.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/RoleFactoryTest.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/RoleTest.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/KeycloakRealmAuthorizerTest.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RealmAuthorizerTest.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RoleFactoryTest.java common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RoleTest.java common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java server/src/main/java/com/redhat/thermostat/gateway/server/auth/DefaultAuthFilter.java server/src/main/java/com/redhat/thermostat/gateway/server/auth/keycloak/KeycloakRequestFilter.java server/src/main/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreService.java server/src/test/java/com/redhat/thermostat/gateway/server/auth/keycloak/KeycloakRequestFilterTest.java services/jvms/src/main/java/com/redhat/thermostat/gateway/service/jvms/http/JvmsHttpHandler.java services/jvms/src/main/java/com/redhat/thermostat/gateway/service/jvms/mongo/JvmInfoMongoStorageHandler.java tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java
diffstat 25 files changed, 1336 insertions(+), 1048 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizer.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class DefaultRealmAuthorizer extends RealmAuthorizer {
+    public static final String DEFAULT_REALM = "thermostat";
+
+    public DefaultRealmAuthorizer() throws InvalidRoleException {
+        RoleFactory roleFactory = new RoleFactory();
+        Role r = roleFactory.buildRole("r,w,u,d-" + DEFAULT_REALM);
+        Set<Role> roles = new HashSet<>();
+        roles.add(r);
+
+        clientRoles = Collections.unmodifiableSet(roles);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/InvalidRoleException.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+public class InvalidRoleException extends Exception {
+    public InvalidRoleException(String s) {
+        super(s);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/RealmAuthorizer.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import com.redhat.thermostat.gateway.common.core.auth.keycloak.Action;
+
+public abstract class RealmAuthorizer {
+
+    protected Set<Role> clientRoles = Collections.emptySet();
+
+    public boolean readable() {
+        return checkActionExists(Action.READ);
+    }
+
+    public boolean writable() {
+        return checkActionExists(Action.WRITE);
+    }
+
+    public boolean updatable() {
+        return checkActionExists(Action.UPDATE);
+    }
+
+    public boolean deletable() {
+        return checkActionExists(Action.DELETE);
+    }
+
+    public boolean checkActionExists(String action) {
+        for (Role role : clientRoles) {
+            if (role.containsAction(action)) {
+                return  true;
+            }
+        }
+        return false;
+    }
+
+    public Set<String> getReadableRealms() {
+        return getRealmsWithAction(Action.READ);
+    }
+
+    public Set<String> getWritableRealms() {
+        return getRealmsWithAction(Action.WRITE);
+    }
+
+    public Set<String> getUpdatableRealms() {
+        return getRealmsWithAction(Action.UPDATE);
+    }
+
+    public Set<String> getDeletableRealms() {
+        return getRealmsWithAction(Action.DELETE);
+    }
+
+    public Set<String> getRealmsWithAction(String action) {
+        Set<String> realms = new HashSet<>();
+        for (Role role : clientRoles) {
+            if (role.containsAction(action)) {
+                realms.add(role.getRealm());
+            }
+        }
+        return Collections.unmodifiableSet(realms);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/Role.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+public class Role {
+    public static final String ACTION_DELIMITER = ",";
+    public static final String ROLE_DELIMITER = "-";
+    /**
+     * Array of regex that valid roles cannot match
+     * Role cannot contain any whitespaces
+     */
+    public static final String[] RESTRICTED_CHARACTERS_REGEX = new String[]{".*\\s+.*"};
+
+    private final Set<String> actions;
+    private final String realm;
+
+    public Role(Set<String> actions, String realm) {
+        Objects.requireNonNull(actions);
+        Objects.requireNonNull(realm);
+        this.actions = Collections.unmodifiableSet(actions);
+        this.realm = realm;
+    }
+
+    public Set<String> getActions() {
+        return this.actions;
+    }
+
+    public String getRealm() {
+        return this.realm;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        Role role = (Role) o;
+
+        if (!actions.equals(role.actions)) {
+            return false;
+        }
+
+        return realm.equals(role.realm);
+    }
+
+    public boolean containsAction(String action) {
+        return this.actions.contains(action);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(actions, realm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/RoleFactory.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class RoleFactory {
+
+    private boolean isValidRole(String role) {
+        if (!role.contains(Role.ROLE_DELIMITER)) {
+            return false;
+        }
+        for (String restrictedCharacter : Role.RESTRICTED_CHARACTERS_REGEX) {
+            if (role.matches(restrictedCharacter)) {
+                return false;
+            }
+        }
+
+        int index = role.indexOf(Role.ROLE_DELIMITER);
+
+        // Make sure there are characters before and after the role delimiter
+        return index > 0 && index < role.length() - 1;
+    }
+
+    public Role buildRole(String role) throws InvalidRoleException {
+        role = role.trim();
+
+        if (!isValidRole(role)) {
+            throw new InvalidRoleException("Invalid role: " + role);
+        }
+
+        int index = role.indexOf(Role.ROLE_DELIMITER);
+        String actions = role.substring(0, index);
+
+        String realm = role.substring(index + 1);
+
+        Set<String> actionSet = new HashSet<>(Arrays.asList(actions.split(Role.ACTION_DELIMITER)));
+        return new Role(actionSet, realm);
+    }
+}
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/InvalidRoleException.java	Mon Aug 21 08:57:27 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth.keycloak;
-
-public class InvalidRoleException extends Exception {
-    public InvalidRoleException(String s) {
-        super(s);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/KeycloakRealmAuthorizer.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth.keycloak;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.keycloak.KeycloakSecurityContext;
+
+import com.redhat.thermostat.gateway.common.core.auth.InvalidRoleException;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.Role;
+import com.redhat.thermostat.gateway.common.core.auth.RoleFactory;
+
+public class KeycloakRealmAuthorizer extends RealmAuthorizer {
+
+    public static final String REALMS_HEADER = "X-Thermostat-Realms";
+    private static final String REALMS_HEADER_DELIMITER_REGEX = "\\s+";
+
+    private final RoleFactory roleFactory = new RoleFactory();
+
+    public KeycloakRealmAuthorizer(HttpServletRequest httpServletRequest) throws ServletException {
+        this.clientRoles = buildClientRoles(httpServletRequest);
+    }
+
+    /**
+     * Package private for testing
+     */
+    Set<Role> getAllRoles() {
+        return clientRoles;
+    }
+
+    private Set<Role> buildClientRoles(HttpServletRequest httpServletRequest) throws ServletException {
+        Set<Role> keycloakRoles = buildKeycloakRoles(httpServletRequest);
+
+        String realmsHeader = httpServletRequest.getHeader(REALMS_HEADER);
+        if (realmsHeader != null) {
+            return buildClientPreferredRoles(keycloakRoles, realmsHeader);
+        }
+
+        return Collections.unmodifiableSet(keycloakRoles);
+    }
+
+    /**
+     * @return the set of roles from the Keycloak security token
+     */
+    private Set<Role> buildKeycloakRoles(HttpServletRequest httpServletRequest) {
+        Set<Role> keycloakRoles = new HashSet<>();
+
+        KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) httpServletRequest
+                .getAttribute(KeycloakSecurityContext.class.getName());
+
+        for (String role : keycloakSecurityContext.getToken().getRealmAccess().getRoles()) {
+            try {
+                keycloakRoles.add(roleFactory.buildRole(role));
+            } catch (InvalidRoleException e) {
+                //Do nothing
+            }
+        }
+
+        return keycloakRoles;
+    }
+
+    /**
+     * Builds a set of roles based on a clients preferred set, provided in a comma separated realms header string
+     * @param trustedRoles : The trusted set of roles that the client has
+     * @param realmsHeader : The REALMS_HEADER value as a string
+     * @return The set of roles that the client has selected
+     * @throws ServletException If realms header contains realms the client does not have or no valid realms
+     */
+    private Set<Role> buildClientPreferredRoles(Set<Role> trustedRoles, String realmsHeader) throws ServletException {
+        realmsHeader = realmsHeader.trim();
+        Set<String> preferredRealms = new HashSet<>(Arrays.asList(realmsHeader.split(REALMS_HEADER_DELIMITER_REGEX)));
+        Set<Role> selectedRoles = new HashSet<>();
+
+        for (String preferredRealm : preferredRealms) {
+            boolean found = false;
+            for (Role role : trustedRoles) {
+                if (role.getRealm().equals(preferredRealm)) {
+                    selectedRoles.add(role);
+                    found = true;
+                }
+            }
+            if (!found) {
+                throw new ServletException("Not authorized to access preferred realms.");
+            }
+        }
+
+        if (selectedRoles.size() > 0) {
+            return selectedRoles;
+        } else {
+            throw new ServletException("No realms selected");
+        }
+    }
+
+
+}
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RealmAuthorizer.java	Mon Aug 21 08:57:27 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth.keycloak;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.keycloak.KeycloakSecurityContext;
-
-public class RealmAuthorizer {
-
-    public static final String REALMS_HEADER = "X-Thermostat-Realms";
-    private static final String REALMS_HEADER_DELIMITER_REGEX = "\\s+";
-
-    private final Set<Role> clientRoles;
-    private final RoleFactory roleFactory = new RoleFactory();
-
-    public RealmAuthorizer(HttpServletRequest httpServletRequest) throws ServletException {
-        Set<Role> roles = buildClientRoles(httpServletRequest);
-        this.clientRoles = Collections.unmodifiableSet(roles);
-    }
-
-    public boolean readable() {
-        return checkActionExists(Action.READ);
-    }
-
-    public boolean writable() {
-        return checkActionExists(Action.WRITE);
-    }
-
-    public boolean updatable() {
-        return checkActionExists(Action.UPDATE);
-    }
-
-    public boolean deletable() {
-        return checkActionExists(Action.DELETE);
-    }
-
-    public boolean checkActionExists(String action) {
-        for (Role role : clientRoles) {
-            if (role.containsAction(action)) {
-                return  true;
-            }
-        }
-        return false;
-    }
-
-    public Set<String> getReadableRealms() {
-        return getRealmsWithAction(Action.READ);
-    }
-
-    public Set<String> getWritableRealms() {
-        return getRealmsWithAction(Action.WRITE);
-    }
-    public Set<String> getUpdatableRealms() {
-        return getRealmsWithAction(Action.UPDATE);
-    }
-    public Set<String> getDeletableRealms() {
-        return getRealmsWithAction(Action.DELETE);
-    }
-
-    public Set<String> getRealmsWithAction(String action) {
-        Set<String> realms = new HashSet<>();
-        for (Role role : clientRoles) {
-            if (role.containsAction(action)) {
-                realms.add(role.getRealm());
-            }
-        }
-        return Collections.unmodifiableSet(realms);
-    }
-
-    protected Set<Role> getAllRoles() {
-        return clientRoles;
-    }
-
-    private Set<Role> buildClientRoles(HttpServletRequest httpServletRequest) throws ServletException {
-        Set<Role> keycloakRoles = buildKeycloakRoles(httpServletRequest);
-
-        String realmsHeader = httpServletRequest.getHeader(REALMS_HEADER);
-        if (realmsHeader != null) {
-            return buildClientPreferredRoles(keycloakRoles, realmsHeader);
-        }
-
-        return keycloakRoles;
-    }
-
-    /**
-     * @return the set of roles from the Keycloak security token
-     */
-    private Set<Role> buildKeycloakRoles(HttpServletRequest httpServletRequest) {
-        Set<Role> keycloakRoles = new HashSet<>();
-
-        KeycloakSecurityContext keycloakSecurityContext = (KeycloakSecurityContext) httpServletRequest
-                .getAttribute(KeycloakSecurityContext.class.getName());
-
-        for (String role : keycloakSecurityContext.getToken().getRealmAccess().getRoles()) {
-            try {
-                keycloakRoles.add(roleFactory.buildRole(role));
-            } catch (InvalidRoleException e) {
-                //Do nothing
-            }
-        }
-
-        return keycloakRoles;
-    }
-
-    /**
-     * Builds a set of roles based on a clients preferred set, provided in a comma separated realms header string
-     * @param trustedRoles : The trusted set of roles that the client has
-     * @param realmsHeader : The REALMS_HEADER value as a string
-     * @return The set of roles that the client has selected
-     * @throws ServletException If realms header contains realms the client does not have or no valid realms
-     */
-    private Set<Role> buildClientPreferredRoles(Set<Role> trustedRoles, String realmsHeader) throws ServletException {
-        realmsHeader = realmsHeader.trim();
-        Set<String> preferredRealms = new HashSet<>(Arrays.asList(realmsHeader.split(REALMS_HEADER_DELIMITER_REGEX)));
-        Set<Role> selectedRoles = new HashSet<>();
-
-        for (String preferredRealm : preferredRealms) {
-            boolean found = false;
-            for (Role role : trustedRoles) {
-                if (role.getRealm().equals(preferredRealm)) {
-                    selectedRoles.add(role);
-                    found = true;
-                }
-            }
-            if (!found) {
-                throw new ServletException("Not authorized to access preferred realms.");
-            }
-        }
-
-        if (selectedRoles.size() > 0) {
-            return selectedRoles;
-        } else {
-            throw new ServletException("No realms selected");
-        }
-    }
-
-
-}
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/Role.java	Mon Aug 21 08:57:27 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth.keycloak;
-
-import java.util.Collections;
-import java.util.Objects;
-import java.util.Set;
-
-public class Role {
-    public static final String ACTION_DELIMITER = ",";
-    public static final String ROLE_DELIMITER = "-";
-    /**
-     * Array of regex that valid roles cannot match
-     * Role cannot contain any whitespaces
-     */
-    public static final String[] RESTRICTED_CHARACTERS_REGEX = new String[]{".*\\s+.*"};
-
-    private final Set<String> actions;
-    private final String realm;
-
-    public Role(Set<String> actions, String realm) {
-        Objects.requireNonNull(actions);
-        Objects.requireNonNull(realm);
-        this.actions = Collections.unmodifiableSet(actions);
-        this.realm = realm;
-    }
-
-    public Set<String> getActions() {
-        return this.actions;
-    }
-
-    public String getRealm() {
-        return this.realm;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        Role role = (Role) o;
-
-        if (!actions.equals(role.actions)) {
-            return false;
-        }
-
-        return realm.equals(role.realm);
-    }
-
-    public boolean containsAction(String action) {
-        return this.actions.contains(action);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(actions, realm);
-    }
-}
--- a/common/core/src/main/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RoleFactory.java	Mon Aug 21 08:57:27 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth.keycloak;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-public class RoleFactory {
-
-    private boolean isValidRole(String role) {
-        if (!role.contains(Role.ROLE_DELIMITER)) {
-            return false;
-        }
-        for (String restrictedCharacter : Role.RESTRICTED_CHARACTERS_REGEX) {
-            if (role.matches(restrictedCharacter)) {
-                return false;
-            }
-        }
-
-        int index = role.indexOf(Role.ROLE_DELIMITER);
-
-        // Make sure there are characters before and after the role delimiter
-        return index > 0 && index < role.length() - 1;
-    }
-
-    public Role buildRole(String role) throws InvalidRoleException {
-        role = role.trim();
-
-        if (!isValidRole(role)) {
-            throw new InvalidRoleException("Invalid role: " + role);
-        }
-
-        int index = role.indexOf(Role.ROLE_DELIMITER);
-        String actions = role.substring(0, index);
-
-        String realm = role.substring(index + 1);
-
-        Set<String> actionSet = new HashSet<>(Arrays.asList(actions.split(Role.ACTION_DELIMITER)));
-        return new Role(actionSet, realm);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/DefaultRealmAuthorizerTest.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class DefaultRealmAuthorizerTest {
+
+    @Test
+    public void testDefaultRoleExists() throws InvalidRoleException {
+        DefaultRealmAuthorizer realmAuthorizer = new DefaultRealmAuthorizer();
+
+        assertEquals(1, realmAuthorizer.clientRoles.size());
+
+        for (Role r : realmAuthorizer.clientRoles) {
+            assertEquals("thermostat", r.getRealm());
+            assertTrue(r.containsAction("r"));
+            assertTrue(r.containsAction("w"));
+            assertTrue(r.containsAction("u"));
+            assertTrue(r.containsAction("d"));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/RoleFactoryTest.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class RoleFactoryTest {
+
+    private RoleFactory roleFactory;
+
+    @Before
+    public void setup() {
+        roleFactory = new RoleFactory();
+    }
+
+    @Test
+    public void testValidRole() throws InvalidRoleException {
+        String role = "a-valid,role";
+        roleFactory.buildRole(role);
+
+        Set<String> actions = new HashSet<>();
+        actions.add("a");
+        Role r = roleFactory.buildRole(role);
+        verifyRole(r, actions, "valid,role");
+    }
+
+    @Test
+    public void testValidRoleWithActions() throws InvalidRoleException {
+        String role = "r,w,d-role";
+
+        Role r = roleFactory.buildRole(role);
+        Set<String> actions = new HashSet<>();
+        actions.add("r");
+        actions.add("w");
+        actions.add("d");
+        verifyRole(r, actions, "role");
+    }
+
+    @Test(expected = InvalidRoleException.class)
+    public void testNoActionRole() throws InvalidRoleException {
+        String role = "-role";
+        roleFactory.buildRole(role);
+    }
+
+    @Test(expected = InvalidRoleException.class)
+    public void testNoRealmRole() throws InvalidRoleException {
+        String role = "a-";
+        roleFactory.buildRole(role);
+    }
+
+    @Test
+    public void testHyphenRealm() throws InvalidRoleException {
+        String role = "a-realm-with-hyphens";
+
+        Role r = roleFactory.buildRole(role);
+        Set<String> actions = new HashSet<>();
+        actions.add("a");
+        verifyRole(r, actions, "realm-with-hyphens");
+    }
+
+    @Test(expected = InvalidRoleException.class)
+    public void testRealmWithWhitespaceIsInvalid() throws InvalidRoleException {
+        String role = "a-invalid \trealm";
+        roleFactory.buildRole(role);
+    }
+
+    @Test
+    public void testRealmWithLeadingWhitespace() throws InvalidRoleException {
+        String role = " a-role";
+
+        Role r = roleFactory.buildRole(role);
+        Set<String> actions = new HashSet<>();
+        actions.add("a");
+        verifyRole(r, actions, "role");
+    }
+
+    @Test
+    public void testRealmWithTrailingWhitespace() throws InvalidRoleException {
+        String role = "a-role\t";
+
+        Role r = roleFactory.buildRole(role);
+        Set<String> actions = new HashSet<>();
+        actions.add("a");
+        verifyRole(r, actions, "role");
+    }
+
+    private void verifyRole(Role role, Set<String> expectedActions, String expectedRole) {
+        for (String item : expectedActions) {
+            assertTrue(role.containsAction(item));
+        }
+        assertEquals(expectedRole, role.getRealm());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/RoleTest.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.gateway.common.core.auth.Role;
+
+public class RoleTest {
+
+    @Test
+    public void testSimpleRole() {
+        Set<String> actions = new HashSet<>();
+        actions.add("a");
+        Role r = new Role(actions, "realm");
+
+        verifyRole(r, actions, "realm");
+    }
+
+    @Test
+    public void testMultipleActionsRole() {
+        Set<String> actions = new HashSet<>();
+        actions.add("a");
+        Role r = new Role(actions, "realm-1.2-3");
+
+        verifyRole(r, actions, "realm-1.2-3");
+    }
+
+    /*
+    Roles are added to set data structures which rely on the equals()
+    implementation to prevent duplicates
+     */
+    @Test
+    public void testEquals() {
+        Set<String> actionsOne = new HashSet<>();
+        actionsOne.add("a");
+
+        Role one = new Role(actionsOne, "b");
+        Role two = new Role(actionsOne, "b");
+
+        assertEquals(one, two);
+
+        Set<String> actionsTwo = new HashSet<>();
+        actionsTwo.add("a");
+
+        Role three = new Role(actionsTwo, "b");
+
+        assertEquals(one, three);
+    }
+
+    @Test
+    public void testNotEquals() {
+        Set<String> actionsOne = new HashSet<>();
+        actionsOne.add("a");
+
+        Set<String> actionsTwo = new HashSet<>();
+        actionsTwo.add("b");
+
+        Role one = new Role(actionsOne, "b");
+        Role two = new Role(actionsOne, "c");
+        Role three = new Role(actionsTwo, "b");
+
+        assertNotEquals(one, two);
+        assertNotEquals(one, three);
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void testActionsCannotBeModified() {
+        Set<String> actions = new HashSet<>();
+        actions.add("a");
+        Role r = new Role(actions, "realm-1.2-3");
+
+        verifyRole(r, actions, "realm-1.2-3");
+
+        r.getActions().add("not-allowed");
+    }
+
+    private void verifyRole(Role role, Set<String> expectedActions, String expectedRole) {
+        for (String item : expectedActions) {
+            assertTrue(role.containsAction(item));
+        }
+        assertEquals(expectedRole, role.getRealm());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/KeycloakRealmAuthorizerTest.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.common.core.auth.keycloak;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.keycloak.KeycloakSecurityContext;
+import org.keycloak.representations.AccessToken;
+
+import com.redhat.thermostat.gateway.common.core.auth.Role;
+
+public class KeycloakRealmAuthorizerTest {
+
+    HttpServletRequest request;
+    AccessToken.Access access;
+
+    @Before
+    public void setup() {
+        request = mock(HttpServletRequest.class);
+        KeycloakSecurityContext keycloakSecurityContext = mock(KeycloakSecurityContext.class);
+        when(request.getAttribute(eq(KeycloakSecurityContext.class.getName()))).thenReturn(keycloakSecurityContext);
+
+        AccessToken accessToken = mock(AccessToken.class);
+        when(keycloakSecurityContext.getToken()).thenReturn(accessToken);
+
+        access = mock(AccessToken.Access.class);
+        when(accessToken.getRealmAccess()).thenReturn(access);
+    }
+
+    @Test
+    public void testBuildSingleRealm() throws ServletException {
+        String[] roles = new String[]{"a-realm"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+
+        Set<String> realms = realmAuthorizer.getRealmsWithAction("a");
+        assertTrue(realms.contains("realm"));
+    }
+
+    @Test
+    public void testBuildMultipleRealms() throws ServletException {
+        String[] roles = new String[]{"a-realm", "b-another"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+
+        Set<String> realms = realmAuthorizer.getRealmsWithAction("a");
+        assertTrue(realms.contains("realm"));
+        assertFalse(realms.contains("another"));
+
+        realms = realmAuthorizer.getRealmsWithAction("b");
+        assertTrue(realms.contains("another"));
+        assertFalse(realms.contains("realm"));
+    }
+
+    @Test
+    public void testBuildMultipleRealmsSameAction() throws ServletException {
+        String[] roles = new String[]{"r-realm", "w-realm"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+
+
+        Set<String> realms = realmAuthorizer.getRealmsWithAction("r");
+        assertTrue(realms.contains("realm"));
+
+        realms = realmAuthorizer.getRealmsWithAction("w");
+        assertTrue(realms.contains("realm"));
+    }
+
+    @Test
+    public void testBuildRoleWithoutRealm() throws ServletException {
+        String[] roles = new String[]{"a-"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        Set<Role> realms = realmAuthorizer.getAllRoles();
+        assertTrue(realms.isEmpty());
+    }
+
+    @Test
+    public void testBuildInvalidRoleWithoutAction() throws ServletException {
+        String[] roles = new String[]{"-realm"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        Set<Role> realms = realmAuthorizer.getAllRoles();
+        assertTrue(realms.isEmpty());
+    }
+
+
+    private void setupRealms() {
+        String[] roles = new String[]{"r-read", "w-write", "d-delete", "u-update"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+    }
+
+    @Test
+    public void testReadable() throws ServletException {
+        setupRealms();
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertTrue(realmAuthorizer.readable());
+
+        Set<String> realms = realmAuthorizer.getReadableRealms();
+        assertEquals(1, realms.size());
+        assertTrue(realms.contains("read"));
+    }
+
+    @Test
+    public void testWritable() throws ServletException {
+        setupRealms();
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertTrue(realmAuthorizer.writable());
+
+        Set<String> realms = realmAuthorizer.getWritableRealms();
+        assertEquals(1, realms.size());
+        assertTrue(realms.contains("write"));
+    }
+
+    @Test
+    public void testUpdatable() throws ServletException {
+        setupRealms();
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertTrue(realmAuthorizer.updatable());
+
+        Set<String> realms = realmAuthorizer.getUpdatableRealms();
+        assertEquals(1, realms.size());
+        assertTrue(realms.contains("update"));
+    }
+
+    @Test
+    public void testDeletable() throws ServletException {
+        setupRealms();
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertTrue(realmAuthorizer.deletable());
+
+        Set<String> realms = realmAuthorizer.getDeletableRealms();
+        assertEquals(1, realms.size());
+        assertTrue(realms.contains("delete"));
+    }
+
+    @Test
+    public void testNotReadable() throws ServletException {
+        String[] roles = new String[]{"w-write", "d-delete", "u-update"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertFalse(realmAuthorizer.readable());
+
+        Set<String> realms = realmAuthorizer.getReadableRealms();
+        assertEquals(0, realms.size());
+    }
+
+    @Test
+    public void testNotWritable() throws ServletException {
+        String[] roles = new String[]{"r-read", "d-delete", "u-update"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertFalse(realmAuthorizer.writable());
+
+        Set<String> realms = realmAuthorizer.getWritableRealms();
+        assertEquals(0, realms.size());
+    }
+
+    @Test
+    public void testNotUpdatable() throws ServletException {
+        String[] roles = new String[]{"w-write", "d-delete", "r-read"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertFalse(realmAuthorizer.updatable());
+
+        Set<String> realms = realmAuthorizer.getUpdatableRealms();
+        assertEquals(0, realms.size());
+    }
+
+    @Test
+    public void testNotDeletable() throws ServletException {
+        String[] roles = new String[]{"w-write", "r-read", "u-update"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertFalse(realmAuthorizer.deletable());
+
+        Set<String> realms = realmAuthorizer.getDeletableRealms();
+        assertEquals(0, realms.size());
+    }
+
+    @Test
+    public void testRealmsHeaderSubset() throws ServletException {
+        String[] roles = new String[]{"w-write", "r-read", "u-update"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        when(request.getHeader(eq("X-Thermostat-Realms"))).thenReturn("read update");
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertEquals(1, realmAuthorizer.getReadableRealms().size());
+        assertEquals(1, realmAuthorizer.getUpdatableRealms().size());
+
+        assertEquals(0, realmAuthorizer.getWritableRealms().size());
+        assertEquals(0, realmAuthorizer.getDeletableRealms().size());
+    }
+
+    @Test (expected = ServletException.class)
+    public void testRealmsHeaderSuperset() throws ServletException {
+        String[] roles = new String[]{"r-read,","u-update"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        when(request.getHeader(eq("X-Thermostat-Realms"))).thenReturn("read update other");
+
+        new KeycloakRealmAuthorizer(request);
+    }
+
+    @Test
+    public void testRealmsHeaderWhitespace() throws ServletException {
+        String[] roles = new String[]{"w-write", "r-read", "u-update"};
+        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
+
+        when(request.getHeader(eq("X-Thermostat-Realms"))).thenReturn("  read  update\twrite    ");
+
+        KeycloakRealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(request);
+        assertEquals(1, realmAuthorizer.getReadableRealms().size());
+        assertEquals(1, realmAuthorizer.getUpdatableRealms().size());
+        assertEquals(1, realmAuthorizer.getWritableRealms().size());
+
+        assertEquals(0, realmAuthorizer.getDeletableRealms().size());
+    }
+
+}
--- a/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RealmAuthorizerTest.java	Mon Aug 21 08:57:27 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,280 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth.keycloak;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.keycloak.KeycloakSecurityContext;
-import org.keycloak.representations.AccessToken;
-
-public class RealmAuthorizerTest {
-
-    HttpServletRequest request;
-    AccessToken.Access access;
-
-    @Before
-    public void setup() {
-        request = mock(HttpServletRequest.class);
-        KeycloakSecurityContext keycloakSecurityContext = mock(KeycloakSecurityContext.class);
-        when(request.getAttribute(eq(KeycloakSecurityContext.class.getName()))).thenReturn(keycloakSecurityContext);
-
-        AccessToken accessToken = mock(AccessToken.class);
-        when(keycloakSecurityContext.getToken()).thenReturn(accessToken);
-
-        access = mock(AccessToken.Access.class);
-        when(accessToken.getRealmAccess()).thenReturn(access);
-    }
-
-    @Test
-    public void testBuildSingleRealm() throws ServletException {
-        String[] roles = new String[]{"a-realm"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-
-        Set<String> realms = realmAuthorizer.getRealmsWithAction("a");
-        assertTrue(realms.contains("realm"));
-    }
-
-    @Test
-    public void testBuildMultipleRealms() throws ServletException {
-        String[] roles = new String[]{"a-realm", "b-another"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-
-        Set<String> realms = realmAuthorizer.getRealmsWithAction("a");
-        assertTrue(realms.contains("realm"));
-        assertFalse(realms.contains("another"));
-
-        realms = realmAuthorizer.getRealmsWithAction("b");
-        assertTrue(realms.contains("another"));
-        assertFalse(realms.contains("realm"));
-    }
-
-    @Test
-    public void testBuildMultipleRealmsSameAction() throws ServletException {
-        String[] roles = new String[]{"r-realm", "w-realm"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-
-
-        Set<String> realms = realmAuthorizer.getRealmsWithAction("r");
-        assertTrue(realms.contains("realm"));
-
-        realms = realmAuthorizer.getRealmsWithAction("w");
-        assertTrue(realms.contains("realm"));
-    }
-
-    @Test
-    public void testBuildRoleWithoutRealm() throws ServletException {
-        String[] roles = new String[]{"a-"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        Set<Role> realms = realmAuthorizer.getAllRoles();
-        assertTrue(realms.isEmpty());
-    }
-
-    @Test
-    public void testBuildInvalidRoleWithoutAction() throws ServletException {
-        String[] roles = new String[]{"-realm"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        Set<Role> realms = realmAuthorizer.getAllRoles();
-        assertTrue(realms.isEmpty());
-    }
-
-
-    private void setupRealms() {
-        String[] roles = new String[]{"r-read", "w-write", "d-delete", "u-update"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-    }
-
-    @Test
-    public void testReadable() throws ServletException {
-        setupRealms();
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertTrue(realmAuthorizer.readable());
-
-        Set<String> realms = realmAuthorizer.getReadableRealms();
-        assertEquals(1, realms.size());
-        assertTrue(realms.contains("read"));
-    }
-
-    @Test
-    public void testWritable() throws ServletException {
-        setupRealms();
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertTrue(realmAuthorizer.writable());
-
-        Set<String> realms = realmAuthorizer.getWritableRealms();
-        assertEquals(1, realms.size());
-        assertTrue(realms.contains("write"));
-    }
-
-    @Test
-    public void testUpdatable() throws ServletException {
-        setupRealms();
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertTrue(realmAuthorizer.updatable());
-
-        Set<String> realms = realmAuthorizer.getUpdatableRealms();
-        assertEquals(1, realms.size());
-        assertTrue(realms.contains("update"));
-    }
-
-    @Test
-    public void testDeletable() throws ServletException {
-        setupRealms();
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertTrue(realmAuthorizer.deletable());
-
-        Set<String> realms = realmAuthorizer.getDeletableRealms();
-        assertEquals(1, realms.size());
-        assertTrue(realms.contains("delete"));
-    }
-
-    @Test
-    public void testNotReadable() throws ServletException {
-        String[] roles = new String[]{"w-write", "d-delete", "u-update"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertFalse(realmAuthorizer.readable());
-
-        Set<String> realms = realmAuthorizer.getReadableRealms();
-        assertEquals(0, realms.size());
-    }
-
-    @Test
-    public void testNotWritable() throws ServletException {
-        String[] roles = new String[]{"r-read", "d-delete", "u-update"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertFalse(realmAuthorizer.writable());
-
-        Set<String> realms = realmAuthorizer.getWritableRealms();
-        assertEquals(0, realms.size());
-    }
-
-    @Test
-    public void testNotUpdatable() throws ServletException {
-        String[] roles = new String[]{"w-write", "d-delete", "r-read"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertFalse(realmAuthorizer.updatable());
-
-        Set<String> realms = realmAuthorizer.getUpdatableRealms();
-        assertEquals(0, realms.size());
-    }
-
-    @Test
-    public void testNotDeletable() throws ServletException {
-        String[] roles = new String[]{"w-write", "r-read", "u-update"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertFalse(realmAuthorizer.deletable());
-
-        Set<String> realms = realmAuthorizer.getDeletableRealms();
-        assertEquals(0, realms.size());
-    }
-
-    @Test
-    public void testRealmsHeaderSubset() throws ServletException {
-        String[] roles = new String[]{"w-write", "r-read", "u-update"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        when(request.getHeader(eq("X-Thermostat-Realms"))).thenReturn("read update");
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertEquals(1, realmAuthorizer.getReadableRealms().size());
-        assertEquals(1, realmAuthorizer.getUpdatableRealms().size());
-
-        assertEquals(0, realmAuthorizer.getWritableRealms().size());
-        assertEquals(0, realmAuthorizer.getDeletableRealms().size());
-    }
-
-    @Test (expected = ServletException.class)
-    public void testRealmsHeaderSuperset() throws ServletException {
-        String[] roles = new String[]{"r-read,","u-update"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        when(request.getHeader(eq("X-Thermostat-Realms"))).thenReturn("read update other");
-
-        new RealmAuthorizer(request);
-    }
-
-    @Test
-    public void testRealmsHeaderWhitespace() throws ServletException {
-        String[] roles = new String[]{"w-write", "r-read", "u-update"};
-        when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
-
-        when(request.getHeader(eq("X-Thermostat-Realms"))).thenReturn("  read  update\twrite    ");
-
-        RealmAuthorizer realmAuthorizer = new RealmAuthorizer(request);
-        assertEquals(1, realmAuthorizer.getReadableRealms().size());
-        assertEquals(1, realmAuthorizer.getUpdatableRealms().size());
-        assertEquals(1, realmAuthorizer.getWritableRealms().size());
-
-        assertEquals(0, realmAuthorizer.getDeletableRealms().size());
-    }
-
-}
--- a/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RoleFactoryTest.java	Mon Aug 21 08:57:27 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth.keycloak;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class RoleFactoryTest {
-
-    private RoleFactory roleFactory;
-
-    @Before
-    public void setup() {
-        roleFactory = new RoleFactory();
-    }
-
-    @Test
-    public void testValidRole() throws InvalidRoleException {
-        String role = "a-valid,role";
-        roleFactory.buildRole(role);
-
-        Set<String> actions = new HashSet<>();
-        actions.add("a");
-        Role r = roleFactory.buildRole(role);
-        verifyRole(r, actions, "valid,role");
-    }
-
-    @Test
-    public void testValidRoleWithActions() throws InvalidRoleException {
-        String role = "r,w,d-role";
-
-        Role r = roleFactory.buildRole(role);
-        Set<String> actions = new HashSet<>();
-        actions.add("r");
-        actions.add("w");
-        actions.add("d");
-        verifyRole(r, actions, "role");
-    }
-
-    @Test(expected = InvalidRoleException.class)
-    public void testNoActionRole() throws InvalidRoleException {
-        String role = "-role";
-        roleFactory.buildRole(role);
-    }
-
-    @Test(expected = InvalidRoleException.class)
-    public void testNoRealmRole() throws InvalidRoleException {
-        String role = "a-";
-        roleFactory.buildRole(role);
-    }
-
-    @Test
-    public void testHyphenRealm() throws InvalidRoleException {
-        String role = "a-realm-with-hyphens";
-
-        Role r = roleFactory.buildRole(role);
-        Set<String> actions = new HashSet<>();
-        actions.add("a");
-        verifyRole(r, actions, "realm-with-hyphens");
-    }
-
-    @Test(expected = InvalidRoleException.class)
-    public void testRealmWithWhitespaceIsInvalid() throws InvalidRoleException {
-        String role = "a-invalid \trealm";
-        roleFactory.buildRole(role);
-    }
-
-    @Test
-    public void testRealmWithLeadingWhitespace() throws InvalidRoleException {
-        String role = " a-role";
-
-        Role r = roleFactory.buildRole(role);
-        Set<String> actions = new HashSet<>();
-        actions.add("a");
-        verifyRole(r, actions, "role");
-    }
-
-    @Test
-    public void testRealmWithTrailingWhitespace() throws InvalidRoleException {
-        String role = "a-role\t";
-
-        Role r = roleFactory.buildRole(role);
-        Set<String> actions = new HashSet<>();
-        actions.add("a");
-        verifyRole(r, actions, "role");
-    }
-
-    private void verifyRole(Role role, Set<String> expectedActions, String expectedRole) {
-        for (String item : expectedActions) {
-            assertTrue(role.containsAction(item));
-        }
-        assertEquals(expectedRole, role.getRealm());
-    }
-}
--- a/common/core/src/test/java/com/redhat/thermostat/gateway/common/core/auth/keycloak/RoleTest.java	Mon Aug 21 08:57:27 2017 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright 2012-2017 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gateway.common.core.auth.keycloak;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.junit.Test;
-
-public class RoleTest {
-
-    @Test
-    public void testSimpleRole() {
-        Set<String> actions = new HashSet<>();
-        actions.add("a");
-        Role r = new Role(actions, "realm");
-
-        verifyRole(r, actions, "realm");
-    }
-
-    @Test
-    public void testMultipleActionsRole() {
-        Set<String> actions = new HashSet<>();
-        actions.add("a");
-        Role r = new Role(actions, "realm-1.2-3");
-
-        verifyRole(r, actions, "realm-1.2-3");
-    }
-
-    /*
-    Roles are added to set data structures which rely on the equals()
-    implementation to prevent duplicates
-     */
-    @Test
-    public void testEquals() {
-        Set<String> actionsOne = new HashSet<>();
-        actionsOne.add("a");
-
-        Role one = new Role(actionsOne, "b");
-        Role two = new Role(actionsOne, "b");
-
-        assertEquals(one, two);
-
-        Set<String> actionsTwo = new HashSet<>();
-        actionsTwo.add("a");
-
-        Role three = new Role(actionsTwo, "b");
-
-        assertEquals(one, three);
-    }
-
-    @Test
-    public void testNotEquals() {
-        Set<String> actionsOne = new HashSet<>();
-        actionsOne.add("a");
-
-        Set<String> actionsTwo = new HashSet<>();
-        actionsTwo.add("b");
-
-        Role one = new Role(actionsOne, "b");
-        Role two = new Role(actionsOne, "c");
-        Role three = new Role(actionsTwo, "b");
-
-        assertNotEquals(one, two);
-        assertNotEquals(one, three);
-    }
-
-    @Test(expected = UnsupportedOperationException.class)
-    public void testActionsCannotBeModified() {
-        Set<String> actions = new HashSet<>();
-        actions.add("a");
-        Role r = new Role(actions, "realm-1.2-3");
-
-        verifyRole(r, actions, "realm-1.2-3");
-
-        r.getActions().add("not-allowed");
-    }
-
-    private void verifyRole(Role role, Set<String> expectedActions, String expectedRole) {
-        for (String item : expectedActions) {
-            assertTrue(role.containsAction(item));
-        }
-        assertEquals(expectedRole, role.getRealm());
-    }
-}
--- a/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java	Mon Aug 21 08:57:27 2017 -0400
+++ b/common/mongodb/src/main/java/com/redhat/thermostat/gateway/common/mongodb/servlet/MongoHttpHandlerHelper.java	Mon Aug 21 16:44:08 2017 -0400
@@ -40,7 +40,7 @@
 import com.mongodb.MongoTimeoutException;
 import com.mongodb.MongoWriteException;
 
-import com.redhat.thermostat.gateway.common.core.auth.keycloak.RealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
 import com.redhat.thermostat.gateway.common.mongodb.ThermostatFields;
 import com.redhat.thermostat.gateway.common.mongodb.ThermostatMongoStorage;
 import com.redhat.thermostat.gateway.common.mongodb.executor.MongoDataResultContainer;
@@ -60,6 +60,7 @@
 import static com.redhat.thermostat.gateway.common.util.ServiceException.DATABASE_UNAVAILABLE;
 import static com.redhat.thermostat.gateway.common.util.ServiceException.EXPECTED_JSON_ARRAY;
 import static com.redhat.thermostat.gateway.common.util.ServiceException.MALFORMED_CLIENT_REQUEST;
+import static com.redhat.thermostat.gateway.common.util.ServiceException.UNEXPECTED_ERROR;
 
 public class MongoHttpHandlerHelper {
 
@@ -74,7 +75,8 @@
                 .add(UnsupportedOperationException.class, MALFORMED_CLIENT_REQUEST)
                 .add(ClassCastException.class, EXPECTED_JSON_ARRAY)
                 .add(MongoTimeoutException.class, DATABASE_UNAVAILABLE)
-                .add(IOException.class, CANNOT_QUERY_REALMS_PROPERTY);
+                .add(IOException.class, CANNOT_QUERY_REALMS_PROPERTY)
+                .add(NullPointerException.class, UNEXPECTED_ERROR);
     }
 
     /*
@@ -93,36 +95,30 @@
         try {
             boolean metadata = Boolean.valueOf(returnMetadata);
             RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
-            ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
 
-            MongoDataResultContainer execResult;
+            if (realmAuthorizer.readable()) {
+                ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
+
+                MongoDataResultContainer execResult = mongoExecutor.execGetRequest(
+                        storage.getDatabase().getCollection(collectionName), limit, offset, sort, queries, includes, excludes, realmAuthorizer.getReadableRealms());
 
-            if (realmAuthorizer != null) {
-                if (realmAuthorizer.readable()) {
-                    execResult = mongoExecutor.execGetRequest(
-                            storage.getDatabase().getCollection(collectionName), limit, offset, sort, queries, includes, excludes, realmAuthorizer.getReadableRealms());
-                } else {
-                    return Response.status(Response.Status.FORBIDDEN).build();
+                MongoResponseBuilder.Builder response = new MongoResponseBuilder.Builder();
+                response.addQueryDocuments(execResult.getQueryDataResult());
+                if (metadata) {
+                    MongoMetaDataResponseBuilder.MetaBuilder metaDataResponse = new MongoMetaDataResponseBuilder.MetaBuilder();
+                    MongoMetaDataGenerator metaDataGenerator = new MongoMetaDataGenerator(limit, offset, sort, queries,
+                            includes, excludes, httpServletRequest, execResult);
+
+                    metaDataGenerator.setDocAndPayloadCount(metaDataResponse);
+                    metaDataGenerator.setPrev(metaDataResponse);
+                    metaDataGenerator.setNext(metaDataResponse);
+
+                    response.addMetaData(metaDataResponse.build());
                 }
+                return Response.status(Response.Status.OK).entity(response.build()).build();
             } else {
-                execResult = mongoExecutor.execGetRequest(
-                        storage.getDatabase().getCollection(collectionName), limit, offset, sort, queries, includes, excludes, null);
+                return Response.status(Response.Status.FORBIDDEN).build();
             }
-
-            MongoResponseBuilder.Builder response = new MongoResponseBuilder.Builder();
-            response.addQueryDocuments(execResult.getQueryDataResult());
-            if (metadata) {
-                MongoMetaDataResponseBuilder.MetaBuilder metaDataResponse = new MongoMetaDataResponseBuilder.MetaBuilder();
-                MongoMetaDataGenerator metaDataGenerator = new MongoMetaDataGenerator(limit, offset, sort, queries,
-                        includes, excludes, httpServletRequest, execResult);
-
-                metaDataGenerator.setDocAndPayloadCount(metaDataResponse);
-                metaDataGenerator.setPrev(metaDataResponse);
-                metaDataGenerator.setNext(metaDataResponse);
-
-                response.addMetaData(metaDataResponse.build());
-            }
-            return Response.status(Response.Status.OK).entity(response.build()).build();
         } catch (Exception e) {
             return exceptionHandler.generateResponseForException(e);
         }
@@ -147,19 +143,16 @@
     public Response handlePut(HttpServletRequest httpServletRequest, ServletContext context, String systemId, String jvmId, String queries, String metadata, String body) {
         try {
             RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
-            ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
+
+            if (realmAuthorizer.updatable()) {
+                ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
 
-            if (realmAuthorizer != null) {
-                if (realmAuthorizer.updatable()) {
-                    mongoExecutor.execPutRequest(storage.getDatabase().getCollection(collectionName), body, queries, realmAuthorizer.getUpdatableRealms(), systemId, jvmId);
-                } else {
-                    return Response.status(Response.Status.FORBIDDEN).build();
-                }
+                mongoExecutor.execPutRequest(storage.getDatabase().getCollection(collectionName), body, queries, realmAuthorizer.getUpdatableRealms(), systemId, jvmId);
+
+                return Response.status(Response.Status.OK).build();
             } else {
-                mongoExecutor.execPutRequest(storage.getDatabase().getCollection(collectionName), body, queries, null, systemId, jvmId);
+                return Response.status(Response.Status.FORBIDDEN).build();
             }
-
-            return Response.status(Response.Status.OK).build();
         } catch (Exception e) {
             return exceptionHandler.generateResponseForException(e);
         }
@@ -180,18 +173,16 @@
     public Response handlePost(HttpServletRequest httpServletRequest, ServletContext context, String systemId, String jvmId, String metadata, String body) {
         try {
             RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
-            ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
+
+            if (realmAuthorizer.writable()) {
+                ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
 
-            if (realmAuthorizer != null) {
-                if (realmAuthorizer.writable()) {
-                    mongoExecutor.execPostRequest(storage.getDatabase().getCollection(collectionName, DBObject.class), body, realmAuthorizer.getWritableRealms(), systemId, jvmId);
-                } else {
-                    return Response.status(Response.Status.FORBIDDEN).build();
-                }
+                mongoExecutor.execPostRequest(storage.getDatabase().getCollection(collectionName, DBObject.class), body, realmAuthorizer.getWritableRealms(), systemId, jvmId);
+
+                return Response.status(Response.Status.OK).build();
             } else {
-                mongoExecutor.execPostRequest(storage.getDatabase().getCollection(collectionName, DBObject.class), body, null, systemId, jvmId);
+                return Response.status(Response.Status.FORBIDDEN).build();
             }
-            return Response.status(Response.Status.OK).build();
         } catch (Exception e) {
             return exceptionHandler.generateResponseForException(e);
         }
@@ -212,18 +203,16 @@
     public Response handleDelete(HttpServletRequest httpServletRequest, ServletContext context, String queries, String metadata) {
         try {
             RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
-            ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
+
+            if (realmAuthorizer.deletable()) {
+                ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
 
-            if (realmAuthorizer != null) {
-                if (realmAuthorizer.deletable()) {
-                    mongoExecutor.execDeleteRequest(storage.getDatabase().getCollection(collectionName), queries, realmAuthorizer.getDeletableRealms());
-                } else {
-                    return Response.status(Response.Status.FORBIDDEN).build();
-                }
+                mongoExecutor.execDeleteRequest(storage.getDatabase().getCollection(collectionName), queries, realmAuthorizer.getDeletableRealms());
+
+                return Response.status(Response.Status.OK).build();
             } else {
-                mongoExecutor.execDeleteRequest(storage.getDatabase().getCollection(collectionName), queries, null);
+                return Response.status(Response.Status.FORBIDDEN).build();
             }
-            return Response.status(Response.Status.OK).build();
         } catch (Exception e) {
             return exceptionHandler.generateResponseForException(e);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/server/src/main/java/com/redhat/thermostat/gateway/server/auth/DefaultAuthFilter.java	Mon Aug 21 16:44:08 2017 -0400
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012-2017 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.gateway.server.auth;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import com.redhat.thermostat.gateway.common.core.auth.DefaultRealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.InvalidRoleException;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
+
+public class DefaultAuthFilter implements Filter {
+    private RealmAuthorizer realmAuthorizer;
+
+    public DefaultAuthFilter() {
+        try {
+            realmAuthorizer = new DefaultRealmAuthorizer();
+        } catch (InvalidRoleException e) {
+            throw new IllegalStateException("Unable to create DefaultRealmAuthorizer", e);
+        }
+    }
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        // Do nothing
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
+        httpServletRequest.setAttribute(RealmAuthorizer.class.getName(), realmAuthorizer);
+
+        chain.doFilter(request, response);
+    }
+
+    @Override
+    public void destroy() {
+        // Do nothing
+    }
+}
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/auth/keycloak/KeycloakRequestFilter.java	Mon Aug 21 08:57:27 2017 -0400
+++ b/server/src/main/java/com/redhat/thermostat/gateway/server/auth/keycloak/KeycloakRequestFilter.java	Mon Aug 21 16:44:08 2017 -0400
@@ -47,7 +47,8 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import com.redhat.thermostat.gateway.common.core.auth.keycloak.RealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.keycloak.KeycloakRealmAuthorizer;
 
 public class KeycloakRequestFilter implements Filter {
     @Override
@@ -59,7 +60,7 @@
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
         try {
             HttpServletRequest httpServletRequest = (HttpServletRequest) request;
-            RealmAuthorizer realmAuthorizer = new RealmAuthorizer(httpServletRequest);
+            RealmAuthorizer realmAuthorizer = new KeycloakRealmAuthorizer(httpServletRequest);
 
             httpServletRequest.setAttribute(RealmAuthorizer.class.getName(), realmAuthorizer);
 
--- a/server/src/main/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreService.java	Mon Aug 21 08:57:27 2017 -0400
+++ b/server/src/main/java/com/redhat/thermostat/gateway/server/services/WebArchiveCoreService.java	Mon Aug 21 16:44:08 2017 -0400
@@ -59,6 +59,7 @@
 import com.redhat.thermostat.gateway.common.core.config.Configuration;
 import com.redhat.thermostat.gateway.common.core.config.ServiceConfiguration;
 import com.redhat.thermostat.gateway.common.core.servlet.GlobalConstants;
+import com.redhat.thermostat.gateway.server.auth.DefaultAuthFilter;
 import com.redhat.thermostat.gateway.server.auth.basic.BasicLoginService;
 import com.redhat.thermostat.gateway.server.auth.basic.BasicUserStore;
 import com.redhat.thermostat.gateway.server.auth.keycloak.KeycloakConfiguration;
@@ -86,6 +87,8 @@
 
         webAppContext.setAttribute(GlobalConstants.SERVICE_CONFIG_KEY, serviceConfig);
         webAppContext.addSystemClass(Configuration.class.getName());
+        webAppContext.addSystemClass("com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer");
+
 
         initializeWebSockets(server, webAppContext);
 
@@ -100,9 +103,15 @@
             setupBasicAuthForContext(webAppContext);
         } else if (isSet(ServiceConfiguration.ConfigurationKey.SECURITY_KEYCLOAK)) {
             setupKeycloakAuthForContext(webAppContext);
+        } else {
+            setupDefaultAuthForContext(webAppContext);
         }
     }
 
+    private void setupDefaultAuthForContext(WebAppContext webAppContext) {
+        webAppContext.addFilter(DefaultAuthFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
+    }
+
     private void setupKeycloakAuthForContext(WebAppContext webAppContext) {
         String keycloakConfig = (String) serviceConfig.asMap().get(ServiceConfiguration.ConfigurationKey.KEYCLOAK_CONFIG.name());
         KeycloakConfiguration keycloakConfiguration = new KeycloakConfigurationFactory().createKeycloakConfiguration(keycloakConfig);
@@ -128,7 +137,6 @@
         webAppContext.setInitParameter("org.keycloak.json.adapterConfig", keycloakConfig);
         webAppContext.setSecurityHandler(securityHandler);
         webAppContext.addSystemClass("org.keycloak.");
-        webAppContext.addSystemClass("com.redhat.thermostat.gateway.common.core.auth.keycloak.");
 
         webAppContext.addFilter(KeycloakRequestFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
     }
--- a/server/src/test/java/com/redhat/thermostat/gateway/server/auth/keycloak/KeycloakRequestFilterTest.java	Mon Aug 21 08:57:27 2017 -0400
+++ b/server/src/test/java/com/redhat/thermostat/gateway/server/auth/keycloak/KeycloakRequestFilterTest.java	Mon Aug 21 16:44:08 2017 -0400
@@ -57,7 +57,8 @@
 import org.keycloak.representations.AccessToken;
 import org.mockito.ArgumentMatchers;
 
-import com.redhat.thermostat.gateway.common.core.auth.keycloak.RealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
+import com.redhat.thermostat.gateway.common.core.auth.keycloak.KeycloakRealmAuthorizer;
 
 public class KeycloakRequestFilterTest {
 
@@ -90,7 +91,7 @@
 
         keycloakRequestFilter.doFilter(request, httpServletResponse, filterChain);
 
-        verify(request, times(1)).setAttribute(eq(RealmAuthorizer.class.getName()), ArgumentMatchers.any(RealmAuthorizer.class));
+        verify(request, times(1)).setAttribute(eq(RealmAuthorizer.class.getName()), ArgumentMatchers.any(KeycloakRealmAuthorizer.class));
 
         verify(filterChain, times(1)).doFilter(eq(request), eq(httpServletResponse));
     }
@@ -100,7 +101,7 @@
         String[] roles = new String[]{"a-realm"};
         when(access.getRoles()).thenReturn(new HashSet<>(Arrays.asList(roles)));
 
-        when(request.getHeader(eq(RealmAuthorizer.REALMS_HEADER))).thenReturn("blob");
+        when(request.getHeader(eq(KeycloakRealmAuthorizer.REALMS_HEADER))).thenReturn("blob");
 
         KeycloakRequestFilter keycloakRequestFilter = new KeycloakRequestFilter();
 
@@ -111,7 +112,7 @@
 
         verify(httpServletResponse, times(1)).sendError(eq(HttpServletResponse.SC_BAD_REQUEST), eq("Invalid realms header"));
 
-        verify(request, times(0)).setAttribute(eq(RealmAuthorizer.class.getName()), ArgumentMatchers.any(RealmAuthorizer.class));
+        verify(request, times(0)).setAttribute(eq(KeycloakRealmAuthorizer.class.getName()), ArgumentMatchers.any(KeycloakRealmAuthorizer.class));
 
         verify(filterChain, times(0)).doFilter(eq(request), eq(httpServletResponse));
     }
--- a/services/jvms/src/main/java/com/redhat/thermostat/gateway/service/jvms/http/JvmsHttpHandler.java	Mon Aug 21 08:57:27 2017 -0400
+++ b/services/jvms/src/main/java/com/redhat/thermostat/gateway/service/jvms/http/JvmsHttpHandler.java	Mon Aug 21 16:44:08 2017 -0400
@@ -40,6 +40,7 @@
 import static com.redhat.thermostat.gateway.common.util.ServiceException.DATABASE_UNAVAILABLE;
 import static com.redhat.thermostat.gateway.common.util.ServiceException.EXPECTED_JSON_ARRAY;
 import static com.redhat.thermostat.gateway.common.util.ServiceException.MALFORMED_CLIENT_REQUEST;
+import static com.redhat.thermostat.gateway.common.util.ServiceException.UNEXPECTED_ERROR;
 
 import java.io.IOException;
 
@@ -60,6 +61,7 @@
 
 import com.mongodb.MongoTimeoutException;
 import com.mongodb.MongoWriteException;
+import com.redhat.thermostat.gateway.common.core.auth.RealmAuthorizer;
 import com.redhat.thermostat.gateway.common.mongodb.servlet.RequestParameters;
 import com.redhat.thermostat.gateway.common.mongodb.ThermostatMongoStorage;
 import com.redhat.thermostat.gateway.common.mongodb.servlet.ServletContextConstants;
@@ -81,7 +83,8 @@
                         .add(UnsupportedOperationException.class, MALFORMED_CLIENT_REQUEST)
                         .add(ClassCastException.class, EXPECTED_JSON_ARRAY)
                         .add(MongoTimeoutException.class, DATABASE_UNAVAILABLE)
-                        .add(IOException.class, CANNOT_QUERY_REALMS_PROPERTY);
+                        .add(IOException.class, CANNOT_QUERY_REALMS_PROPERTY)
+                        .add(NullPointerException.class, UNEXPECTED_ERROR);
     }
 
     @GET
@@ -145,9 +148,15 @@
                                @Context HttpServletRequest httpServletRequest
     ) {
         try {
-            ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
-            String message = mongoStorageHandler.getJvmInfo(storage.getDatabase().getCollection(collectionName), systemId, jvmId, includes, excludes);
-            return Response.status(Response.Status.OK).entity(message).build();
+            RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
+
+            if (realmAuthorizer.readable()) {
+                ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
+                String message = mongoStorageHandler.getJvmInfo(storage.getDatabase().getCollection(collectionName), systemId, jvmId, includes, excludes);
+                return Response.status(Response.Status.OK).entity(message).build();
+            } else {
+                return Response.status(Response.Status.FORBIDDEN).build();
+            }
         } catch (Exception e) {
             return exceptionHandler.generateResponseForException(e);
         }
@@ -188,9 +197,15 @@
                                        @Context ServletContext context,
                                        @Context HttpServletRequest httpServletRequest) {
         try {
-            ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
-            mongoStorageHandler.updateTimestamps(storage.getDatabase().getCollection(collectionName), body, systemId, timeStamp);
-            return Response.status(Response.Status.OK).build();
+            RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
+
+            if (realmAuthorizer.updatable()) {
+                ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
+                mongoStorageHandler.updateTimestamps(storage.getDatabase().getCollection(collectionName), body, systemId, timeStamp);
+                return Response.status(Response.Status.OK).build();
+            } else {
+                return Response.status(Response.Status.FORBIDDEN).build();
+            }
         } catch (Exception e) {
             return exceptionHandler.generateResponseForException(e);
         }
@@ -206,11 +221,19 @@
                                    @QueryParam(RequestParameters.METADATA) @DefaultValue("false") String metadata,
                                    @QueryParam(RequestParameters.INCLUDE) String includes,
                                    @QueryParam(RequestParameters.EXCLUDE) String excludes,
-                                   @Context ServletContext context) {
+                                   @Context ServletContext context,
+                                   @Context HttpServletRequest httpServletRequest) {
         try {
-            ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
-            String message = mongoStorageHandler.getJvmsTree(storage.getDatabase().getCollection(collectionName), aliveOnly, excludes, includes, limit, offset);
-            return Response.status(Response.Status.OK).entity(message).build();
+            RealmAuthorizer realmAuthorizer = (RealmAuthorizer) httpServletRequest.getAttribute(RealmAuthorizer.class.getName());
+
+            if (realmAuthorizer.readable()) {
+                ThermostatMongoStorage storage = (ThermostatMongoStorage) context.getAttribute(ServletContextConstants.MONGODB_CLIENT_ATTRIBUTE);
+
+                String message = mongoStorageHandler.getJvmsTree(storage.getDatabase().getCollection(collectionName), aliveOnly, excludes, includes, limit, offset);
+                return Response.status(Response.Status.OK).entity(message).build();
+            } else {
+                return Response.status(Response.Status.FORBIDDEN).build();
+            }
         } catch (Exception e) {
             return exceptionHandler.generateResponseForException(e);
         }
--- a/services/jvms/src/main/java/com/redhat/thermostat/gateway/service/jvms/mongo/JvmInfoMongoStorageHandler.java	Mon Aug 21 08:57:27 2017 -0400
+++ b/services/jvms/src/main/java/com/redhat/thermostat/gateway/service/jvms/mongo/JvmInfoMongoStorageHandler.java	Mon Aug 21 16:44:08 2017 -0400
@@ -61,6 +61,7 @@
 import com.mongodb.util.JSON;
 import com.redhat.thermostat.gateway.common.mongodb.filters.MongoRequestFilters;
 import com.redhat.thermostat.gateway.common.mongodb.filters.MongoSortFilters;
+import com.redhat.thermostat.gateway.common.mongodb.keycloak.KeycloakFields;
 import com.redhat.thermostat.gateway.common.mongodb.response.ArgumentRunnable;
 import com.redhat.thermostat.gateway.common.mongodb.response.MongoResponseBuilder;
 
@@ -197,6 +198,7 @@
         documents.forEach(new Block<Document>() {
             @Override
             public void apply(Document document) {
+                document.remove(KeycloakFields.REALMS_KEY);
                 setIsAlive(document);
 
                 String systemId = document.getString(StorageFields.SYSTEM_ID);
--- a/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Mon Aug 21 08:57:27 2017 -0400
+++ b/tests/integration-tests/src/test/java/com/redhat/thermostat/gateway/service/jvm/gc/JvmGcServiceIntegrationTest.java	Mon Aug 21 16:44:08 2017 -0400
@@ -46,6 +46,7 @@
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeoutException;
 
+import com.redhat.thermostat.gateway.common.core.auth.DefaultRealmAuthorizer;
 import com.redhat.thermostat.gateway.common.mongodb.servlet.RequestParameters;
 import com.redhat.thermostat.gateway.tests.integration.MongoIntegrationTest;
 import org.bson.Document;
@@ -396,23 +397,23 @@
 
     @Test
     public void testUpdateOnlyRealmsDoesNotAffectRealms() throws InterruptedException, TimeoutException, ExecutionException {
-        MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
-        String data = "[{\"item\":1,\"realms\":[\"a\",\"b\"]}," +
-                "{\"item\":2,\"realms\":[\"a\",\"b\"]}]";
-        final Gson gson = new GsonBuilder().create();
-        final Type listType = new TypeToken<List<Document>>() {}.getType();
-        List<Document> insertDocuments = gson.fromJson(data, listType);
+        String data = "[{\"item\":1,}," +
+                "{\"item\":2}]";
 
-        collection.insertMany(insertDocuments);
+        makeHttpMethodRequest(HttpMethod.POST, "", data,
+                "application/json", "", 200);
 
         String updateString = "{\"set\" : {\"realms\" : 1}}";
         makeHttpMethodRequest(HttpMethod.PUT,"", updateString,"application/json","", 400);
 
+        MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
+        final Gson gson = new GsonBuilder().create();
+        final Type listType = new TypeToken<List<Document>>() {}.getType();
         FindIterable<Document> documents = collection.find();
         documents.forEach(new Block<Document>() {
             @Override
             public void apply(Document document) {
-                assertEquals("[\"a\",\"b\"]", gson.toJson(document.get("realms"), listType));
+                assertEquals(getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
             }
         });
     }
@@ -448,72 +449,61 @@
 
     @Test
     public void testUpdateMultipleRealmsDoesNotAffectRealms() throws InterruptedException, TimeoutException, ExecutionException {
-        MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
-        String data = "[{\"item\":1,\"realms\":[\"a\",\"b\"]}," +
-                "{\"item\":2,\"realms\":[\"a\",\"b\"]}]";
-        final Gson gson = new GsonBuilder().create();
-        final Type listType = new TypeToken<List<Document>>() {}.getType();
-        List<Document> insertDocuments = gson.fromJson(data, listType);
+        String data = "[{\"item\":1,}," +
+                "{\"item\":2}]";
 
-        collection.insertMany(insertDocuments);
+        makeHttpMethodRequest(HttpMethod.POST, "", data,
+                "application/json", "", 200);
 
         String updateString = "{\"set\" : {\"realms\" : 1, \"realms\" : 2}}";
         makeHttpMethodRequest(HttpMethod.PUT,"", updateString,"application/json","", 400);
 
+        MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
+        final Gson gson = new GsonBuilder().create();
+        final Type listType = new TypeToken<List<Document>>() {}.getType();
+
         FindIterable<Document> documents = collection.find();
         documents.forEach(new Block<Document>() {
             @Override
             public void apply(Document document) {
-                assertEquals("[\"a\",\"b\"]", gson.toJson(document.get("realms"), listType));
+                assertEquals(getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
             }
         });
     }
 
     @Test
     public void testGetCannotSeeRealms() throws InterruptedException, ExecutionException, TimeoutException {
-        MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
-        String data = "[{\"item\":1,\"realms\":[\"a\",\"b\"]}," +
-                "{\"item\":2,\"realms\":[\"a\",\"b\"]}]";
-        final Gson gson = new GsonBuilder().create();
-        final Type listType = new TypeToken<List<Document>>() {}.getType();
-        List<Document> insertDocuments = gson.fromJson(data, listType);
+        String data = "[{\"item\":1},{\"item\":2}]";
+        makeHttpMethodRequest(HttpMethod.POST, "", data,
+                "application/json", "", 200);
 
-        collection.insertMany(insertDocuments);
-
-        String expected = "{\"response\":[{\"item\":1.0}]}";
+        String expected = "{\"response\":[{\"item\":1}]}";
 
         makeHttpGetRequest(gcUrl,expected, 200);
     }
 
     @Test
     public void testGetProjectionCannotSeeRealms() throws InterruptedException, ExecutionException, TimeoutException {
-        MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
-        String data = "[{\"item\":1,\"realms\":[\"a\",\"b\"]}," +
-                "{\"item\":2,\"realms\":[\"a\",\"b\"]}]";
-        final Gson gson = new GsonBuilder().create();
-        final Type listType = new TypeToken<List<Document>>() {}.getType();
-        List<Document> insertDocuments = gson.fromJson(data, listType);
+        String data = "[{\"item\":1},{\"item\":2}]";
+        makeHttpMethodRequest(HttpMethod.POST, "", data,
+                "application/json", "", 200);
 
-        collection.insertMany(insertDocuments);
 
-        String expected = "{\"response\":[{\"item\":1.0}]}";
+        String expected = "{\"response\":[{\"item\":1}]}";
 
-        makeHttpGetRequest(gcUrl + "?" + RequestParameters.INCLUDE + "=realms,item",expected, 200);
+        makeHttpGetRequest(gcUrl + "?" + RequestParameters.INCLUDE + "=realms,item", expected, 200);
     }
 
     @Test
     public void testGetQueryCannotMatchRealms() throws InterruptedException, ExecutionException, TimeoutException {
-        MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
-        String data = "[{\"item\":1,\"realms\":[\"a\"]}," +
-                "{\"item\":2,\"realms\":[\"b\"]}]";
-        final Gson gson = new GsonBuilder().create();
-        final Type listType = new TypeToken<List<Document>>() {}.getType();
-        List<Document> insertDocuments = gson.fromJson(data, listType);
+        String data = "[{\"item\":1},{\"item\":2}]";
+        makeHttpMethodRequest(HttpMethod.POST, "", data,
+                "application/json", "", 200);
 
-        collection.insertMany(insertDocuments);
 
         ContentResponse response = client.newRequest(gcUrl)
-                .param(RequestParameters.QUERY, "realms==[\"a\"]").method(HttpMethod.GET).send();
+                .param(RequestParameters.QUERY, "realms==" + getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM))
+                .method(HttpMethod.GET).send();
 
         assertEquals(400, response.getStatus());
     }
@@ -527,12 +517,14 @@
         makeHttpMethodRequest(HttpMethod.POST, "", data, "application/json", "", 200);
 
         MongoCollection<Document> collection = mongodTestUtil.getCollection(serviceName);
+        final Gson gson = new GsonBuilder().create();
+        final Type listType = new TypeToken<List<Document>>() {}.getType();
 
         FindIterable<Document> documents = collection.find();
         documents.forEach(new Block<Document>() {
             @Override
             public void apply(Document document) {
-                assertNull(document.get("realms"));
+                assertEquals(getRealmArray(DefaultRealmAuthorizer.DEFAULT_REALM), gson.toJson(document.get("realms"), listType));
             }
         });
     }
@@ -561,4 +553,21 @@
             }
         });
     }
+
+    private String getRealmArray(String... realms) {
+        if (realms != null) {
+            StringBuilder arrayBuilder = new StringBuilder();
+            arrayBuilder.append("[");
+
+            for (String s : realms) {
+                arrayBuilder.append("\"" + s + "\",");
+            }
+            arrayBuilder.deleteCharAt(arrayBuilder.length() - 1);
+            arrayBuilder.append("]");
+
+            return arrayBuilder.toString();
+        } else {
+            return "[]";
+        }
+    }
 }