Skip to content

Commit e0e4c57

Browse files
committed
feat(UI): Simple PoC for UI-integration
see OSS-9
1 parent 2aa54cb commit e0e4c57

File tree

8 files changed

+214
-2
lines changed

8 files changed

+214
-2
lines changed

docker-compose.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ services:
4646
KEYCLOAK_ADMIN: 'admin'
4747
KEYCLOAK_ADMIN_PASSWORD: 'admin'
4848
KC_AUD_GLOBAL_MASTER_ACCESS: 'true'
49+
KC_FEATURES: "authorization,declarative-ui,step-up-authentication,token-exchange,web-authn"
4950

5051
maildev:
5152
container_name: maildev
5253
image: djfarrelly/maildev:1.0.0-rc2
5354
ports:
5455
- '8081:80'
55-
- '25'
56+
- '25'
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package net.cst.keycloak.admin;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.keycloak.Config;
5+
import org.keycloak.component.ComponentModel;
6+
import org.keycloak.models.KeycloakSessionFactory;
7+
import org.keycloak.provider.ProviderConfigProperty;
8+
import org.keycloak.provider.ProviderConfigurationBuilder;
9+
import org.keycloak.services.ui.extend.UiPageProvider;
10+
import org.keycloak.services.ui.extend.UiPageProviderFactory;
11+
12+
import java.util.HashMap;
13+
import java.util.List;
14+
import java.util.Map;
15+
16+
17+
/**
18+
* Implements UiPageProvider so it will be a master detail view in the admin ui of TODO items
19+
*/
20+
@Slf4j
21+
public class AdminUiPage implements UiPageProvider, UiPageProviderFactory<ComponentModel> {
22+
23+
@Override
24+
public void init(Config.Scope config) {
25+
}
26+
27+
@Override
28+
public void postInit(KeycloakSessionFactory factory) {
29+
}
30+
31+
@Override
32+
public void close() {
33+
}
34+
35+
@Override
36+
public String getId() {
37+
return "auditing";
38+
}
39+
40+
@Override
41+
public String getHelpText() {
42+
return "Here you view audit events from Keycloak";
43+
}
44+
45+
@Override
46+
public List<ProviderConfigProperty> getConfigProperties() {
47+
return ProviderConfigurationBuilder.create()
48+
.property()
49+
.name("name")
50+
.label("Name")
51+
.helpText("Short name of the task")
52+
.type(ProviderConfigProperty.STRING_TYPE)
53+
.add().property()
54+
.name("description")
55+
.label("Description")
56+
.helpText("Description of what needs to be done")
57+
.type(ProviderConfigProperty.TEXT_TYPE)
58+
.add().property()
59+
.name("prio")
60+
.label("Priority")
61+
.type(ProviderConfigProperty.LIST_TYPE)
62+
.options("critical", "high priority", "neutral", "low priority", "unknown")
63+
.add().build();
64+
}
65+
66+
@Override
67+
public Map<String, Object> getTypeMetadata() {
68+
Map<String, Object> metaData = new HashMap<>();
69+
metaData.put("displayFields", List.of("name", "prio"));
70+
return metaData;
71+
}
72+
}

spi/src/main/java/net/cst/keycloak/resources/AuditedResourcesProviderFactory.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import lombok.extern.slf4j.Slf4j;
44
import net.cst.keycloak.events.logging.LoginEventListenerProviderFactory;
5+
import net.cst.keycloak.utils.RuntimeHelper;
56
import org.keycloak.Config;
67
import org.keycloak.models.KeycloakSession;
78
import org.keycloak.models.KeycloakSessionFactory;
@@ -27,7 +28,7 @@ public String getId() {
2728
@Override
2829
public void init(Config.Scope scope) {
2930
log.info("Initializing Keycloak Auditor REST extension (Version {}).",
30-
LoginEventListenerProviderFactory.class.getPackage().getImplementationVersion());
31+
RuntimeHelper.getVersion());
3132
}
3233

