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();
|
||||
|
||||
final String requestedScope = clientSession.getNote(DockerAuthV2Protocol.SCOPE_PARAM);
|
||||
if (requestedScope != null) {
|
||||
final DockerAccess allRequestedAccess = new DockerAccess(requestedScope);
|
||||
responseToken.getAccessItems().add(allRequestedAccess);
|
||||
final String requestedScopes = clientSession.getNote(DockerAuthV2Protocol.SCOPE_PARAM);
|
||||
if (requestedScopes != null) {
|
||||
for (String requestedScope : requestedScopes.split(" ")) {
|
||||
final DockerAccess requestedAccess = new DockerAccess(requestedScope);
|
||||
responseToken.getAccessItems().add(requestedAccess);
|
||||
}
|
||||
}
|
||||
|
||||
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