keycloakify 9.0.0-rc.1 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -18
- package/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.js +0 -4
- package/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.js.map +1 -1
- package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js +32 -103
- package/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.js.map +1 -1
- package/bin/keycloakify/generateStartKeycloakTestingContainer.d.ts +1 -0
- package/bin/keycloakify/generateStartKeycloakTestingContainer.js +4 -3
- package/bin/keycloakify/generateStartKeycloakTestingContainer.js.map +1 -1
- package/bin/keycloakify/keycloakify.js +2 -1
- package/bin/keycloakify/keycloakify.js.map +1 -1
- package/login/kcContext/KcContext.d.ts +1 -0
- package/login/kcContext/KcContext.js.map +1 -1
- package/login/kcContext/kcContextMocks.js +8 -4
- package/login/kcContext/kcContextMocks.js.map +1 -1
- package/login/pages/LoginDeviceVerifyUserCode.js +1 -2
- package/login/pages/LoginDeviceVerifyUserCode.js.map +1 -1
- package/login/pages/LoginOauthGrant.js +1 -2
- package/login/pages/LoginOauthGrant.js.map +1 -1
- package/package.json +1 -67
- package/src/bin/keycloakify/generateJavaStackFiles/bringInAccountV1.ts +0 -5
- package/src/bin/keycloakify/generateJavaStackFiles/generateJavaStackFiles.ts +32 -103
- package/src/bin/keycloakify/generateStartKeycloakTestingContainer.ts +11 -4
- package/src/bin/keycloakify/keycloakify.ts +2 -1
- package/src/login/kcContext/KcContext.ts +1 -0
- package/src/login/kcContext/kcContextMocks.ts +8 -4
- package/src/login/pages/LoginDeviceVerifyUserCode.tsx +1 -2
- package/src/login/pages/LoginOauthGrant.tsx +1 -2
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountPages.java +0 -33
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountProvider.java +0 -76
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountProviderFactory.java +0 -25
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountSpi.java +0 -50
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/FreeMarkerAccountProvider.java +0 -424
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/FreeMarkerAccountProviderFactory.java +0 -51
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/Templates.java +0 -51
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/AccountBean.java +0 -91
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/AccountFederatedIdentityBean.java +0 -157
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/ApplicationsBean.java +0 -258
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/AuthorizationBean.java +0 -515
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/FeaturesBean.java +0 -56
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/LogBean.java +0 -95
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/PasswordBean.java +0 -34
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/RealmBean.java +0 -75
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/ReferrerBean.java +0 -38
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/SessionsBean.java +0 -93
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/TotpBean.java +0 -125
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/UrlBean.java +0 -121
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/AccountUrls.java +0 -115
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/resources/account/AccountFormService.java +0 -1310
- package/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/resources/account/AccountFormServiceFactory.java +0 -64
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountPages.java +0 -33
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountProvider.java +0 -76
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountProviderFactory.java +0 -25
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/AccountSpi.java +0 -50
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/FreeMarkerAccountProvider.java +0 -424
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/FreeMarkerAccountProviderFactory.java +0 -51
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/Templates.java +0 -51
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/AccountBean.java +0 -91
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/AccountFederatedIdentityBean.java +0 -157
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/ApplicationsBean.java +0 -258
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/AuthorizationBean.java +0 -515
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/FeaturesBean.java +0 -56
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/LogBean.java +0 -95
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/PasswordBean.java +0 -34
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/RealmBean.java +0 -75
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/ReferrerBean.java +0 -38
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/SessionsBean.java +0 -93
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/TotpBean.java +0 -125
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/forms/account/freemarker/model/UrlBean.java +0 -121
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/AccountUrls.java +0 -115
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/resources/account/AccountFormService.java +0 -1310
- package/src/bin/keycloakify/generateJavaStackFiles/account-v1-java/services/resources/account/AccountFormServiceFactory.java +0 -64
@@ -1,51 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
3
|
-
* and other contributors as indicated by the @author tags.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
package org.keycloak.forms.account.freemarker;
|
19
|
-
|
20
|
-
import com.google.auto.service.AutoService;
|
21
|
-
import org.keycloak.Config;
|
22
|
-
import org.keycloak.forms.account.AccountProvider;
|
23
|
-
import org.keycloak.forms.account.AccountProviderFactory;
|
24
|
-
import org.keycloak.models.KeycloakSession;
|
25
|
-
import org.keycloak.models.KeycloakSessionFactory;
|
26
|
-
|
27
|
-
/**
|
28
|
-
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
29
|
-
*/
|
30
|
-
@AutoService(AccountProviderFactory.class)
|
31
|
-
public class FreeMarkerAccountProviderFactory implements AccountProviderFactory {
|
32
|
-
|
33
|
-
@Override
|
34
|
-
public AccountProvider create(KeycloakSession session) {
|
35
|
-
return new FreeMarkerAccountProvider(session);
|
36
|
-
}
|
37
|
-
|
38
|
-
@Override
|
39
|
-
public void init(Config.Scope config) {}
|
40
|
-
|
41
|
-
@Override
|
42
|
-
public void postInit(KeycloakSessionFactory factory) {}
|
43
|
-
|
44
|
-
@Override
|
45
|
-
public void close() {}
|
46
|
-
|
47
|
-
@Override
|
48
|
-
public String getId() {
|
49
|
-
return "freemarker";
|
50
|
-
}
|
51
|
-
}
|
@@ -1,51 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
3
|
-
* and other contributors as indicated by the @author tags.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
package org.keycloak.forms.account.freemarker;
|
19
|
-
|
20
|
-
import org.keycloak.forms.account.AccountPages;
|
21
|
-
|
22
|
-
/**
|
23
|
-
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
24
|
-
*/
|
25
|
-
public class Templates {
|
26
|
-
|
27
|
-
public static String getTemplate(AccountPages page) {
|
28
|
-
switch (page) {
|
29
|
-
case ACCOUNT:
|
30
|
-
return "account.ftl";
|
31
|
-
case PASSWORD:
|
32
|
-
return "password.ftl";
|
33
|
-
case TOTP:
|
34
|
-
return "totp.ftl";
|
35
|
-
case FEDERATED_IDENTITY:
|
36
|
-
return "federatedIdentity.ftl";
|
37
|
-
case LOG:
|
38
|
-
return "log.ftl";
|
39
|
-
case SESSIONS:
|
40
|
-
return "sessions.ftl";
|
41
|
-
case APPLICATIONS:
|
42
|
-
return "applications.ftl";
|
43
|
-
case RESOURCES:
|
44
|
-
return "resources.ftl";
|
45
|
-
case RESOURCE_DETAIL:
|
46
|
-
return "resource-detail.ftl";
|
47
|
-
default:
|
48
|
-
throw new IllegalArgumentException();
|
49
|
-
}
|
50
|
-
}
|
51
|
-
}
|
@@ -1,91 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
3
|
-
* and other contributors as indicated by the @author tags.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
package org.keycloak.forms.account.freemarker.model;
|
19
|
-
|
20
|
-
import jakarta.ws.rs.core.MultivaluedMap;
|
21
|
-
import java.util.HashMap;
|
22
|
-
import java.util.List;
|
23
|
-
import java.util.Map;
|
24
|
-
import org.jboss.logging.Logger;
|
25
|
-
import org.keycloak.models.Constants;
|
26
|
-
import org.keycloak.models.UserModel;
|
27
|
-
|
28
|
-
/**
|
29
|
-
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
30
|
-
*/
|
31
|
-
public class AccountBean {
|
32
|
-
|
33
|
-
private static final Logger logger = Logger.getLogger(AccountBean.class);
|
34
|
-
|
35
|
-
private final UserModel user;
|
36
|
-
private final MultivaluedMap<String, String> profileFormData;
|
37
|
-
|
38
|
-
// TODO: More proper multi-value attribute support
|
39
|
-
private final Map<String, String> attributes = new HashMap<>();
|
40
|
-
|
41
|
-
public AccountBean(UserModel user, MultivaluedMap<String, String> profileFormData) {
|
42
|
-
this.user = user;
|
43
|
-
this.profileFormData = profileFormData;
|
44
|
-
|
45
|
-
for (Map.Entry<String, List<String>> attr : user.getAttributes().entrySet()) {
|
46
|
-
List<String> attrValue = attr.getValue();
|
47
|
-
if (attrValue.size() > 0) {
|
48
|
-
attributes.put(attr.getKey(), attrValue.get(0));
|
49
|
-
}
|
50
|
-
|
51
|
-
if (attrValue.size() > 1) {
|
52
|
-
logger.warnf(
|
53
|
-
"There are more values for attribute '%s' of user '%s' . Will display just first value",
|
54
|
-
attr.getKey(), user.getUsername());
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
58
|
-
if (profileFormData != null) {
|
59
|
-
for (String key : profileFormData.keySet()) {
|
60
|
-
if (key.startsWith(Constants.USER_ATTRIBUTES_PREFIX)) {
|
61
|
-
String attribute = key.substring(Constants.USER_ATTRIBUTES_PREFIX.length());
|
62
|
-
attributes.put(attribute, profileFormData.getFirst(key));
|
63
|
-
}
|
64
|
-
}
|
65
|
-
}
|
66
|
-
}
|
67
|
-
|
68
|
-
public String getFirstName() {
|
69
|
-
return profileFormData != null ? profileFormData.getFirst("firstName") : user.getFirstName();
|
70
|
-
}
|
71
|
-
|
72
|
-
public String getLastName() {
|
73
|
-
return profileFormData != null ? profileFormData.getFirst("lastName") : user.getLastName();
|
74
|
-
}
|
75
|
-
|
76
|
-
public String getUsername() {
|
77
|
-
if (profileFormData != null && profileFormData.containsKey("username")) {
|
78
|
-
return profileFormData.getFirst("username");
|
79
|
-
} else {
|
80
|
-
return user.getUsername();
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
public String getEmail() {
|
85
|
-
return profileFormData != null ? profileFormData.getFirst("email") : user.getEmail();
|
86
|
-
}
|
87
|
-
|
88
|
-
public Map<String, String> getAttributes() {
|
89
|
-
return attributes;
|
90
|
-
}
|
91
|
-
}
|
@@ -1,157 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
3
|
-
* and other contributors as indicated by the @author tags.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
package org.keycloak.forms.account.freemarker.model;
|
19
|
-
|
20
|
-
import java.net.URI;
|
21
|
-
import java.util.List;
|
22
|
-
import java.util.Objects;
|
23
|
-
import java.util.concurrent.atomic.AtomicInteger;
|
24
|
-
import java.util.stream.Collectors;
|
25
|
-
import java.util.stream.Stream;
|
26
|
-
import org.keycloak.models.FederatedIdentityModel;
|
27
|
-
import org.keycloak.models.IdentityProviderModel;
|
28
|
-
import org.keycloak.models.KeycloakSession;
|
29
|
-
import org.keycloak.models.OrderedModel;
|
30
|
-
import org.keycloak.models.RealmModel;
|
31
|
-
import org.keycloak.models.UserModel;
|
32
|
-
import org.keycloak.models.utils.KeycloakModelUtils;
|
33
|
-
import org.keycloak.services.resources.account.AccountFormService;
|
34
|
-
|
35
|
-
/**
|
36
|
-
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
37
|
-
* @author <a href="mailto:velias@redhat.com">Vlastimil Elias</a>
|
38
|
-
*/
|
39
|
-
public class AccountFederatedIdentityBean {
|
40
|
-
|
41
|
-
private static OrderedModel.OrderedModelComparator<FederatedIdentityEntry>
|
42
|
-
IDP_COMPARATOR_INSTANCE = new OrderedModel.OrderedModelComparator<>();
|
43
|
-
|
44
|
-
private final List<FederatedIdentityEntry> identities;
|
45
|
-
private final boolean removeLinkPossible;
|
46
|
-
private final KeycloakSession session;
|
47
|
-
|
48
|
-
public AccountFederatedIdentityBean(
|
49
|
-
KeycloakSession session, RealmModel realm, UserModel user, URI baseUri, String stateChecker) {
|
50
|
-
this.session = session;
|
51
|
-
|
52
|
-
AtomicInteger availableIdentities = new AtomicInteger(0);
|
53
|
-
this.identities =
|
54
|
-
realm
|
55
|
-
.getIdentityProvidersStream()
|
56
|
-
.filter(IdentityProviderModel::isEnabled)
|
57
|
-
.map(
|
58
|
-
provider -> {
|
59
|
-
String providerId = provider.getAlias();
|
60
|
-
|
61
|
-
FederatedIdentityModel identity =
|
62
|
-
getIdentity(
|
63
|
-
session.users().getFederatedIdentitiesStream(realm, user), providerId);
|
64
|
-
|
65
|
-
if (identity != null) {
|
66
|
-
availableIdentities.getAndIncrement();
|
67
|
-
}
|
68
|
-
|
69
|
-
String displayName =
|
70
|
-
KeycloakModelUtils.getIdentityProviderDisplayName(session, provider);
|
71
|
-
return new FederatedIdentityEntry(
|
72
|
-
identity,
|
73
|
-
displayName,
|
74
|
-
provider.getAlias(),
|
75
|
-
provider.getAlias(),
|
76
|
-
provider.getConfig() != null ? provider.getConfig().get("guiOrder") : null);
|
77
|
-
})
|
78
|
-
.sorted(IDP_COMPARATOR_INSTANCE)
|
79
|
-
.collect(Collectors.toList());
|
80
|
-
|
81
|
-
// Removing last social provider is not possible if you don't have other possibility to
|
82
|
-
// authenticate
|
83
|
-
this.removeLinkPossible =
|
84
|
-
availableIdentities.get() > 1
|
85
|
-
|| user.getFederationLink() != null
|
86
|
-
|| AccountFormService.isPasswordSet(session, realm, user);
|
87
|
-
}
|
88
|
-
|
89
|
-
private FederatedIdentityModel getIdentity(
|
90
|
-
Stream<FederatedIdentityModel> identities, String providerId) {
|
91
|
-
return identities
|
92
|
-
.filter(
|
93
|
-
federatedIdentityModel ->
|
94
|
-
Objects.equals(federatedIdentityModel.getIdentityProvider(), providerId))
|
95
|
-
.findFirst()
|
96
|
-
.orElse(null);
|
97
|
-
}
|
98
|
-
|
99
|
-
public List<FederatedIdentityEntry> getIdentities() {
|
100
|
-
return identities;
|
101
|
-
}
|
102
|
-
|
103
|
-
public boolean isRemoveLinkPossible() {
|
104
|
-
return removeLinkPossible;
|
105
|
-
}
|
106
|
-
|
107
|
-
public static class FederatedIdentityEntry implements OrderedModel {
|
108
|
-
|
109
|
-
private FederatedIdentityModel federatedIdentityModel;
|
110
|
-
private final String providerId;
|
111
|
-
private final String providerName;
|
112
|
-
private final String guiOrder;
|
113
|
-
private final String displayName;
|
114
|
-
|
115
|
-
public FederatedIdentityEntry(
|
116
|
-
FederatedIdentityModel federatedIdentityModel,
|
117
|
-
String displayName,
|
118
|
-
String providerId,
|
119
|
-
String providerName,
|
120
|
-
String guiOrder) {
|
121
|
-
this.federatedIdentityModel = federatedIdentityModel;
|
122
|
-
this.displayName = displayName;
|
123
|
-
this.providerId = providerId;
|
124
|
-
this.providerName = providerName;
|
125
|
-
this.guiOrder = guiOrder;
|
126
|
-
}
|
127
|
-
|
128
|
-
public String getProviderId() {
|
129
|
-
return providerId;
|
130
|
-
}
|
131
|
-
|
132
|
-
public String getProviderName() {
|
133
|
-
return providerName;
|
134
|
-
}
|
135
|
-
|
136
|
-
public String getUserId() {
|
137
|
-
return federatedIdentityModel != null ? federatedIdentityModel.getUserId() : null;
|
138
|
-
}
|
139
|
-
|
140
|
-
public String getUserName() {
|
141
|
-
return federatedIdentityModel != null ? federatedIdentityModel.getUserName() : null;
|
142
|
-
}
|
143
|
-
|
144
|
-
public boolean isConnected() {
|
145
|
-
return federatedIdentityModel != null;
|
146
|
-
}
|
147
|
-
|
148
|
-
@Override
|
149
|
-
public String getGuiOrder() {
|
150
|
-
return guiOrder;
|
151
|
-
}
|
152
|
-
|
153
|
-
public String getDisplayName() {
|
154
|
-
return displayName;
|
155
|
-
}
|
156
|
-
}
|
157
|
-
}
|
@@ -1,258 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
3
|
-
* and other contributors as indicated by the @author tags.
|
4
|
-
*
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
-
* you may not use this file except in compliance with the License.
|
7
|
-
* You may obtain a copy of the License at
|
8
|
-
*
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
-
*
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
-
* See the License for the specific language governing permissions and
|
15
|
-
* limitations under the License.
|
16
|
-
*/
|
17
|
-
|
18
|
-
package org.keycloak.forms.account.freemarker.model;
|
19
|
-
|
20
|
-
import java.util.ArrayList;
|
21
|
-
import java.util.LinkedList;
|
22
|
-
import java.util.List;
|
23
|
-
import java.util.Objects;
|
24
|
-
import java.util.Set;
|
25
|
-
import java.util.function.Predicate;
|
26
|
-
import java.util.stream.Collectors;
|
27
|
-
import java.util.stream.Stream;
|
28
|
-
import org.keycloak.common.util.MultivaluedHashMap;
|
29
|
-
import org.keycloak.models.ClientModel;
|
30
|
-
import org.keycloak.models.ClientScopeModel;
|
31
|
-
import org.keycloak.models.Constants;
|
32
|
-
import org.keycloak.models.KeycloakSession;
|
33
|
-
import org.keycloak.models.OrderedModel;
|
34
|
-
import org.keycloak.models.RealmModel;
|
35
|
-
import org.keycloak.models.RoleModel;
|
36
|
-
import org.keycloak.models.UserConsentModel;
|
37
|
-
import org.keycloak.models.UserModel;
|
38
|
-
import org.keycloak.protocol.oidc.TokenManager;
|
39
|
-
import org.keycloak.services.managers.UserSessionManager;
|
40
|
-
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
|
41
|
-
import org.keycloak.services.util.ResolveRelative;
|
42
|
-
import org.keycloak.storage.StorageId;
|
43
|
-
|
44
|
-
/**
|
45
|
-
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
46
|
-
*/
|
47
|
-
public class ApplicationsBean {
|
48
|
-
|
49
|
-
private List<ApplicationEntry> applications = new LinkedList<>();
|
50
|
-
|
51
|
-
public ApplicationsBean(KeycloakSession session, RealmModel realm, UserModel user) {
|
52
|
-
Set<ClientModel> offlineClients =
|
53
|
-
new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
|
54
|
-
|
55
|
-
this.applications =
|
56
|
-
this.getApplications(session, realm, user)
|
57
|
-
.filter(
|
58
|
-
client ->
|
59
|
-
!isAdminClient(client)
|
60
|
-
|| AdminPermissions.realms(session, realm, user).isAdmin())
|
61
|
-
.map(client -> toApplicationEntry(session, realm, user, client, offlineClients))
|
62
|
-
.filter(Objects::nonNull)
|
63
|
-
.collect(Collectors.toList());
|
64
|
-
}
|
65
|
-
|
66
|
-
public static boolean isAdminClient(ClientModel client) {
|
67
|
-
return client.getClientId().equals(Constants.ADMIN_CLI_CLIENT_ID)
|
68
|
-
|| client.getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID);
|
69
|
-
}
|
70
|
-
|
71
|
-
private Stream<ClientModel> getApplications(
|
72
|
-
KeycloakSession session, RealmModel realm, UserModel user) {
|
73
|
-
Predicate<ClientModel> bearerOnly = ClientModel::isBearerOnly;
|
74
|
-
Stream<ClientModel> clients = realm.getClientsStream().filter(bearerOnly.negate());
|
75
|
-
|
76
|
-
Predicate<ClientModel> isLocal = client -> new StorageId(client.getId()).isLocal();
|
77
|
-
return Stream.concat(
|
78
|
-
clients,
|
79
|
-
session
|
80
|
-
.users()
|
81
|
-
.getConsentsStream(realm, user.getId())
|
82
|
-
.map(UserConsentModel::getClient)
|
83
|
-
.filter(isLocal.negate()))
|
84
|
-
.distinct();
|
85
|
-
}
|
86
|
-
|
87
|
-
private void processRoles(
|
88
|
-
Set<RoleModel> inputRoles,
|
89
|
-
List<RoleModel> realmRoles,
|
90
|
-
MultivaluedHashMap<String, ClientRoleEntry> clientRoles) {
|
91
|
-
for (RoleModel role : inputRoles) {
|
92
|
-
if (role.getContainer() instanceof RealmModel) {
|
93
|
-
realmRoles.add(role);
|
94
|
-
} else {
|
95
|
-
ClientModel currentClient = (ClientModel) role.getContainer();
|
96
|
-
ClientRoleEntry clientRole =
|
97
|
-
new ClientRoleEntry(
|
98
|
-
currentClient.getClientId(),
|
99
|
-
currentClient.getName(),
|
100
|
-
role.getName(),
|
101
|
-
role.getDescription());
|
102
|
-
clientRoles.add(currentClient.getClientId(), clientRole);
|
103
|
-
}
|
104
|
-
}
|
105
|
-
}
|
106
|
-
|
107
|
-
public List<ApplicationEntry> getApplications() {
|
108
|
-
return applications;
|
109
|
-
}
|
110
|
-
|
111
|
-
public static class ApplicationEntry {
|
112
|
-
|
113
|
-
private KeycloakSession session;
|
114
|
-
private final List<RoleModel> realmRolesAvailable;
|
115
|
-
private final MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable;
|
116
|
-
private final ClientModel client;
|
117
|
-
private final List<String> clientScopesGranted;
|
118
|
-
private final List<String> additionalGrants;
|
119
|
-
|
120
|
-
public ApplicationEntry(
|
121
|
-
KeycloakSession session,
|
122
|
-
List<RoleModel> realmRolesAvailable,
|
123
|
-
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable,
|
124
|
-
ClientModel client,
|
125
|
-
List<String> clientScopesGranted,
|
126
|
-
List<String> additionalGrants) {
|
127
|
-
this.session = session;
|
128
|
-
this.realmRolesAvailable = realmRolesAvailable;
|
129
|
-
this.resourceRolesAvailable = resourceRolesAvailable;
|
130
|
-
this.client = client;
|
131
|
-
this.clientScopesGranted = clientScopesGranted;
|
132
|
-
this.additionalGrants = additionalGrants;
|
133
|
-
}
|
134
|
-
|
135
|
-
public List<RoleModel> getRealmRolesAvailable() {
|
136
|
-
return realmRolesAvailable;
|
137
|
-
}
|
138
|
-
|
139
|
-
public MultivaluedHashMap<String, ClientRoleEntry> getResourceRolesAvailable() {
|
140
|
-
return resourceRolesAvailable;
|
141
|
-
}
|
142
|
-
|
143
|
-
public List<String> getClientScopesGranted() {
|
144
|
-
return clientScopesGranted;
|
145
|
-
}
|
146
|
-
|
147
|
-
public String getEffectiveUrl() {
|
148
|
-
return ResolveRelative.resolveRelativeUri(
|
149
|
-
session, getClient().getRootUrl(), getClient().getBaseUrl());
|
150
|
-
}
|
151
|
-
|
152
|
-
public ClientModel getClient() {
|
153
|
-
return client;
|
154
|
-
}
|
155
|
-
|
156
|
-
public List<String> getAdditionalGrants() {
|
157
|
-
return additionalGrants;
|
158
|
-
}
|
159
|
-
}
|
160
|
-
|
161
|
-
// Same class used in OAuthGrantBean as well. Maybe should be merged into common-freemarker...
|
162
|
-
public static class ClientRoleEntry {
|
163
|
-
|
164
|
-
private final String clientId;
|
165
|
-
private final String clientName;
|
166
|
-
private final String roleName;
|
167
|
-
private final String roleDescription;
|
168
|
-
|
169
|
-
public ClientRoleEntry(
|
170
|
-
String clientId, String clientName, String roleName, String roleDescription) {
|
171
|
-
this.clientId = clientId;
|
172
|
-
this.clientName = clientName;
|
173
|
-
this.roleName = roleName;
|
174
|
-
this.roleDescription = roleDescription;
|
175
|
-
}
|
176
|
-
|
177
|
-
public String getClientId() {
|
178
|
-
return clientId;
|
179
|
-
}
|
180
|
-
|
181
|
-
public String getClientName() {
|
182
|
-
return clientName;
|
183
|
-
}
|
184
|
-
|
185
|
-
public String getRoleName() {
|
186
|
-
return roleName;
|
187
|
-
}
|
188
|
-
|
189
|
-
public String getRoleDescription() {
|
190
|
-
return roleDescription;
|
191
|
-
}
|
192
|
-
}
|
193
|
-
|
194
|
-
/**
|
195
|
-
* Constructs a {@link ApplicationEntry} from the specified parameters.
|
196
|
-
*
|
197
|
-
* @param session a reference to the {@code Keycloak} session.
|
198
|
-
* @param realm a reference to the realm.
|
199
|
-
* @param user a reference to the user.
|
200
|
-
* @param client a reference to the client that contains the applications.
|
201
|
-
* @param offlineClients a {@link Set} containing the offline clients.
|
202
|
-
* @return the constructed {@link ApplicationEntry} instance or {@code null} if the user can't
|
203
|
-
* access the applications in the specified client.
|
204
|
-
*/
|
205
|
-
private ApplicationEntry toApplicationEntry(
|
206
|
-
final KeycloakSession session,
|
207
|
-
final RealmModel realm,
|
208
|
-
final UserModel user,
|
209
|
-
final ClientModel client,
|
210
|
-
final Set<ClientModel> offlineClients) {
|
211
|
-
|
212
|
-
// Construct scope parameter with all optional scopes to see all potentially available roles
|
213
|
-
Stream<ClientScopeModel> allClientScopes =
|
214
|
-
Stream.concat(
|
215
|
-
client.getClientScopes(true).values().stream(),
|
216
|
-
client.getClientScopes(false).values().stream());
|
217
|
-
allClientScopes = Stream.concat(allClientScopes, Stream.of(client)).distinct();
|
218
|
-
|
219
|
-
Set<RoleModel> availableRoles = TokenManager.getAccess(user, client, allClientScopes);
|
220
|
-
|
221
|
-
// Don't show applications, which user doesn't have access into (any available roles)
|
222
|
-
// unless this is can be changed by approving/revoking consent
|
223
|
-
if (!isAdminClient(client) && availableRoles.isEmpty() && !client.isConsentRequired()) {
|
224
|
-
return null;
|
225
|
-
}
|
226
|
-
|
227
|
-
List<RoleModel> realmRolesAvailable = new LinkedList<>();
|
228
|
-
MultivaluedHashMap<String, ClientRoleEntry> resourceRolesAvailable = new MultivaluedHashMap<>();
|
229
|
-
processRoles(availableRoles, realmRolesAvailable, resourceRolesAvailable);
|
230
|
-
|
231
|
-
List<ClientScopeModel> orderedScopes = new LinkedList<>();
|
232
|
-
if (client.isConsentRequired()) {
|
233
|
-
UserConsentModel consent =
|
234
|
-
session.users().getConsentByClient(realm, user.getId(), client.getId());
|
235
|
-
|
236
|
-
if (consent != null) {
|
237
|
-
orderedScopes.addAll(consent.getGrantedClientScopes());
|
238
|
-
}
|
239
|
-
}
|
240
|
-
List<String> clientScopesGranted =
|
241
|
-
orderedScopes.stream()
|
242
|
-
.sorted(OrderedModel.OrderedModelComparator.getInstance())
|
243
|
-
.map(ClientScopeModel::getConsentScreenText)
|
244
|
-
.collect(Collectors.toList());
|
245
|
-
|
246
|
-
List<String> additionalGrants = new ArrayList<>();
|
247
|
-
if (offlineClients.contains(client)) {
|
248
|
-
additionalGrants.add("${offlineToken}");
|
249
|
-
}
|
250
|
-
return new ApplicationEntry(
|
251
|
-
session,
|
252
|
-
realmRolesAvailable,
|
253
|
-
resourceRolesAvailable,
|
254
|
-
client,
|
255
|
-
clientScopesGranted,
|
256
|
-
additionalGrants);
|
257
|
-
}
|
258
|
-
}
|