3334
@Override
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package net.cst.keycloak.user;
2+
3+
import org.keycloak.Config;
4+
import org.keycloak.component.ComponentModel;
5+
import org.keycloak.models.KeycloakSession;
6+
import org.keycloak.models.KeycloakSessionFactory;
7+
import org.keycloak.models.RealmModel;
8+
import org.keycloak.provider.ProviderConfigProperty;
9+
import org.keycloak.provider.ProviderConfigurationBuilder;
10+
import org.keycloak.services.ui.extend.UiTabProvider;
11+
import org.keycloak.services.ui.extend.UiTabProviderFactory;
12+
13+
import java.util.HashMap;
14+
import java.util.List;
15+
import java.util.Map;
16+
17+
public class AccountUiPage implements UiTabProvider, UiTabProviderFactory<ComponentModel> {
18+
19+
private KeycloakSession session;
20+
21+
@Override
22+
public String getId() {
23+
return "Auditing";
24+
}
25+
26+
@Override
27+
public String getHelpText() {
28+
return "Show auditing information";
29+
}
30+
31+
@Override
32+
public void init(Config.Scope config) {
33+
}
34+
35+
@Override
36+
public void postInit(KeycloakSessionFactory factory) {
37+
}
38+
39+
@Override
40+
public void close() {
41+
}
42+
43+
@Override
44+
public void onCreate(KeycloakSession session, RealmModel realm, ComponentModel model) {
45+
realm.setAttribute("logo", model.get("logo"));
46+
}
47+
48+
@Override
49+
public List<ProviderConfigProperty> getConfigProperties() {
50+
final ProviderConfigurationBuilder builder = ProviderConfigurationBuilder.create();
51+
builder.property()
52+
.name("logo")
53+
.label("Set a logo")
54+
.helpText("This logo will be shown on the account ui")
55+
.type(ProviderConfigProperty.STRING_TYPE)
56+
.add();
57+
return builder.build();
58+
}
59+
60+
@Override
61+
public String getPath() {
62+
return "/:realm/realm-settings/:tab?";
63+
}
64+
65+
@Override
66+
public Map<String, String> getParams() {
67+
Map<String, String> params = new HashMap<>();
68+
params.put("tab", "attributes");
69+
return params;
70+
}
71+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
net.cst.keycloak.admin.AdminUiPage
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
net.cst.keycloak.user.AccountUiPage
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package net.cst.keycloak.admin;
2+
3+
import net.cst.keycloak.utils.EndpointTest;
4+
import org.junit.jupiter.api.Test;
5+
import org.keycloak.Config;
6+
import org.keycloak.component.ComponentModel;
7+
import org.keycloak.models.KeycloakSessionFactory;
8+
import org.keycloak.models.RealmModel;
9+
10+
import static org.junit.jupiter.api.Assertions.assertNotNull;
11+
import static org.mockito.Mockito.mock;
12+
13+
class AdminUiPageTest extends EndpointTest {
14+
15+
private ComponentModel componentModel = mock(ComponentModel.class);
16+
private RealmModel masterRealm = mock(RealmModel.class);
17+
private Config.Scope config = mock(Config.Scope.class);
18+
private KeycloakSessionFactory sessionFactory = mock(KeycloakSessionFactory.class);
19+
20+
@Test
21+
void shouldInit() {
22+
AdminUiPage page = new AdminUiPage();
23+
page.onCreate(session, masterRealm, componentModel);
24+
page.init(config);
25+
page.postInit(sessionFactory);
26+
page.close();
27+
assertNotNull(page.getConfigProperties());
28+
assertNotNull(page.getId());
29+
assertNotNull(page.getHelpText());
30+
assertNotNull(page.getTypeMetadata());
31+
}
32+
33+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package net.cst.keycloak.user;
2+
3+
import net.cst.keycloak.utils.EndpointTest;
4+
import org.junit.jupiter.api.Test;
5+
import org.keycloak.Config;
6+
import org.keycloak.component.ComponentModel;
7+
import org.keycloak.models.KeycloakSessionFactory;
8+
import org.keycloak.models.RealmModel;
9+
10+
import static org.junit.jupiter.api.Assertions.assertNotNull;
11+
import static org.mockito.Mockito.mock;
12+
13+
class AccountUiPageTest extends EndpointTest {
14+
15+
private ComponentModel componentModel = mock(ComponentModel.class);
16+
private RealmModel masterRealm = mock(RealmModel.class);
17+
private Config.Scope config = mock(Config.Scope.class);
18+
private KeycloakSessionFactory sessionFactory = mock(KeycloakSessionFactory.class);
19+
20+
@Test
21+
void shouldInit() {
22+
AccountUiPage page = new AccountUiPage();
23+
page.onCreate(session, masterRealm, componentModel);
24+
page.init(config);
25+
page.postInit(sessionFactory);
26+
assertNotNull(page.getConfigProperties());
27+
assertNotNull(page.getId());
28+
assertNotNull(page.getHelpText());
29+
assertNotNull(page.getPath());
30+
}
31+
32+
}

0 commit comments

Comments
 (0)