Skip to content

Commit

Permalink
[FGAP] First draft of Authorization Schema
Browse files Browse the repository at this point in the history
Closes keycloak#34569

Signed-off-by: vramik <[email protected]>
  • Loading branch information
vramik authored and pedroigor committed Nov 14, 2024
1 parent 79d914e commit 9050172
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2024 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.representations.idm.authorization;

import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

public class AuthorizationSchema {

private final Set<ResourceType> resourceTypes;

public AuthorizationSchema(ResourceType... resourceTypes) {
this.resourceTypes = Arrays.stream(resourceTypes).collect(Collectors.toSet());
}

public Set<ResourceType> getResourceTypes() {
return Collections.unmodifiableSet(resourceTypes);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2024 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.representations.idm.authorization;

import java.util.Arrays;
import java.util.HashSet;

public class FineGrainedAdminPermissionsAuthorizationSchema extends AuthorizationSchema {

public static final FineGrainedAdminPermissionsAuthorizationSchema INSTANCE = new FineGrainedAdminPermissionsAuthorizationSchema();

private FineGrainedAdminPermissionsAuthorizationSchema() {
super(new ResourceType("Users", new HashSet<>(Arrays.asList("manage"))));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class ResourceServerRepresentation {
private List<PolicyRepresentation> policies = emptyList();
private List<ScopeRepresentation> scopes = emptyList();
private DecisionStrategy decisionStrategy;
private AuthorizationSchema authorizationSchema;

public void setId(String id) {
this.id = id;
Expand Down Expand Up @@ -107,4 +108,12 @@ public void setDecisionStrategy(DecisionStrategy decisionStrategy) {
public DecisionStrategy getDecisionStrategy() {
return decisionStrategy;
}

public void setAuthorizationSchema(FineGrainedAdminPermissionsAuthorizationSchema authorizationSchema) {
this.authorizationSchema = authorizationSchema;
}

public AuthorizationSchema getAuthorizationSchema() {
return authorizationSchema;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2024 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.representations.idm.authorization;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collections;
import java.util.Set;

public class ResourceType {
private final String type;
private final Set<String> scopes;

@JsonCreator
public ResourceType(@JsonProperty("type") String type, @JsonProperty("scopes") Set<String> scopes) {
this.type = type;
this.scopes = Collections.unmodifiableSet(scopes);
}

public String getType() {
return type;
}

public Set<String> getScopes() {
return Collections.unmodifiableSet(scopes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,7 @@ public static ResourceServerRepresentation toRepresentation(ResourceServer model
server.setAllowRemoteResourceManagement(model.isAllowRemoteResourceManagement());
server.setPolicyEnforcementMode(model.getPolicyEnforcementMode());
server.setDecisionStrategy(model.getDecisionStrategy());
server.setAuthorizationSchema(Profile.isFeatureEnabled(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ_V2) ? FineGrainedAdminPermissionsAuthorizationSchema.INSTANCE : null);

return server;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright 2024 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.authz.admin;

import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import org.junit.Test;
import org.keycloak.common.Profile;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.util.ClientBuilder;

public class FineGrainedAdminPermissionsTest extends AbstractTestRealmKeycloakTest {

private final String CLIENT_ID = "fgap-client";

@Override
public void configureTestRealm(RealmRepresentation testRealm) {
testRealm.getClients().add(ClientBuilder.create()
.clientId(CLIENT_ID)
.serviceAccount()
.authorizationServicesEnabled(true)
.build());
}

@Test
public void authorizationSchemaNotAvailableFeatureDisabled() {
List<ClientRepresentation> clients = testRealm().clients().findByClientId(CLIENT_ID);
assertThat(clients, hasSize(1));
ResourceServerRepresentation authorizationSettings = testRealm().clients().get(clients.get(0).getId()).authorization().getSettings();
assertThat(authorizationSettings, notNullValue());
assertThat(authorizationSettings.getAuthorizationSchema(), nullValue());
}

@Test
@EnableFeature(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ)
public void authorizationSchemaNotAvailableFeatureV1Enabled() throws Exception {
reconnectAdminClient();
List<ClientRepresentation> clients = testRealm().clients().findByClientId(CLIENT_ID);
assertThat(clients, hasSize(1));
ResourceServerRepresentation authorizationSettings = testRealm().clients().get(clients.get(0).getId()).authorization().getSettings();
assertThat(authorizationSettings, notNullValue());
assertThat(authorizationSettings.getAuthorizationSchema(), nullValue());
}

@Test
@EnableFeature(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ_V2)
public void authorizationSchemaAvailableFeatureV2Enabled() throws Exception {
reconnectAdminClient();
List<ClientRepresentation> clients = testRealm().clients().findByClientId(CLIENT_ID);
assertThat(clients, hasSize(1));
ResourceServerRepresentation authorizationSettings = testRealm().clients().get(clients.get(0).getId()).authorization().getSettings();
assertThat(authorizationSettings, notNullValue());
assertThat(authorizationSettings.getAuthorizationSchema(), notNullValue());
}
}

0 comments on commit 9050172

Please sign in to comment.