KEYCLOAK-3666 client registration policies - polishing
This commit is contained in:
parent
4136d76b7e
commit
3779bfb6b4
28 changed files with 66 additions and 735 deletions
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClientRegistrationTrustedHostRepresentation {
|
||||
|
||||
String hostName;
|
||||
Integer count;
|
||||
Integer remainingCount;
|
||||
|
||||
public static ClientRegistrationTrustedHostRepresentation create(String hostName, int count, int remainingCount) {
|
||||
ClientRegistrationTrustedHostRepresentation rep = new ClientRegistrationTrustedHostRepresentation();
|
||||
rep.setHostName(hostName);
|
||||
rep.setCount(count);
|
||||
rep.setRemainingCount(remainingCount);
|
||||
return rep;
|
||||
}
|
||||
|
||||
public String getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
||||
public void setHostName(String hostName) {
|
||||
this.hostName = hostName;
|
||||
}
|
||||
|
||||
public Integer getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Integer count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public Integer getRemainingCount() {
|
||||
return remainingCount;
|
||||
}
|
||||
|
||||
public void setRemainingCount(Integer remainingCount) {
|
||||
this.remainingCount = remainingCount;
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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.admin.client.resource;
|
||||
|
||||
import org.keycloak.representations.idm.ClientRegistrationTrustedHostRepresentation;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClientRegistrationTrustedHostResource {
|
||||
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Response create(ClientRegistrationTrustedHostRepresentation config);
|
||||
|
||||
@PUT
|
||||
@Path("{hostname}")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Response update(final @PathParam("hostname") String hostName, ClientRegistrationTrustedHostRepresentation config);
|
||||
|
||||
@GET
|
||||
@Path("{hostname}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
ClientRegistrationTrustedHostRepresentation get(final @PathParam("hostname") String hostName);
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
List<ClientRegistrationTrustedHostRepresentation> list();
|
||||
|
||||
@DELETE
|
||||
@Path("{hostname}")
|
||||
void delete(final @PathParam("hostname") String hostName);
|
||||
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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.models.sessions.infinispan;
|
||||
|
||||
import org.infinispan.Cache;
|
||||
import org.keycloak.models.ClientRegistrationTrustedHostModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.sessions.infinispan.entities.ClientRegistrationTrustedHostEntity;
|
||||
import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClientRegistrationTrustedHostAdapter implements ClientRegistrationTrustedHostModel {
|
||||
|
||||
private final KeycloakSession session;
|
||||
private final InfinispanUserSessionProvider provider;
|
||||
private final Cache<String, SessionEntity> cache;
|
||||
private final RealmModel realm;
|
||||
private final ClientRegistrationTrustedHostEntity entity;
|
||||
|
||||
public ClientRegistrationTrustedHostAdapter(KeycloakSession session, InfinispanUserSessionProvider provider, Cache<String, SessionEntity> cache, RealmModel realm, ClientRegistrationTrustedHostEntity entity) {
|
||||
this.session = session;
|
||||
this.provider = provider;
|
||||
this.cache = cache;
|
||||
this.realm = realm;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RealmModel getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostName() {
|
||||
return entity.getHostName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return entity.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCount(int count) {
|
||||
entity.setCount(count);
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRemainingCount() {
|
||||
return entity.getRemainingCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRemainingCount(int remainingCount) {
|
||||
entity.setRemainingCount(remainingCount);
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decreaseRemainingCount() {
|
||||
entity.setRemainingCount(entity.getRemainingCount() - 1);
|
||||
update();
|
||||
}
|
||||
|
||||
void update() {
|
||||
provider.getTx().replace(cache, entity.getId(), entity);
|
||||
}
|
||||
}
|
|
@ -23,11 +23,9 @@ import org.jboss.logging.Logger;
|
|||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.ClientInitialAccessModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientRegistrationTrustedHostModel;
|
||||
import org.keycloak.models.ClientSessionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakTransaction;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserLoginFailureModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
@ -35,14 +33,12 @@ import org.keycloak.models.UserSessionModel;
|
|||
import org.keycloak.models.UserSessionProvider;
|
||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||
import org.keycloak.models.sessions.infinispan.entities.ClientInitialAccessEntity;
|
||||
import org.keycloak.models.sessions.infinispan.entities.ClientRegistrationTrustedHostEntity;
|
||||
import org.keycloak.models.sessions.infinispan.entities.ClientSessionEntity;
|
||||
import org.keycloak.models.sessions.infinispan.entities.LoginFailureEntity;
|
||||
import org.keycloak.models.sessions.infinispan.entities.LoginFailureKey;
|
||||
import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
|
||||
import org.keycloak.models.sessions.infinispan.entities.UserSessionEntity;
|
||||
import org.keycloak.models.sessions.infinispan.stream.ClientInitialAccessPredicate;
|
||||
import org.keycloak.models.sessions.infinispan.stream.ClientRegistrationTrustedHostPredicate;
|
||||
import org.keycloak.models.sessions.infinispan.stream.ClientSessionPredicate;
|
||||
import org.keycloak.models.sessions.infinispan.stream.Comparators;
|
||||
import org.keycloak.models.sessions.infinispan.stream.Mappers;
|
||||
|
@ -540,12 +536,6 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
|||
return entity != null ? new ClientInitialAccessAdapter(session, this, cache, realm, entity) : null;
|
||||
}
|
||||
|
||||
ClientRegistrationTrustedHostAdapter wrap(RealmModel realm, ClientRegistrationTrustedHostEntity entity) {
|
||||
Cache<String, SessionEntity> cache = getCache(false);
|
||||
return entity != null ? new ClientRegistrationTrustedHostAdapter(session, this, cache, realm, entity) : null;
|
||||
}
|
||||
|
||||
|
||||
UserLoginFailureModel wrap(LoginFailureKey key, LoginFailureEntity entity) {
|
||||
return entity != null ? new UserLoginFailureAdapter(this, loginFailureCache, key, entity) : null;
|
||||
}
|
||||
|
@ -737,62 +727,6 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
|||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientRegistrationTrustedHostModel createClientRegistrationTrustedHostModel(RealmModel realm, String hostName, int count) {
|
||||
if (getClientRegistrationTrustedHostModel(realm, hostName) != null) {
|
||||
throw new ModelDuplicateException("Client registration already exists for this realm and hostName");
|
||||
}
|
||||
|
||||
String id = computeClientRegistrationTrustedHostEntityId(realm, hostName);
|
||||
|
||||
ClientRegistrationTrustedHostEntity entity = new ClientRegistrationTrustedHostEntity();
|
||||
entity.setId(id);
|
||||
entity.setHostName(hostName);
|
||||
entity.setRealm(realm.getId());
|
||||
entity.setCount(count);
|
||||
entity.setRemainingCount(count);
|
||||
|
||||
tx.put(sessionCache, id, entity);
|
||||
|
||||
return wrap(realm, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientRegistrationTrustedHostModel getClientRegistrationTrustedHostModel(RealmModel realm, String hostName) {
|
||||
String id = computeClientRegistrationTrustedHostEntityId(realm, hostName);
|
||||
|
||||
Cache<String, SessionEntity> cache = getCache(false);
|
||||
ClientRegistrationTrustedHostEntity entity = (ClientRegistrationTrustedHostEntity) cache.get(id);
|
||||
|
||||
// If created in this transaction
|
||||
if (entity == null) {
|
||||
entity = (ClientRegistrationTrustedHostEntity) tx.get(cache, id);
|
||||
}
|
||||
|
||||
return wrap(realm, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeClientRegistrationTrustedHostModel(RealmModel realm, String hostName) {
|
||||
String id = computeClientRegistrationTrustedHostEntityId(realm, hostName);
|
||||
tx.remove(getCache(false), id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ClientRegistrationTrustedHostModel> listClientRegistrationTrustedHosts(RealmModel realm) {
|
||||
Iterator<Map.Entry<String, SessionEntity>> itr = sessionCache.entrySet().stream().filter(ClientRegistrationTrustedHostPredicate.create(realm.getId())).iterator();
|
||||
List<ClientRegistrationTrustedHostModel> list = new LinkedList<>();
|
||||
while (itr.hasNext()) {
|
||||
list.add(wrap(realm, (ClientRegistrationTrustedHostEntity) itr.next().getValue()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static final String CLIENT_REG_TRUSTED_HOST_ID_PREFIX = "reg:::";
|
||||
|
||||
private String computeClientRegistrationTrustedHostEntityId(RealmModel realm, String hostName) {
|
||||
return CLIENT_REG_TRUSTED_HOST_ID_PREFIX + realm.getId() + ":::" + hostName;
|
||||
}
|
||||
|
||||
class InfinispanKeycloakTransaction implements KeycloakTransaction {
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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.models.sessions.infinispan.entities;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClientRegistrationTrustedHostEntity extends SessionEntity {
|
||||
|
||||
private String hostName;
|
||||
|
||||
private int count;
|
||||
|
||||
private int remainingCount;
|
||||
|
||||
public String getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
||||
public void setHostName(String hostName) {
|
||||
this.hostName = hostName;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(int count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public int getRemainingCount() {
|
||||
return remainingCount;
|
||||
}
|
||||
|
||||
public void setRemainingCount(int remainingCount) {
|
||||
this.remainingCount = remainingCount;
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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.models.sessions.infinispan.stream;
|
||||
|
||||
import org.keycloak.models.sessions.infinispan.entities.ClientRegistrationTrustedHostEntity;
|
||||
import org.keycloak.models.sessions.infinispan.entities.SessionEntity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClientRegistrationTrustedHostPredicate implements Predicate<Map.Entry<String, SessionEntity>>, Serializable {
|
||||
|
||||
public static ClientRegistrationTrustedHostPredicate create(String realm) {
|
||||
return new ClientRegistrationTrustedHostPredicate(realm);
|
||||
}
|
||||
|
||||
private ClientRegistrationTrustedHostPredicate(String realm) {
|
||||
this.realm = realm;
|
||||
}
|
||||
|
||||
private String realm;
|
||||
|
||||
|
||||
@Override
|
||||
public boolean test(Map.Entry<String, SessionEntity> entry) {
|
||||
SessionEntity e = entry.getValue();
|
||||
|
||||
if (!realm.equals(e.getRealm())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(e instanceof ClientRegistrationTrustedHostEntity)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -61,4 +61,6 @@ public interface Details {
|
|||
String SIGNATURE_REQUIRED = "signature_required";
|
||||
String SIGNATURE_ALGORITHM = "signature_algorithm";
|
||||
|
||||
String CLIENT_REGISTRATION_POLICY = "client_registration_policy";
|
||||
|
||||
}
|
||||
|
|
|
@ -128,11 +128,6 @@ public enum ResourceType {
|
|||
*/
|
||||
, CLIENT_INITIAL_ACCESS_MODEL
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
, CLIENT_REGISTRATION_TRUSTED_HOST_MODEL
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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.models;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public interface ClientRegistrationTrustedHostModel {
|
||||
|
||||
RealmModel getRealm();
|
||||
|
||||
String getHostName();
|
||||
|
||||
int getCount();
|
||||
void setCount(int count);
|
||||
|
||||
int getRemainingCount();
|
||||
void setRemainingCount(int remainingCount);
|
||||
void decreaseRemainingCount();
|
||||
|
||||
}
|
|
@ -82,11 +82,6 @@ public interface UserSessionProvider extends Provider {
|
|||
void removeClientInitialAccessModel(RealmModel realm, String id);
|
||||
List<ClientInitialAccessModel> listClientInitialAccess(RealmModel realm);
|
||||
|
||||
ClientRegistrationTrustedHostModel createClientRegistrationTrustedHostModel(RealmModel realm, String hostName, int count);
|
||||
ClientRegistrationTrustedHostModel getClientRegistrationTrustedHostModel(RealmModel realm, String hostName);
|
||||
void removeClientRegistrationTrustedHostModel(RealmModel realm, String hostName);
|
||||
List<ClientRegistrationTrustedHostModel> listClientRegistrationTrustedHosts(RealmModel realm);
|
||||
|
||||
void close();
|
||||
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ public class ConfigurationValidationHelper {
|
|||
|
||||
String val = model.getConfig().getFirst(key);
|
||||
if (val != null && !(val.equals("true") || val.equals("false"))) {
|
||||
throw new ComponentValidationException("''{0}'' should be 'true' or 'false'", label);
|
||||
throw new ComponentValidationException("''{0}'' should be ''true'' or ''false''", label);
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
@ -434,8 +434,21 @@ public interface ServicesLogger extends BasicLogger {
|
|||
@Message(id=97, value="Invalid request")
|
||||
void invalidRequest(@Cause Throwable t);
|
||||
|
||||
@LogMessage(level = ERROR)
|
||||
@Message(id=98, value="Failed to get redirect uris from sector identifier URI: %s")
|
||||
void failedToGetRedirectUrisFromSectorIdentifierUri(@Cause Throwable t, String sectorIdentifierUri);
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(id=99, value="Operation '%s' rejected. %s")
|
||||
void clientRegistrationRequestRejected(String opDescription, String detailedMessage);
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(id=100, value= "ProtocolMapper '%s' of type '%s' not allowed")
|
||||
void clientRegistrationMapperNotAllowed(String mapperName, String mapperType);
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(id=101, value= "Failed to verify remote host : %s")
|
||||
void failedToVerifyRemoteHost(String hostname);
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(id=102, value= "URL '%s' doesn't match any trustedHost or trustedDomain")
|
||||
void urlDoesntMatch(String url);
|
||||
|
||||
}
|
||||
|
|
|
@ -170,6 +170,11 @@ public abstract class AbstractClientRegistrationProvider implements ClientRegist
|
|||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventBuilder getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
|
|
@ -75,6 +75,11 @@ public class AdapterInstallationClientRegistrationProvider implements ClientRegi
|
|||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EventBuilder getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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.services.clientregistration;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.models.ClientRegistrationTrustedHostModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClientRegistrationHostUtils {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ClientRegistrationHostUtils.class);
|
||||
|
||||
/**
|
||||
* @return null if host from request is not trusted. Otherwise return trusted host model
|
||||
*
|
||||
* TODO: Remove
|
||||
*/
|
||||
public static ClientRegistrationTrustedHostModel getTrustedHost(String hostAddress, KeycloakSession session, RealmModel realm) {
|
||||
logger.debugf("Verifying remote host : %s", hostAddress);
|
||||
|
||||
List<ClientRegistrationTrustedHostModel> trustedHosts = session.sessions().listClientRegistrationTrustedHosts(realm);
|
||||
|
||||
for (ClientRegistrationTrustedHostModel realmTrustedHost : trustedHosts) {
|
||||
try {
|
||||
if (realmTrustedHost.getRemainingCount() <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String realmHostIPAddress = InetAddress.getByName(realmTrustedHost.getHostName()).getHostAddress();
|
||||
logger.debugf("Trying host '%s' of address '%s'", realmTrustedHost.getHostName(), realmHostIPAddress);
|
||||
if (realmHostIPAddress.equals(hostAddress)) {
|
||||
logger.debugf("Successfully verified host : %s", realmTrustedHost.getHostName());
|
||||
return realmTrustedHost;
|
||||
}
|
||||
} catch (UnknownHostException uhe) {
|
||||
logger.debugf("Unknown host from realm configuration: %s", realmTrustedHost.getHostName());
|
||||
}
|
||||
}
|
||||
|
||||
logger.debugf("Failed to verify remote host : %s", hostAddress);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -31,4 +31,6 @@ public interface ClientRegistrationProvider extends Provider {
|
|||
|
||||
void setEvent(EventBuilder event);
|
||||
|
||||
EventBuilder getEvent();
|
||||
|
||||
}
|
||||
|
|
|
@ -18,13 +18,16 @@
|
|||
package org.keycloak.services.clientregistration.policy;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.services.ServicesLogger;
|
||||
import org.keycloak.services.clientregistration.ClientRegistrationContext;
|
||||
import org.keycloak.services.clientregistration.ClientRegistrationProvider;
|
||||
|
||||
|
@ -36,7 +39,7 @@ public class ClientRegistrationPolicyManager {
|
|||
private static final Logger logger = Logger.getLogger(ClientRegistrationPolicyManager.class);
|
||||
|
||||
public static void triggerBeforeRegister(ClientRegistrationContext context, RegistrationAuth authType) throws ClientRegistrationPolicyException {
|
||||
triggerPolicies(context.getSession(), authType, "before register client", (ClientRegistrationPolicy policy) -> {
|
||||
triggerPolicies(context.getSession(), context.getProvider(), authType, "before register client", (ClientRegistrationPolicy policy) -> {
|
||||
|
||||
policy.beforeRegister(context);
|
||||
|
||||
|
@ -46,7 +49,7 @@ public class ClientRegistrationPolicyManager {
|
|||
|
||||
public static void triggerAfterRegister(ClientRegistrationContext context, RegistrationAuth authType, ClientModel client) {
|
||||
try {
|
||||
triggerPolicies(context.getSession(), authType, "after register client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
triggerPolicies(context.getSession(), context.getProvider(), authType, "after register client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
|
||||
policy.afterRegister(context, client);
|
||||
|
||||
|
@ -58,7 +61,7 @@ public class ClientRegistrationPolicyManager {
|
|||
|
||||
|
||||
public static void triggerBeforeUpdate(ClientRegistrationContext context, RegistrationAuth authType, ClientModel client) throws ClientRegistrationPolicyException {
|
||||
triggerPolicies(context.getSession(), authType, "before update client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
triggerPolicies(context.getSession(), context.getProvider(), authType, "before update client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
|
||||
policy.beforeUpdate(context, client);
|
||||
|
||||
|
@ -67,7 +70,7 @@ public class ClientRegistrationPolicyManager {
|
|||
|
||||
public static void triggerAfterUpdate(ClientRegistrationContext context, RegistrationAuth authType, ClientModel client) {
|
||||
try {
|
||||
triggerPolicies(context.getSession(), authType, "after update client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
triggerPolicies(context.getSession(), context.getProvider(), authType, "after update client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
|
||||
policy.afterUpdate(context, client);
|
||||
|
||||
|
@ -78,7 +81,7 @@ public class ClientRegistrationPolicyManager {
|
|||
}
|
||||
|
||||
public static void triggerBeforeView(KeycloakSession session, ClientRegistrationProvider provider, RegistrationAuth authType, ClientModel client) throws ClientRegistrationPolicyException {
|
||||
triggerPolicies(session, authType, "before view client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
triggerPolicies(session, provider, authType, "before view client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
|
||||
policy.beforeView(provider, client);
|
||||
|
||||
|
@ -86,7 +89,7 @@ public class ClientRegistrationPolicyManager {
|
|||
}
|
||||
|
||||
public static void triggerBeforeRemove(KeycloakSession session, ClientRegistrationProvider provider, RegistrationAuth authType, ClientModel client) throws ClientRegistrationPolicyException {
|
||||
triggerPolicies(session, authType, "before delete client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
triggerPolicies(session, provider, authType, "before delete client " + client.getClientId(), (ClientRegistrationPolicy policy) -> {
|
||||
|
||||
policy.beforeDelete(provider, client);
|
||||
|
||||
|
@ -95,7 +98,7 @@ public class ClientRegistrationPolicyManager {
|
|||
|
||||
|
||||
|
||||
private static void triggerPolicies(KeycloakSession session, RegistrationAuth authType, String opDescription, ClientRegOperation op) throws ClientRegistrationPolicyException {
|
||||
private static void triggerPolicies(KeycloakSession session, ClientRegistrationProvider provider, RegistrationAuth authType, String opDescription, ClientRegOperation op) throws ClientRegistrationPolicyException {
|
||||
RealmModel realm = session.getContext().getRealm();
|
||||
|
||||
String policyTypeKey = getComponentTypeKey(authType);
|
||||
|
@ -113,14 +116,16 @@ public class ClientRegistrationPolicyManager {
|
|||
throw new ClientRegistrationPolicyException("Policy of type '" + policyModel.getProviderId() + "' not found");
|
||||
}
|
||||
|
||||
// TODO: trace
|
||||
logger.infof("Running policy '%s' %s", policyModel.getName(), opDescription);
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.tracef("Running policy '%s' %s", policyModel.getName(), opDescription);
|
||||
}
|
||||
|
||||
try {
|
||||
op.run(policy);
|
||||
} catch (ClientRegistrationPolicyException crpe) {
|
||||
provider.getEvent().detail(Details.CLIENT_REGISTRATION_POLICY, policyModel.getName());
|
||||
crpe.setPolicyModel(policyModel);
|
||||
logger.warnf("Operation '%s' rejected. %s", opDescription, crpe.getMessage());
|
||||
ServicesLogger.LOGGER.clientRegistrationRequestRejected(opDescription, crpe.getMessage());
|
||||
throw crpe;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,8 +35,6 @@ import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyE
|
|||
*/
|
||||
public class ClientTemplatesClientRegistrationPolicy implements ClientRegistrationPolicy {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ClientTemplatesClientRegistrationPolicy.class);
|
||||
|
||||
private final KeycloakSession session;
|
||||
private final ComponentModel componentModel;
|
||||
|
||||
|
|
|
@ -18,17 +18,15 @@
|
|||
package org.keycloak.services.clientregistration.policy.impl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.services.ServicesLogger;
|
||||
import org.keycloak.services.clientregistration.ClientRegistrationContext;
|
||||
import org.keycloak.services.clientregistration.ClientRegistrationProvider;
|
||||
import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy;
|
||||
|
@ -66,7 +64,7 @@ public class ProtocolMappersClientRegistrationPolicy implements ClientRegistrati
|
|||
String mapperType = mapper.getProtocolMapper();
|
||||
|
||||
if (!allowedMapperProviders.contains(mapperType)) {
|
||||
logger.warnf("ProtocolMapper '%s' of type '%s' not allowed", mapper.getName(), mapperType);
|
||||
ServicesLogger.LOGGER.clientRegistrationMapperNotAllowed(mapper.getName(), mapperType);
|
||||
throw new ClientRegistrationPolicyException("ProtocolMapper type not allowed");
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +73,7 @@ public class ProtocolMappersClientRegistrationPolicy implements ClientRegistrati
|
|||
|
||||
protected void enableConsentRequiredForAll(ClientModel clientModel) {
|
||||
if (isConsentRequiredForMappers()) {
|
||||
// TODO: Debug
|
||||
logger.infof("Enable consentRequired for all protocol mappers of client %s", clientModel.getClientId());
|
||||
logger.debugf("Enable consentRequired for all protocol mappers of client %s", clientModel.getClientId());
|
||||
|
||||
Set<ProtocolMapperModel> mappers = clientModel.getProtocolMappers();
|
||||
|
||||
|
@ -105,8 +102,7 @@ public class ProtocolMappersClientRegistrationPolicy implements ClientRegistrati
|
|||
|
||||
}).forEach((ProtocolMapperModel mapperToRemove) -> {
|
||||
|
||||
// TODO: debug
|
||||
logger.infof("Removing builtin mapper '%s' of type '%s' as type is not permitted", mapperToRemove.getName(), mapperToRemove.getProtocolMapper());
|
||||
logger.debugf("Removing builtin mapper '%s' of type '%s' as type is not permitted", mapperToRemove.getName(), mapperToRemove.getProtocolMapper());
|
||||
clientModel.removeProtocolMapper(mapperToRemove);
|
||||
|
||||
});
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.keycloak.models.ClientModel;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.protocol.oidc.utils.PairwiseSubMapperUtils;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.services.ServicesLogger;
|
||||
import org.keycloak.services.clientregistration.ClientRegistrationContext;
|
||||
import org.keycloak.services.clientregistration.ClientRegistrationProvider;
|
||||
import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy;
|
||||
|
@ -95,8 +96,7 @@ public class TrustedHostClientRegistrationPolicy implements ClientRegistrationPo
|
|||
|
||||
String hostAddress = session.getContext().getConnection().getRemoteAddr();
|
||||
|
||||
// TODO: debug
|
||||
logger.infof("Verifying remote host : %s", hostAddress);
|
||||
logger.debugf("Verifying remote host : %s", hostAddress);
|
||||
|
||||
List<String> trustedHosts = getTrustedHosts();
|
||||
List<String> trustedDomains = getTrustedDomains();
|
||||
|
@ -113,7 +113,7 @@ public class TrustedHostClientRegistrationPolicy implements ClientRegistrationPo
|
|||
return;
|
||||
}
|
||||
|
||||
logger.warnf("Failed to verify remote host : %s", hostAddress);
|
||||
ServicesLogger.LOGGER.failedToVerifyRemoteHost(hostAddress);
|
||||
throw new ClientRegistrationPolicyException("Host not trusted.");
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ public class TrustedHostClientRegistrationPolicy implements ClientRegistrationPo
|
|||
return confHostName;
|
||||
}
|
||||
} catch (UnknownHostException uhe) {
|
||||
logger.warnf("Unknown host from realm configuration: %s", confHostName);
|
||||
logger.debugf(uhe, "Unknown host from realm configuration: %s", confHostName);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,8 +167,7 @@ public class TrustedHostClientRegistrationPolicy implements ClientRegistrationPo
|
|||
try {
|
||||
String hostname = InetAddress.getByName(hostAddress).getHostName();
|
||||
|
||||
// TODO: Debug
|
||||
logger.infof("Trying verify request from address '%s' of host '%s' by domains", hostAddress, hostname);
|
||||
logger.debugf("Trying verify request from address '%s' of host '%s' by domains", hostAddress, hostname);
|
||||
|
||||
for (String confDomain : trustedDomains) {
|
||||
if (hostname.endsWith(confDomain)) {
|
||||
|
@ -177,7 +176,7 @@ public class TrustedHostClientRegistrationPolicy implements ClientRegistrationPo
|
|||
}
|
||||
}
|
||||
} catch (UnknownHostException uhe) {
|
||||
logger.warnf("Request of address '%s' came from unknown host. Skip verification by domains", hostAddress);
|
||||
logger.debugf(uhe, "Request of address '%s' came from unknown host. Skip verification by domains", hostAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -237,11 +236,11 @@ public class TrustedHostClientRegistrationPolicy implements ClientRegistrationPo
|
|||
}
|
||||
}
|
||||
} catch (MalformedURLException mfe) {
|
||||
logger.warnf("URL '%s' is malformed", url);
|
||||
logger.debugf(mfe, "URL '%s' is malformed", url);
|
||||
throw new ClientRegistrationPolicyException("URL is malformed");
|
||||
}
|
||||
|
||||
logger.warnf("URL '%s' doesn't match any trustedHost or trustedDomain", url);
|
||||
ServicesLogger.LOGGER.urlDoesntMatch(url);
|
||||
throw new ClientRegistrationPolicyException("URL doesn't match any trusted host or trusted domain");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* Copyright 2016 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.services.resources.admin;
|
||||
|
||||
import org.jboss.resteasy.spi.NotFoundException;
|
||||
import org.keycloak.events.admin.OperationType;
|
||||
import org.keycloak.events.admin.ResourceType;
|
||||
import org.keycloak.models.ClientRegistrationTrustedHostModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.representations.idm.ClientRegistrationTrustedHostRepresentation;
|
||||
import org.keycloak.services.ErrorResponse;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class ClientRegistrationTrustedHostResource {
|
||||
|
||||
private final RealmAuth auth;
|
||||
private final RealmModel realm;
|
||||
private final AdminEventBuilder adminEvent;
|
||||
|
||||
@Context
|
||||
protected KeycloakSession session;
|
||||
|
||||
@Context
|
||||
protected UriInfo uriInfo;
|
||||
|
||||
public ClientRegistrationTrustedHostResource(RealmModel realm, RealmAuth auth, AdminEventBuilder adminEvent) {
|
||||
this.auth = auth;
|
||||
this.realm = realm;
|
||||
this.adminEvent = adminEvent.resource(ResourceType.CLIENT_REGISTRATION_TRUSTED_HOST_MODEL);
|
||||
|
||||
auth.init(RealmAuth.Resource.CLIENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new initial access token.
|
||||
*
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response create(ClientRegistrationTrustedHostRepresentation config) {
|
||||
auth.requireManage();
|
||||
|
||||
if (config.getHostName() == null) {
|
||||
return ErrorResponse.error("hostName not provided in config", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
int count = config.getCount() != null ? config.getCount() : 1;
|
||||
|
||||
try {
|
||||
ClientRegistrationTrustedHostModel clientRegTrustedHostModel = session.sessions().createClientRegistrationTrustedHostModel(realm, config.getHostName(), count);
|
||||
|
||||
adminEvent.operation(OperationType.CREATE).resourcePath(uriInfo, clientRegTrustedHostModel.getHostName()).representation(config).success();
|
||||
|
||||
return Response.created(uriInfo.getAbsolutePathBuilder().path(clientRegTrustedHostModel.getHostName()).build()).build();
|
||||
} catch (ModelDuplicateException mde) {
|
||||
return ErrorResponse.exists(mde.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a new initial access token.
|
||||
*
|
||||
* @param config
|
||||
* @return
|
||||
*/
|
||||
@PUT
|
||||
@Path("{hostname}")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response update(final @PathParam("hostname") String hostName, ClientRegistrationTrustedHostRepresentation config) {
|
||||
auth.requireManage();
|
||||
|
||||
if (config.getHostName() == null || !hostName.equals(config.getHostName())) {
|
||||
return ErrorResponse.error("hostName not provided in config or not compatible", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if (config.getCount() == null) {
|
||||
return ErrorResponse.error("count needs to be available", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
if (config.getRemainingCount() != null && config.getRemainingCount() > config.getCount()) {
|
||||
return ErrorResponse.error("remainingCount can't be bigger than count", Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
ClientRegistrationTrustedHostModel hostModel = session.sessions().getClientRegistrationTrustedHostModel(realm, config.getHostName());
|
||||
if (hostModel == null) {
|
||||
return ErrorResponse.error("hostName record not found", Response.Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
hostModel.setCount(config.getCount());
|
||||
hostModel.setRemainingCount(config.getRemainingCount());
|
||||
|
||||
adminEvent.operation(OperationType.UPDATE).resourcePath(uriInfo).representation(config).success();
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an initial access token.
|
||||
*
|
||||
* @param hostName
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Path("{hostname}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public ClientRegistrationTrustedHostRepresentation getConfig(final @PathParam("hostname") String hostName) {
|
||||
auth.requireView();
|
||||
|
||||
ClientRegistrationTrustedHostModel hostModel = session.sessions().getClientRegistrationTrustedHostModel(realm, hostName);
|
||||
if (hostModel == null) {
|
||||
throw new NotFoundException("hostName record not found");
|
||||
}
|
||||
|
||||
return wrap(hostModel);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public List<ClientRegistrationTrustedHostRepresentation> list() {
|
||||
auth.requireView();
|
||||
|
||||
List<ClientRegistrationTrustedHostModel> models = session.sessions().listClientRegistrationTrustedHosts(realm);
|
||||
List<ClientRegistrationTrustedHostRepresentation> reps = new LinkedList<>();
|
||||
for (ClientRegistrationTrustedHostModel m : models) {
|
||||
ClientRegistrationTrustedHostRepresentation r = wrap(m);
|
||||
reps.add(r);
|
||||
}
|
||||
return reps;
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("{hostname}")
|
||||
public void delete(final @PathParam("hostname") String hostName) {
|
||||
auth.requireManage();
|
||||
|
||||
session.sessions().removeClientRegistrationTrustedHostModel(realm, hostName);
|
||||
adminEvent.operation(OperationType.DELETE).resourcePath(uriInfo).success();
|
||||
}
|
||||
|
||||
private ClientRegistrationTrustedHostRepresentation wrap(ClientRegistrationTrustedHostModel model) {
|
||||
return ClientRegistrationTrustedHostRepresentation.create(model.getHostName(), model.getCount(), model.getRemainingCount());
|
||||
}
|
||||
}
|
|
@ -173,7 +173,7 @@ public class ComponentResource {
|
|||
private Response localizedErrorResponse(ComponentValidationException cve) {
|
||||
Properties messages = AdminRoot.getMessages(session, realm, "admin-messages", auth.getAuth().getToken().getLocale());
|
||||
|
||||
Object[] localizedParameters = Arrays.asList(cve.getParameters()).stream().map((Object parameter) -> {
|
||||
Object[] localizedParameters = cve.getParameters()==null ? null : Arrays.asList(cve.getParameters()).stream().map((Object parameter) -> {
|
||||
|
||||
if (parameter instanceof String) {
|
||||
String paramStr = (String) parameter;
|
||||
|
|
|
@ -65,7 +65,7 @@ public class ComponentsTest extends AbstractAdminTest {
|
|||
try {
|
||||
createComponent(rep);
|
||||
} catch (WebApplicationException e) {
|
||||
assertErrror(e.getResponse(), "Required is required");
|
||||
assertErrror(e.getResponse(), "'Required' is required");
|
||||
}
|
||||
|
||||
rep.getConfig().putSingle("required", "Required");
|
||||
|
@ -75,7 +75,7 @@ public class ComponentsTest extends AbstractAdminTest {
|
|||
try {
|
||||
createComponent(rep);
|
||||
} catch (WebApplicationException e) {
|
||||
assertErrror(e.getResponse(), "Number should be a number");
|
||||
assertErrror(e.getResponse(), "'Number' should be a number");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package org.keycloak.testsuite.cli.registration;
|
|||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.keycloak.admin.client.resource.ClientInitialAccessResource;
|
||||
import org.keycloak.admin.client.resource.ClientRegistrationTrustedHostResource;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
|
||||
import org.keycloak.authentication.authenticators.client.JWTClientAuthenticator;
|
||||
|
@ -12,7 +11,6 @@ import org.keycloak.client.registration.cli.config.FileConfigHandler;
|
|||
import org.keycloak.client.registration.cli.config.RealmConfigData;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessPresentation;
|
||||
import org.keycloak.representations.idm.ClientRegistrationTrustedHostRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
|
@ -27,7 +25,6 @@ import org.keycloak.testsuite.util.ClientBuilder;
|
|||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
|||
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessCreatePresentation;
|
||||
import org.keycloak.representations.idm.ClientInitialAccessPresentation;
|
||||
import org.keycloak.representations.idm.ClientRegistrationTrustedHostRepresentation;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.representations.oidc.OIDCClientRepresentation;
|
||||
|
|
|
@ -144,7 +144,7 @@ public class RsaKeyProviderTest extends AbstractKeycloakTest {
|
|||
rep.getConfig().putSingle(Attributes.PRIORITY_KEY, "invalid");
|
||||
|
||||
Response response = adminClient.realm("test").components().add(rep);
|
||||
assertErrror(response, "Priority should be a number");
|
||||
assertErrror(response, "'Priority' should be a number");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -156,7 +156,7 @@ public class RsaKeyProviderTest extends AbstractKeycloakTest {
|
|||
rep.getConfig().putSingle(Attributes.ENABLED_KEY, "invalid");
|
||||
|
||||
Response response = adminClient.realm("test").components().add(rep);
|
||||
assertErrror(response, "Enabled should be 'true' or 'false'");
|
||||
assertErrror(response, "'Enabled' should be 'true' or 'false'");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -168,7 +168,7 @@ public class RsaKeyProviderTest extends AbstractKeycloakTest {
|
|||
rep.getConfig().putSingle(Attributes.ACTIVE_KEY, "invalid");
|
||||
|
||||
Response response = adminClient.realm("test").components().add(rep);
|
||||
assertErrror(response, "Active should be 'true' or 'false'");
|
||||
assertErrror(response, "'Active' should be 'true' or 'false'");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -178,7 +178,7 @@ public class RsaKeyProviderTest extends AbstractKeycloakTest {
|
|||
ComponentRepresentation rep = createRep("invalid", RsaKeyProviderFactory.ID);
|
||||
|
||||
Response response = adminClient.realm("test").components().add(rep);
|
||||
assertErrror(response, "Private RSA Key is required");
|
||||
assertErrror(response, "'Private RSA Key' is required");
|
||||
|
||||
rep.getConfig().putSingle(Attributes.PRIVATE_KEY_KEY, "nonsense");
|
||||
response = adminClient.realm("test").components().add(rep);
|
||||
|
|
|
@ -316,15 +316,6 @@ public class AdminEventPaths {
|
|||
return uri.toString();
|
||||
}
|
||||
|
||||
// CLIENT REGISTRATION TRUSTED HOSTS
|
||||
|
||||
public static String clientRegistrationTrustedHostPath(String hostName) {
|
||||
URI uri = UriBuilder.fromUri("").path(RealmResource.class, "clientRegistrationTrustedHost")
|
||||
.path(ClientInitialAccessResource.class, "delete")
|
||||
.build(hostName);
|
||||
return uri.toString();
|
||||
}
|
||||
|
||||
// GROUPS
|
||||
|
||||
public static String groupsPath() {
|
||||
|
|
|
@ -67,4 +67,4 @@ log4j.logger.org.apache.directory.server.core=warn
|
|||
|
||||
# log4j.logger.org.keycloak.authentication.authenticators.browser.IdentityProviderAuthenticator=trace
|
||||
# log4j.logger.org.keycloak.keys.infinispan=trace
|
||||
log4j.logger.org.keycloak.services.clientregistration.policy=trace
|
||||
log4j.logger.org.keycloak.services.clientregistration.policy=debug
|
Loading…
Reference in a new issue