1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.console.panels;
20
21 import com.fasterxml.jackson.databind.json.JsonMapper;
22 import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
23 import java.io.IOException;
24 import java.util.concurrent.atomic.AtomicReference;
25 import org.apache.syncope.client.console.SyncopeConsoleSession;
26 import org.apache.syncope.client.console.rest.OIDCJWKSRestClient;
27 import org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
28 import org.apache.syncope.client.console.wicket.markup.html.form.JsonEditorPanel;
29 import org.apache.syncope.client.ui.commons.Constants;
30 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
31 import org.apache.syncope.common.lib.to.OIDCJWKSTO;
32 import org.apache.syncope.common.lib.types.AMEntitlement;
33 import org.apache.wicket.PageReference;
34 import org.apache.wicket.ajax.AjaxRequestTarget;
35 import org.apache.wicket.ajax.markup.html.AjaxLink;
36 import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
37 import org.apache.wicket.markup.ComponentTag;
38 import org.apache.wicket.markup.html.WebMarkupContainer;
39 import org.apache.wicket.markup.html.link.ExternalLink;
40 import org.apache.wicket.markup.html.panel.Panel;
41 import org.apache.wicket.model.Model;
42 import org.apache.wicket.spring.injection.annot.SpringBean;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 public class OIDC extends Panel {
47
48 private static final long serialVersionUID = 12898029694947L;
49
50 private static final Logger LOG = LoggerFactory.getLogger(OIDC.class);
51
52 protected static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
53
54 @SpringBean
55 protected OIDCJWKSRestClient oidcJWKSRestClient;
56
57 protected final BaseModal<String> viewModal = new BaseModal<>("viewModal") {
58
59 private static final long serialVersionUID = 389935548143327858L;
60
61 @Override
62 protected void onConfigure() {
63 super.onConfigure();
64 setFooterVisible(true);
65 }
66 };
67
68 protected final AjaxLink<Void> view;
69
70 protected final AjaxLink<Void> generate;
71
72 protected final AjaxLink<Void> delete;
73
74 public OIDC(final String id, final String waPrefix, final PageReference pageRef) {
75 super(id);
76 setOutputMarkupId(true);
77
78 add(viewModal);
79 viewModal.size(Modal.Size.Extra_large);
80 viewModal.setWindowClosedCallback(target -> viewModal.show(false));
81
82 WebMarkupContainer container = new WebMarkupContainer("container");
83 add(container.setOutputMarkupId(true));
84
85 AtomicReference<OIDCJWKSTO> oidcjwksto = oidcJWKSRestClient.get();
86
87 view = new AjaxLink<>("view") {
88
89 private static final long serialVersionUID = 6250423506463465679L;
90
91 @Override
92 public void onClick(final AjaxRequestTarget target) {
93 String pretty;
94 try {
95 pretty = MAPPER.writerWithDefaultPrettyPrinter().
96 writeValueAsString(MAPPER.readTree(oidcjwksto.get().getJson()));
97 } catch (IOException e) {
98 LOG.error("Could not pretty-print", e);
99 pretty = oidcjwksto.get().getJson();
100 }
101
102 viewModal.header(Model.of("JSON Web Key Sets"));
103 target.add(viewModal.setContent(new JsonEditorPanel(viewModal, Model.of(pretty), true, pageRef)));
104 viewModal.show(true);
105 }
106
107 @Override
108 protected void onComponentTag(final ComponentTag tag) {
109 super.onComponentTag(tag);
110
111 if (oidcjwksto.get() == null) {
112 tag.put("class", "btn btn-app disabled");
113 }
114 }
115 };
116 view.setEnabled(oidcjwksto.get() != null);
117 container.add(view.setOutputMarkupId(true));
118 MetaDataRoleAuthorizationStrategy.authorize(view, ENABLE, AMEntitlement.OIDC_JWKS_READ);
119
120 generate = new AjaxLink<>("generate") {
121
122 private static final long serialVersionUID = 6250423506463465679L;
123
124 @Override
125 public void onClick(final AjaxRequestTarget target) {
126 try {
127 oidcjwksto.set(oidcJWKSRestClient.generate());
128 generate.setEnabled(false);
129 view.setEnabled(true);
130
131 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
132 target.add(container);
133 } catch (Exception e) {
134 LOG.error("While generating OIDC JWKS", e);
135 SyncopeConsoleSession.get().onException(e);
136 }
137 ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
138 }
139
140 @Override
141 protected void onComponentTag(final ComponentTag tag) {
142 super.onComponentTag(tag);
143
144 if (oidcjwksto.get() != null) {
145 tag.put("class", "btn btn-app disabled");
146 }
147 }
148 };
149 generate.setEnabled(oidcjwksto.get() == null);
150 container.add(generate.setOutputMarkupId(true));
151 MetaDataRoleAuthorizationStrategy.authorize(generate, ENABLE, AMEntitlement.OIDC_JWKS_GENERATE);
152
153 delete = new AjaxLink<>("delete") {
154
155 private static final long serialVersionUID = 6250423506463465679L;
156
157 @Override
158 public void onClick(final AjaxRequestTarget target) {
159 try {
160 oidcJWKSRestClient.delete();
161 oidcjwksto.set(null);
162 generate.setEnabled(true);
163 view.setEnabled(false);
164
165 SyncopeConsoleSession.get().success(getString(Constants.OPERATION_SUCCEEDED));
166 target.add(container);
167 } catch (Exception e) {
168 LOG.error("While deleting OIDC JWKS", e);
169 SyncopeConsoleSession.get().onException(e);
170 }
171 ((BaseWebPage) pageRef.getPage()).getNotificationPanel().refresh(target);
172 }
173
174 @Override
175 protected void onComponentTag(final ComponentTag tag) {
176 super.onComponentTag(tag);
177
178 if (oidcjwksto.get() == null) {
179 tag.put("class", "btn btn-app disabled");
180 }
181 }
182 };
183 delete.setEnabled(oidcjwksto.get() != null);
184 container.add(delete.setOutputMarkupId(true));
185 MetaDataRoleAuthorizationStrategy.authorize(delete, ENABLE, AMEntitlement.OIDC_JWKS_DELETE);
186
187 String wellKnownURI = waPrefix + "/oidc/.well-known/openid-configuration";
188 container.add(new ExternalLink("wellKnownURI", wellKnownURI, wellKnownURI));
189 }
190 }