AllowAllDockerProtocolMapper now allows multiple resourceScopes delimited by spaces as specified by the docker auth token spec.
Closes #17187
This commit is contained in:
parent
53ff6c98b4
commit
705d20d4a2
4 changed files with 294 additions and 4 deletions
|
@ -41,10 +41,12 @@ public class AllowAllDockerProtocolMapper extends DockerAuthV2ProtocolMapper imp
|
||||||
|
|
||||||
responseToken.getAccessItems().clear();
|
responseToken.getAccessItems().clear();
|
||||||
|
|
||||||
final String requestedScope = clientSession.getNote(DockerAuthV2Protocol.SCOPE_PARAM);
|
final String requestedScopes = clientSession.getNote(DockerAuthV2Protocol.SCOPE_PARAM);
|
||||||
if (requestedScope != null) {
|
if (requestedScopes != null) {
|
||||||
final DockerAccess allRequestedAccess = new DockerAccess(requestedScope);
|
for (String requestedScope : requestedScopes.split(" ")) {
|
||||||
responseToken.getAccessItems().add(allRequestedAccess);
|
final DockerAccess requestedAccess = new DockerAccess(requestedScope);
|
||||||
|
responseToken.getAccessItems().add(requestedAccess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return responseToken;
|
return responseToken;
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package org.keycloak.protocol;
|
||||||
|
|
||||||
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class TestAuthenticatedClientSessionModel implements AuthenticatedClientSessionModel {
|
||||||
|
|
||||||
|
private final Map<String, String> notes = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTimestamp() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimestamp(int timestamp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void detachFromUserSession() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserSessionModel getUserSession() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCurrentRefreshToken() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentRefreshToken(String currentRefreshToken) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentRefreshTokenUseCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentRefreshTokenUseCount(int currentRefreshTokenUseCount) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNote(String name) {
|
||||||
|
return notes.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNote(String name, String value) {
|
||||||
|
notes.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeNote(String name) {
|
||||||
|
notes.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getNotes() {
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRedirectUri() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRedirectUri(String uri) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealm() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientModel getClient() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAction() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAction(String action) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProtocol() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProtocol(String method) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package org.keycloak.protocol.docker.mapper;
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
|
import org.keycloak.models.ProtocolMapperModel;
|
||||||
|
import org.keycloak.protocol.TestAuthenticatedClientSessionModel;
|
||||||
|
import org.keycloak.protocol.docker.DockerAuthV2Protocol;
|
||||||
|
import org.keycloak.representations.docker.DockerAccess;
|
||||||
|
import org.keycloak.representations.docker.DockerResponseToken;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
|
|
||||||
|
public class AllowAllDockerProtocolMapperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void transformsResourceScope() {
|
||||||
|
DockerResponseToken dockerResponseToken = new DockerResponseToken();
|
||||||
|
AuthenticatedClientSessionModel authenticatedClientSessionModel = new TestAuthenticatedClientSessionModel();
|
||||||
|
authenticatedClientSessionModel.setNote(DockerAuthV2Protocol.SCOPE_PARAM, "repository:my-image:pull,push");
|
||||||
|
|
||||||
|
DockerResponseToken result = new AllowAllDockerProtocolMapper().transformDockerResponseToken(dockerResponseToken, new ProtocolMapperModel(), null, null, authenticatedClientSessionModel);
|
||||||
|
|
||||||
|
assertThat(result.getAccessItems(), containsInAnyOrder(new DockerAccess("repository:my-image:pull,push")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void transformsResourceScopeNull() {
|
||||||
|
DockerResponseToken dockerResponseToken = new DockerResponseToken();
|
||||||
|
AuthenticatedClientSessionModel authenticatedClientSessionModel = new TestAuthenticatedClientSessionModel();
|
||||||
|
authenticatedClientSessionModel.setNote(DockerAuthV2Protocol.SCOPE_PARAM, null);
|
||||||
|
|
||||||
|
DockerResponseToken result = new AllowAllDockerProtocolMapper().transformDockerResponseToken(dockerResponseToken, new ProtocolMapperModel(), null, null, authenticatedClientSessionModel);
|
||||||
|
|
||||||
|
assertThat(result.getAccessItems(), containsInAnyOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void transformsMultipleResourceScopes() {
|
||||||
|
DockerResponseToken dockerResponseToken = new DockerResponseToken();
|
||||||
|
AuthenticatedClientSessionModel authenticatedClientSessionModel = new TestAuthenticatedClientSessionModel();
|
||||||
|
authenticatedClientSessionModel.setNote(DockerAuthV2Protocol.SCOPE_PARAM, "repository:my-image:pull,push repository:my-base-image:pull");
|
||||||
|
|
||||||
|
DockerResponseToken result = new AllowAllDockerProtocolMapper().transformDockerResponseToken(dockerResponseToken, new ProtocolMapperModel(), null, null, authenticatedClientSessionModel);
|
||||||
|
|
||||||
|
assertThat(result.getAccessItems(), containsInAnyOrder(new DockerAccess("repository:my-image:pull,push"), new DockerAccess("repository:my-base-image:pull")));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package org.keycloak.protocol.docker.mapper;
|
||||||
|
|
||||||
|
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserSessionModel;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
class TestAuthenticatedClientSessionModel implements AuthenticatedClientSessionModel {
|
||||||
|
|
||||||
|
private final Map<String, String> notes = new HashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTimestamp() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTimestamp(int timestamp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void detachFromUserSession() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserSessionModel getUserSession() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCurrentRefreshToken() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentRefreshToken(String currentRefreshToken) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCurrentRefreshTokenUseCount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCurrentRefreshTokenUseCount(int currentRefreshTokenUseCount) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNote(String name) {
|
||||||
|
return notes.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setNote(String name, String value) {
|
||||||
|
notes.put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeNote(String name) {
|
||||||
|
notes.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getNotes() {
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRedirectUri() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRedirectUri(String uri) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RealmModel getRealm() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClientModel getClient() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAction() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAction(String action) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getProtocol() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProtocol(String method) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue