http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java new file mode 100644 index 0000000..132bb66 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/UserSearchResultPanel.java @@ -0,0 +1,297 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.panels; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.pages.DisplayAttributesModalPage; +import org.apache.syncope.client.console.pages.EditUserModalPage; +import org.apache.syncope.client.console.pages.ResultStatusModalPage; +import org.apache.syncope.client.console.pages.StatusModalPage; +import org.apache.syncope.client.console.rest.AbstractSubjectRestClient; +import org.apache.syncope.client.console.rest.SchemaRestClient; +import org.apache.syncope.client.console.rest.UserRestClient; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.ActionColumn; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.AttrColumn; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn; +import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.TokenColumn; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink.ActionType; +import org.apache.syncope.client.console.wicket.markup.html.form.ActionLinksPanel; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.AbstractAttributableTO; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.syncope.common.lib.types.SchemaType; +import org.apache.wicket.Page; +import org.apache.wicket.PageReference; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn; +import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.spring.injection.annot.SpringBean; +import org.springframework.util.ReflectionUtils; + +public class UserSearchResultPanel extends AbstractSearchResultPanel { + + private static final long serialVersionUID = -905187144506842332L; + + private final static String PAGEID = "Users"; + + @SpringBean + private SchemaRestClient schemaRestClient; + + private final List<String> pSchemaNames; + + private final List<String> dSchemaNames; + + private final List<String> vSchemaNames; + + public <T extends AbstractAttributableTO> UserSearchResultPanel(final String id, final boolean filtered, + final String fiql, final PageReference callerRef, final AbstractSubjectRestClient restClient) { + + super(id, filtered, fiql, callerRef, restClient); + + this.pSchemaNames = schemaRestClient.getPlainSchemaNames(AttributableType.USER); + this.dSchemaNames = schemaRestClient.getDerSchemaNames(AttributableType.USER); + this.vSchemaNames = schemaRestClient.getVirSchemaNames(AttributableType.USER); + + initResultTable(); + } + + @Override + protected List<IColumn<AbstractAttributableTO, String>> getColumns() { + final List<IColumn<AbstractAttributableTO, String>> columns = new ArrayList<>(); + + for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_DETAILS_VIEW)) { + final Field field = ReflectionUtils.findField(UserTO.class, name); + + if ("token".equalsIgnoreCase(name)) { + columns.add(new TokenColumn("token")); + } else if (field != null && field.getType().equals(Date.class)) { + columns.add(new DatePropertyColumn<AbstractAttributableTO>(new ResourceModel(name, name), name, name)); + } else { + columns.add( + new PropertyColumn<AbstractAttributableTO, String>(new ResourceModel(name, name), name, name)); + } + } + + for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_ATTRIBUTES_VIEW)) { + if (pSchemaNames.contains(name)) { + columns.add(new AttrColumn(name, SchemaType.PLAIN)); + } + } + + for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_DERIVED_ATTRIBUTES_VIEW)) { + if (dSchemaNames.contains(name)) { + columns.add(new AttrColumn(name, SchemaType.DERIVED)); + } + } + + for (String name : prefMan.getList(getRequest(), Constants.PREF_USERS_VIRTUAL_ATTRIBUTES_VIEW)) { + if (vSchemaNames.contains(name)) { + columns.add(new AttrColumn(name, SchemaType.VIRTUAL)); + } + } + + // Add defaults in case of no selection + if (columns.isEmpty()) { + for (String name : DisplayAttributesModalPage.DEFAULT_SELECTION) { + columns.add( + new PropertyColumn<AbstractAttributableTO, String>(new ResourceModel(name, name), name, name)); + } + + prefMan.setList(getRequest(), getResponse(), Constants.PREF_USERS_DETAILS_VIEW, + Arrays.asList(DisplayAttributesModalPage.DEFAULT_SELECTION)); + } + + columns.add(new ActionColumn<AbstractAttributableTO, String>(new ResourceModel("actions", "")) { + + private static final long serialVersionUID = -3503023501954863131L; + + @Override + public ActionLinksPanel getActions(final String componentId, final IModel<AbstractAttributableTO> model) { + + final ActionLinksPanel panel = new ActionLinksPanel(componentId, model, page.getPageReference()); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + statusmodal.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new StatusModalPage<UserTO>( + page.getPageReference(), statusmodal, (UserTO) model.getObject()); + } + }); + + statusmodal.show(target); + } + }, ActionLink.ActionType.MANAGE_RESOURCES, PAGEID); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + statusmodal.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new StatusModalPage<UserTO>( + page.getPageReference(), statusmodal, (UserTO) model.getObject(), true); + } + }); + + statusmodal.show(target); + } + }, ActionLink.ActionType.ENABLE, PAGEID); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + editmodal.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + // SYNCOPE-294: re-read userTO before edit + UserTO userTO = ((UserRestClient) restClient).read(model.getObject().getKey()); + return new EditUserModalPage(page.getPageReference(), editmodal, userTO); + } + }); + + editmodal.show(target); + } + }, ActionLink.ActionType.EDIT, PAGEID); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + try { + final UserTO userTO = (UserTO) restClient. + delete(model.getObject().getETagValue(), model.getObject().getKey()); + + page.setModalResult(true); + + editmodal.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new ResultStatusModalPage.Builder(editmodal, userTO).build(); + } + }); + + editmodal.show(target); + } catch (SyncopeClientException scce) { + error(getString(Constants.OPERATION_ERROR) + ": " + scce.getMessage()); + feedbackPanel.refresh(target); + } + } + }, ActionLink.ActionType.DELETE, PAGEID); + + return panel; + } + + @Override + public ActionLinksPanel getHeader(final String componentId) { + final ActionLinksPanel panel = new ActionLinksPanel(componentId, new Model(), page.getPageReference()); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + displaymodal.setPageCreator(new ModalWindow.PageCreator() { + + private static final long serialVersionUID = -7834632442532690940L; + + @Override + public Page createPage() { + return new DisplayAttributesModalPage(page.getPageReference(), displaymodal, + pSchemaNames, dSchemaNames, vSchemaNames); + } + }); + + displaymodal.show(target); + } + }, ActionLink.ActionType.CHANGE_VIEW, PAGEID); + + panel.add(new ActionLink() { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + if (target != null) { + target.add(container); + } + } + }, ActionLink.ActionType.RELOAD, PAGEID, "list"); + + return panel; + } + }); + + return columns; + } + + @Override + protected <T extends AbstractAttributableTO> Collection<ActionType> getBulkActions() { + final List<ActionType> bulkActions = new ArrayList<ActionType>(); + + bulkActions.add(ActionType.DELETE); + bulkActions.add(ActionType.SUSPEND); + bulkActions.add(ActionType.REACTIVATE); + + return bulkActions; + } + + @Override + protected String getPageId() { + return PAGEID; + } +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/panels/VirAttrsPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/VirAttrsPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/VirAttrsPanel.java new file mode 100644 index 0000000..34d21d5 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/VirAttrsPanel.java @@ -0,0 +1,295 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.panels; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.panels.AttrTemplatesPanel.RoleAttrTemplatesChange; +import org.apache.syncope.client.console.rest.RoleRestClient; +import org.apache.syncope.client.console.rest.SchemaRestClient; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDecoratedCheckbox; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; +import org.apache.syncope.common.lib.to.AbstractAttributableTO; +import org.apache.syncope.common.lib.to.AttrTO; +import org.apache.syncope.common.lib.to.MembershipTO; +import org.apache.syncope.common.lib.to.RoleTO; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.to.VirSchemaTO; +import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.attributes.AjaxCallListener; +import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.ajax.markup.html.form.AjaxButton; +import org.apache.wicket.event.IEvent; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.form.ChoiceRenderer; +import org.apache.wicket.markup.html.form.DropDownChoice; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.apache.wicket.model.ResourceModel; +import org.apache.wicket.spring.injection.annot.SpringBean; + +public class VirAttrsPanel extends Panel { + + private static final long serialVersionUID = -7982691107029848579L; + + @SpringBean + private SchemaRestClient schemaRestClient; + + @SpringBean + private RoleRestClient roleRestClient; + + private final AttrTemplatesPanel attrTemplates; + + private final Map<String, VirSchemaTO> schemas = new TreeMap<String, VirSchemaTO>(); + + public <T extends AbstractAttributableTO> VirAttrsPanel(final String id, final T entityTO, + final boolean templateMode) { + + this(id, entityTO, templateMode, null); + } + + public <T extends AbstractAttributableTO> VirAttrsPanel(final String id, final T entityTO, + final boolean templateMode, final AttrTemplatesPanel attrTemplates) { + + super(id); + this.attrTemplates = attrTemplates; + this.setOutputMarkupId(true); + + final IModel<List<String>> virSchemas = new LoadableDetachableModel<List<String>>() { + + private static final long serialVersionUID = 5275935387613157437L; + + private void filter(final List<VirSchemaTO> schemaTOs, final Set<String> allowed) { + for (ListIterator<VirSchemaTO> itor = schemaTOs.listIterator(); itor.hasNext();) { + VirSchemaTO schema = itor.next(); + if (!allowed.contains(schema.getKey())) { + itor.remove(); + } + } + } + + @Override + protected List<String> load() { + List<VirSchemaTO> schemaTOs; + + if (entityTO instanceof RoleTO) { + final RoleTO roleTO = (RoleTO) entityTO; + + schemaTOs = schemaRestClient.getVirSchemas(AttributableType.ROLE); + Set<String> allowed; + if (attrTemplates == null) { + allowed = new HashSet<String>(roleTO.getRVirAttrTemplates()); + } else { + allowed = new HashSet<String>(attrTemplates.getSelected( + AttrTemplatesPanel.Type.rVirAttrTemplates)); + if (roleTO.isInheritTemplates() && roleTO.getParent() != 0) { + allowed.addAll(roleRestClient.read(roleTO.getParent()).getRVirAttrTemplates()); + } + } + filter(schemaTOs, allowed); + } else if (entityTO instanceof UserTO) { + schemaTOs = schemaRestClient.getVirSchemas(AttributableType.USER); + } else { + schemaTOs = schemaRestClient.getVirSchemas(AttributableType.MEMBERSHIP); + Set<String> allowed = new HashSet<String>( + roleRestClient.read(((MembershipTO) entityTO).getRoleId()).getMVirAttrTemplates()); + filter(schemaTOs, allowed); + } + + schemas.clear(); + + for (VirSchemaTO schemaTO : schemaTOs) { + schemas.put(schemaTO.getKey(), schemaTO); + } + + return new ArrayList<>(schemas.keySet()); + } + }; + + final WebMarkupContainer attributesContainer = new WebMarkupContainer("virAttrContainer"); + attributesContainer.setOutputMarkupId(true); + add(attributesContainer); + + AjaxButton addAttributeBtn = new IndicatingAjaxButton("addAttributeBtn", new ResourceModel("addAttributeBtn")) { + + private static final long serialVersionUID = -4804368561204623354L; + + @Override + protected void onSubmit(final AjaxRequestTarget target, final Form<?> form) { + entityTO.getVirAttrs().add(new AttrTO()); + target.add(attributesContainer); + } + + @Override + protected void onError(final AjaxRequestTarget target, final Form<?> form) { + target.add(attributesContainer); + } + }; + + add(addAttributeBtn.setDefaultFormProcessing(Boolean.FALSE)); + + ListView<AttrTO> attributes = new ListView<AttrTO>("attrs", + new PropertyModel<List<? extends AttrTO>>(entityTO, "virAttrs")) { + + private static final long serialVersionUID = 9101744072914090143L; + + @Override + @SuppressWarnings("unchecked") + protected void populateItem(final ListItem<AttrTO> item) { + final AttrTO attributeTO = item.getModelObject(); + + item.add(new AjaxDecoratedCheckbox("toRemove", new Model<Boolean>(Boolean.FALSE)) { + + private static final long serialVersionUID = 7170946748485726506L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + entityTO.getVirAttrs().remove(attributeTO); + target.add(attributesContainer); + } + + @Override + protected void updateAjaxAttributes(final AjaxRequestAttributes attributes) { + super.updateAjaxAttributes(attributes); + + final AjaxCallListener ajaxCallListener = new AjaxCallListener() { + + private static final long serialVersionUID = 7160235486520935153L; + + @Override + public CharSequence getPrecondition(final Component component) { + return "if (!confirm('" + getString("confirmDelete") + "')) return false;"; + } + }; + attributes.getAjaxCallListeners().add(ajaxCallListener); + } + }); + + if (attributeTO.getValues().isEmpty()) { + attributeTO.getValues().add(""); + } + + if (attributeTO.getSchema() != null) { + VirSchemaTO attributeSchema = schemas.get(attributeTO.getSchema()); + if (attributeSchema != null) { + attributeTO.setReadonly(attributeSchema.isReadonly()); + } + } + + final AjaxTextFieldPanel panel; + final MultiFieldPanel multiPanel; + if (templateMode) { + panel = new AjaxTextFieldPanel("values", "values", new Model<String>()); + panel.setReadOnly(attributeTO.isReadonly()); + multiPanel = null; + } else { + panel = new AjaxTextFieldPanel("panel", "values", new Model<String>(null)); + panel.setReadOnly(attributeTO.isReadonly()); + multiPanel = new MultiFieldPanel("values", + new PropertyModel<List<String>>(attributeTO, "values"), panel); + } + + final DropDownChoice<String> schemaChoice = new DropDownChoice<String>("schema", + new PropertyModel<String>(attributeTO, "schema"), virSchemas, + new ChoiceRenderer<String>() { + + private static final long serialVersionUID = 3109256773218160485L; + + @Override + public Object getDisplayValue(final String object) { + final StringBuilder text = new StringBuilder(object); + if (templateMode) { + text.append(" (JEXL)"); + } + return text.toString(); + } + }); + + schemaChoice.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + attributeTO.setSchema(schemaChoice.getModelObject()); + + VirSchemaTO virSchema = schemas.get(attributeTO.getSchema()); + if (virSchema != null) { + attributeTO.setReadonly(virSchema.isReadonly()); + panel.setReadOnly(attributeTO.isReadonly()); + } + + if (multiPanel != null) { + multiPanel.getView().setEnabled(false); + } + } + }); + + schemaChoice.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + target.add(attributesContainer); + } + }); + + schemaChoice.setOutputMarkupId(true); + schemaChoice.setRequired(true); + item.add(schemaChoice); + + if (templateMode) { + item.add(panel); + } else { + item.add(multiPanel); + } + } + }; + + attributesContainer.add(attributes); + } + + @Override + public void onEvent(final IEvent<?> event) { + if ((event.getPayload() instanceof RoleAttrTemplatesChange)) { + final RoleAttrTemplatesChange update = (RoleAttrTemplatesChange) event.getPayload(); + if (attrTemplates != null && update.getType() == AttrTemplatesPanel.Type.rVirAttrTemplates) { + update.getTarget().add(this); + } + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java new file mode 100644 index 0000000..8a95de6 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/resources/FilesystemResource.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.resources; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import org.apache.wicket.request.resource.AbstractResource; +import org.apache.wicket.util.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Mounts directory on local filesystem as subcontext. + */ +public class FilesystemResource extends AbstractResource { + + private static final long serialVersionUID = -4791087117785935198L; + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(FilesystemResource.class); + + private final String baseCtx; + + private final String basePath; + + public FilesystemResource(final String baseCtx, final String basePath) { + this.baseCtx = baseCtx; + this.basePath = basePath; + } + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + ResourceResponse response = new ResourceResponse(); + + final File baseDir = new File(basePath); + if (baseDir.exists() && baseDir.canRead() && baseDir.isDirectory()) { + String reqPath = attributes.getRequest().getUrl().getPath(); + final String subPath = reqPath.substring(reqPath.indexOf(baseCtx) + baseCtx.length()). + replace('/', File.separatorChar); + LOG.debug("Request for {}", subPath); + + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + FileInputStream resourceIS = null; + try { + resourceIS = new FileInputStream(new File(baseDir, subPath)); + IOUtils.copy(resourceIS, attributes.getResponse().getOutputStream()); + } catch (IOException e) { + LOG.error("Could not read from {}", baseDir.getAbsolutePath() + subPath, e); + } finally { + IOUtils.closeQuietly(resourceIS); + } + } + }); + } else { + LOG.error("{} not found, not readable or not a directory", basePath); + } + + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java new file mode 100644 index 0000000..2104745 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefGETResource.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.resources; + +import java.io.IOException; +import javax.ws.rs.core.MediaType; +import org.apache.syncope.client.console.rest.WorkflowRestClient; +import org.apache.wicket.protocol.http.WebApplication; +import org.apache.wicket.request.resource.AbstractResource; +import org.apache.wicket.util.io.IOUtils; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Mirror REST resource for obtaining user workflow definition in JSON (used by Activiti Modeler). + * + * @see org.apache.syncope.common.services.WorkflowService#exportDefinition(org.apache.syncope.common.types.SubjectType) + */ +public class WorkflowDefGETResource extends AbstractResource { + + private static final long serialVersionUID = 4637304868056148970L; + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + ResourceResponse response = new ResourceResponse(); + response.disableCaching(); + response.setContentType(MediaType.APPLICATION_JSON); + + response.setWriteCallback(new WriteCallback() { + + @Override + public void writeData(final Attributes attributes) throws IOException { + IOUtils.copy(WebApplicationContextUtils.getWebApplicationContext( + WebApplication.get().getServletContext()).getBean(WorkflowRestClient.class). + getDefinition(MediaType.APPLICATION_JSON_TYPE), + attributes.getResponse().getOutputStream()); + } + }); + + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java new file mode 100644 index 0000000..add6485 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/resources/WorkflowDefPUTResource.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.resources; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.MediaType; +import org.apache.cxf.common.util.UrlUtils; +import org.apache.syncope.client.console.rest.WorkflowRestClient; +import org.apache.wicket.protocol.http.WebApplication; +import org.apache.wicket.request.resource.AbstractResource; +import org.apache.wicket.util.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.support.WebApplicationContextUtils; + +/** + * Mirror REST resource for putting user workflow definition in JSON (used by Activiti Modeler). + * + * @see org.apache.syncope.common.services.WorkflowService#importDefinition( + * org.apache.syncope.common.types.SubjectType, java.lang.String) + */ +public class WorkflowDefPUTResource extends AbstractResource { + + private static final long serialVersionUID = 2964542005207297944L; + + /** + * Logger. + */ + private static final Logger LOG = LoggerFactory.getLogger(WorkflowDefPUTResource.class); + + @Override + protected ResourceResponse newResourceResponse(final Attributes attributes) { + String definition = null; + try { + HttpServletRequest request = (HttpServletRequest) attributes.getRequest().getContainerRequest(); + String requestBody = IOUtils.toString(request.getInputStream()); + String[] split = requestBody.split("&"); + for (int i = 0; i < split.length && definition == null; i++) { + String keyValue = split[i]; + if (keyValue.startsWith("json_xml=")) { + definition = UrlUtils.urlDecode(keyValue.split("=")[1]); + } + } + } catch (IOException e) { + LOG.error("Could not extract workflow definition from request", e); + } + + WebApplicationContextUtils.getWebApplicationContext(WebApplication.get().getServletContext()). + getBean(WorkflowRestClient.class). + updateDefinition(MediaType.APPLICATION_JSON_TYPE, definition); + + ResourceResponse response = new ResourceResponse(); + response.setStatusCode(204); + return response; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java new file mode 100644 index 0000000..a18a0a9 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AbstractSubjectRestClient.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.List; +import org.apache.syncope.common.lib.to.AbstractAttributableTO; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.ConnObjectTO; +import org.apache.wicket.extensions.markup.html.repeater.util.SortParam; + +public abstract class AbstractSubjectRestClient extends BaseRestClient { + + private static final long serialVersionUID = 1962529678091410544L; + + public abstract int count(); + + public abstract List<? extends AbstractAttributableTO> list(int page, int size, final SortParam<String> sort); + + public abstract int searchCount(String fiql); + + public abstract List<? extends AbstractAttributableTO> search(String fiql, + int page, int size, final SortParam<String> sort); + + public abstract ConnObjectTO getConnectorObject(String resourceName, Long id); + + public abstract AbstractAttributableTO delete(String etag, Long id); + + public abstract BulkActionResult bulkAction(BulkAction action); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/ApprovalRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ApprovalRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ApprovalRestClient.java new file mode 100644 index 0000000..dc9d12f --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ApprovalRestClient.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.List; +import org.apache.syncope.common.lib.to.WorkflowFormTO; +import org.apache.syncope.common.rest.api.service.UserWorkflowService; +import org.springframework.stereotype.Component; + +/** + * Console client for invoking Rest Todo services. + */ +@Component +public class ApprovalRestClient extends BaseRestClient { + + private static final long serialVersionUID = -4785231164900813921L; + + public List<WorkflowFormTO> getForms() { + return getService(UserWorkflowService.class).getForms(); + } + + public WorkflowFormTO claimForm(final String taskId) { + return getService(UserWorkflowService.class).claimForm(taskId); + } + + public void submitForm(final WorkflowFormTO form) { + getService(UserWorkflowService.class).submitForm(form); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/AuthRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/AuthRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/AuthRestClient.java new file mode 100644 index 0000000..01e6838 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/AuthRestClient.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.ArrayList; +import java.util.List; +import org.apache.syncope.common.rest.api.CollectionWrapper; +import org.apache.syncope.common.rest.api.service.EntitlementService; +import org.springframework.stereotype.Component; + +/** + * Console client for invoking Rest Resources services. + */ +@Component +public class AuthRestClient extends BaseRestClient { + + private static final long serialVersionUID = 2999780105004742914L; + + public List<String> getAllEntitlements() { + return new ArrayList<>( + CollectionWrapper.unwrap(getService(EntitlementService.class).getAllEntitlements())); + } + + public List<String> getOwnedEntitlements() { + return new ArrayList<>( + CollectionWrapper.unwrap(getService(EntitlementService.class).getOwnEntitlements())); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java new file mode 100644 index 0000000..ddab7af --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/BaseRestClient.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.io.Serializable; +import org.apache.syncope.client.console.SyncopeSession; +import org.apache.syncope.client.lib.SyncopeClient; +import org.apache.syncope.common.lib.search.OrderByClauseBuilder; +import org.apache.wicket.extensions.markup.html.repeater.util.SortParam; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class BaseRestClient implements Serializable { + + /** + * Logger. + */ + protected static final Logger LOG = LoggerFactory.getLogger(BaseRestClient.class); + + private static final long serialVersionUID = 1523999867826481989L; + + protected <T> T getAnonymousService(final Class<T> serviceClass) { + return SyncopeSession.get().getAnonymousService(serviceClass); + } + + protected <T> T getService(final Class<T> serviceClass) { + return SyncopeSession.get().getService(serviceClass); + } + + protected <T> T getService(final String etag, final Class<T> serviceClass) { + return SyncopeSession.get().getService(etag, serviceClass); + } + + protected <T> void resetClient(final Class<T> serviceClass) { + SyncopeSession.get().resetClient(serviceClass); + } + + protected String toOrderBy(final SortParam<String> sort) { + OrderByClauseBuilder builder = SyncopeClient.getOrderByClauseBuilder(); + + String property = sort.getProperty(); + if (property.indexOf('#') != -1) { + property = property.substring(property.indexOf('#') + 1); + } + + if (sort.isAscending()) { + builder.asc(property); + } else { + builder.desc(property); + } + + return builder.build(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java new file mode 100644 index 0000000..ca00ea8 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.Iterator; +import java.util.List; +import javax.ws.rs.core.Response; +import org.apache.syncope.client.console.SyncopeSession; +import org.apache.syncope.client.console.commons.AttrLayoutType; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.AttrTO; +import org.apache.syncope.common.lib.to.ConfTO; +import org.apache.syncope.common.rest.api.service.ConfigurationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ConfigurationRestClient extends BaseRestClient { + + private static final long serialVersionUID = 7692363064029538722L; + + @Autowired + private SchemaRestClient schemaRestClient; + + public ConfTO list() { + ConfTO conf = getService(ConfigurationService.class).list(); + + for (Iterator<AttrTO> it = conf.getPlainAttrs().iterator(); it.hasNext();) { + AttrTO attr = it.next(); + for (AttrLayoutType type : AttrLayoutType.values()) { + if (type.getConfKey().equals(attr.getSchema())) { + it.remove(); + } + } + } + + return conf; + } + + public AttrTO read(final String key) { + try { + return getService(ConfigurationService.class).read(key); + } catch (SyncopeClientException e) { + LOG.error("While reading a configuration schema", e); + } + return null; + } + + public AttrTO readAttrLayout(final AttrLayoutType type) { + if (type == null) { + return null; + } + + AttrTO attrLayout = read(type.getConfKey()); + if (attrLayout == null) { + attrLayout = new AttrTO(); + attrLayout.setSchema(type.getConfKey()); + } + if (attrLayout.getValues().isEmpty()) { + attrLayout.getValues().addAll(schemaRestClient.getPlainSchemaNames(type.getAttrType())); + } + + return attrLayout; + } + + public void set(final AttrTO attributeTO) { + getService(ConfigurationService.class).set(attributeTO.getSchema(), attributeTO); + } + + public void delete(final String key) { + getService(ConfigurationService.class).delete(key); + } + + public List<String> getMailTemplates() { + return SyncopeSession.get().getSyncopeTO().getMailTemplates(); + } + + public Response dbExport() { + return getService(ConfigurationService.class).export(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java new file mode 100644 index 0000000..d9a729d --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java @@ -0,0 +1,217 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.syncope.client.console.SyncopeSession; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.ConnBundleTO; +import org.apache.syncope.common.lib.to.ConnIdObjectClassTO; +import org.apache.syncope.common.lib.to.ConnInstanceTO; +import org.apache.syncope.common.lib.to.PlainSchemaTO; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.types.ConnConfProperty; +import org.apache.syncope.common.rest.api.service.ConnectorService; +import org.apache.syncope.common.rest.api.service.ResourceService; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Component; + +/** + * Console client for invoking Rest Connectors services. + */ +@Component +public class ConnectorRestClient extends BaseRestClient { + + private static final long serialVersionUID = -6870366819966266617L; + + public List<ConnInstanceTO> getAllConnectors() { + List<ConnInstanceTO> connectors = Collections.<ConnInstanceTO>emptyList(); + try { + connectors = getService(ConnectorService.class).list(SyncopeSession.get().getLocale().toString()); + } catch (Exception e) { + LOG.error("While reading connectors", e); + } + return connectors; + } + + public void create(final ConnInstanceTO connectorTO) { + Set<ConnConfProperty> filteredConf = filterProperties(connectorTO.getConfiguration()); + connectorTO.getConfiguration().clear(); + connectorTO.getConfiguration().addAll(filteredConf); + getService(ConnectorService.class).create(connectorTO); + } + + /** + * Load an already existent connector by its name. + * + * @param connectorInstanceId the id + * @return ConnInstanceTO + */ + public ConnInstanceTO read(final Long connectorInstanceId) { + ConnInstanceTO connectorTO = null; + + try { + connectorTO = getService(ConnectorService.class).read(connectorInstanceId); + } catch (SyncopeClientException e) { + LOG.error("While reading a connector", e); + } + + return connectorTO; + } + + public void update(final ConnInstanceTO connectorTO) { + Set<ConnConfProperty> filteredConf = filterProperties(connectorTO.getConfiguration()); + connectorTO.getConfiguration().clear(); + connectorTO.getConfiguration().addAll(filteredConf); + getService(ConnectorService.class).update(connectorTO.getKey(), connectorTO); + } + + public ConnInstanceTO delete(final Long id) { + ConnInstanceTO instanceTO = getService(ConnectorService.class).read(id); + getService(ConnectorService.class).delete(id); + return instanceTO; + } + + public List<ConnBundleTO> getAllBundles() { + List<ConnBundleTO> bundles = Collections.<ConnBundleTO>emptyList(); + + try { + bundles = getService(ConnectorService.class).getBundles(SyncopeSession.get().getLocale().toString()); + } catch (SyncopeClientException e) { + LOG.error("While getting connector bundles", e); + } + + return bundles; + } + + /** + * Get all configuration properties for the given connector instance. + * + * @param connectorId the connector id + * @return List of ConnConfProperty, or an empty list in case none found + */ + public List<ConnConfProperty> getConnectorProperties(final Long connectorId) { + List<ConnConfProperty> properties = null; + + try { + properties = getService(ConnectorService.class).getConfigurationProperties(connectorId); + } catch (SyncopeClientException e) { + LOG.error("While getting connector configuration properties", e); + } + + return properties; + } + + private Set<ConnConfProperty> filterProperties(final Set<ConnConfProperty> properties) { + Set<ConnConfProperty> newProperties = new HashSet<ConnConfProperty>(); + + for (ConnConfProperty property : properties) { + ConnConfProperty prop = new ConnConfProperty(); + prop.setSchema(property.getSchema()); + prop.setOverridable(property.isOverridable()); + + final List<Object> parsed = new ArrayList<Object>(); + if (property.getValues() != null) { + for (Object obj : property.getValues()) { + if (obj != null && !obj.toString().isEmpty()) { + parsed.add(obj); + } + } + } + prop.getValues().addAll(parsed); + newProperties.add(prop); + } + return newProperties; + } + + /** + * Test connector connection. + * + * @param connectorTO connector + * @return Connection status + */ + public boolean check(final ConnInstanceTO connectorTO) { + ConnInstanceTO toBeChecked = new ConnInstanceTO(); + BeanUtils.copyProperties(connectorTO, toBeChecked, new String[] { "configuration", "configurationMap" }); + toBeChecked.getConfiguration().addAll(filterProperties(connectorTO.getConfiguration())); + + boolean check = false; + try { + check = getService(ConnectorService.class).check(toBeChecked); + } catch (Exception e) { + LOG.error("While checking {}", toBeChecked, e); + } + + return check; + } + + public boolean check(final ResourceTO resourceTO) { + boolean check = false; + try { + check = getService(ResourceService.class).check(resourceTO); + } catch (Exception e) { + LOG.error("Connector not found {}", resourceTO.getConnectorId(), e); + } + + return check; + } + + public List<String> getSchemaNames(final ConnInstanceTO connectorTO) { + List<String> schemaNames = new ArrayList<String>(); + try { + List<PlainSchemaTO> response = getService(ConnectorService.class). + getSchemaNames(connectorTO.getKey(), connectorTO, false); + for (PlainSchemaTO schema : response) { + schemaNames.add(schema.getKey()); + } + } catch (Exception e) { + LOG.error("While getting schema names", e); + } finally { + // re-order schema names list + Collections.sort(schemaNames); + } + + return schemaNames; + } + + public List<ConnIdObjectClassTO> getSupportedObjectClasses(final ConnInstanceTO connectorTO) { + List<ConnIdObjectClassTO> result = Collections.emptyList(); + try { + result = getService(ConnectorService.class).getSupportedObjectClasses(connectorTO.getKey(), connectorTO); + } catch (Exception e) { + LOG.error("While getting supported object classes", e); + } + + return result; + } + + public void reload() { + getService(ConnectorService.class).reload(); + } + + public BulkActionResult bulkAction(final BulkAction action) { + return getService(ConnectorService.class).bulk(action); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java new file mode 100644 index 0000000..f78a682 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ExecutionRestClient.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +public interface ExecutionRestClient { + + void startExecution(long executionCollectorId); + + void deleteExecution(long executionId); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/InvalidPolicyType.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/InvalidPolicyType.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/InvalidPolicyType.java new file mode 100644 index 0000000..6c7959c --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/InvalidPolicyType.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +public class InvalidPolicyType extends RuntimeException { + + private static final long serialVersionUID = -1230154509336169378L; + + public InvalidPolicyType() { + } + + public InvalidPolicyType(final String msg) { + super(msg); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java new file mode 100644 index 0000000..a8b40ac --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/LoggerRestClient.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.apache.syncope.common.lib.to.EventCategoryTO; +import org.apache.syncope.common.lib.to.LoggerTO; +import org.apache.syncope.common.lib.types.AuditLoggerName; +import org.apache.syncope.common.lib.types.LoggerLevel; +import org.apache.syncope.common.lib.types.LoggerType; +import org.apache.syncope.common.rest.api.CollectionWrapper; +import org.apache.syncope.common.rest.api.service.LoggerService; +import org.springframework.stereotype.Component; + +@Component +public class LoggerRestClient extends BaseRestClient { + + private static final long serialVersionUID = 4579786978763032240L; + + public List<LoggerTO> listLogs() { + return getService(LoggerService.class).list(LoggerType.LOG); + } + + public List<AuditLoggerName> listAudits() { + return CollectionWrapper.wrapLogger(getService(LoggerService.class).list(LoggerType.AUDIT)); + } + + public Map<String, Set<AuditLoggerName>> listAuditsByCategory() { + Map<String, Set<AuditLoggerName>> result = new HashMap<String, Set<AuditLoggerName>>(); + for (AuditLoggerName auditLoggerName : listAudits()) { + if (!result.containsKey(auditLoggerName.getCategory())) { + result.put(auditLoggerName.getCategory(), new HashSet<AuditLoggerName>()); + } + + result.get(auditLoggerName.getCategory()).add(auditLoggerName); + } + + return result; + } + + public void setLogLevel(final String name, final LoggerLevel level) { + LoggerTO loggerTO = new LoggerTO(); + loggerTO.setKey(name); + loggerTO.setLevel(level); + getService(LoggerService.class).update(LoggerType.LOG, name, loggerTO); + } + + public void enableAudit(final AuditLoggerName auditLoggerName) { + String name = auditLoggerName.toLoggerName(); + LoggerTO loggerTO = new LoggerTO(); + loggerTO.setKey(name); + loggerTO.setLevel(LoggerLevel.DEBUG); + getService(LoggerService.class).update(LoggerType.AUDIT, name, loggerTO); + } + + public void deleteLog(final String name) { + getService(LoggerService.class).delete(LoggerType.LOG, name); + } + + public void disableAudit(final AuditLoggerName auditLoggerName) { + getService(LoggerService.class).delete(LoggerType.AUDIT, auditLoggerName.toLoggerName()); + } + + public List<EventCategoryTO> listEvents() { + try { + return getService(LoggerService.class).events(); + } catch (Exception e) { + return Collections.<EventCategoryTO>emptyList(); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java new file mode 100644 index 0000000..687ade0 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/NotificationRestClient.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.List; +import org.apache.syncope.common.lib.to.NotificationTO; +import org.apache.syncope.common.rest.api.service.NotificationService; +import org.springframework.stereotype.Component; + +@Component +public class NotificationRestClient extends BaseRestClient { + + private static final long serialVersionUID = 6328933265096511690L; + + public List<NotificationTO> getAllNotifications() { + return getService(NotificationService.class).list(); + } + + public NotificationTO read(final Long id) { + return getService(NotificationService.class).read(id); + } + + public void create(final NotificationTO notificationTO) { + getService(NotificationService.class).create(notificationTO); + } + + public void update(final NotificationTO notificationTO) { + getService(NotificationService.class).update(notificationTO.getKey(), notificationTO); + } + + public void delete(final Long id) { + getService(NotificationService.class).delete(id); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java new file mode 100644 index 0000000..eb9e7cb --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/PolicyRestClient.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.ArrayList; +import java.util.List; +import org.apache.syncope.client.console.SyncopeSession; +import org.apache.syncope.common.lib.to.AbstractPolicyTO; +import org.apache.syncope.common.lib.types.PolicyType; +import org.apache.syncope.common.rest.api.service.PolicyService; +import org.springframework.stereotype.Component; + +/** + * Console client for invoking Rest Policy services. + */ +@Component +public class PolicyRestClient extends BaseRestClient { + + private static final long serialVersionUID = -1392090291817187902L; + + public <T extends AbstractPolicyTO> T getGlobalPolicy(final PolicyType type) { + T policy = null; + try { + policy = getService(PolicyService.class).readGlobal(type); + } catch (Exception e) { + LOG.warn("No global " + type + " policy found", e); + } + return policy; + } + + public <T extends AbstractPolicyTO> T getPolicy(final Long id) { + T policy = null; + try { + policy = getService(PolicyService.class).read(id); + } catch (Exception e) { + LOG.warn("No policy found for id {}", id, e); + } + return policy; + } + + @SuppressWarnings("unchecked") + public <T extends AbstractPolicyTO> List<T> getPolicies(final PolicyType type, final boolean includeGlobal) { + final List<T> res = new ArrayList<>(); + + try { + res.addAll((List<T>) getService(PolicyService.class).list(type)); + } catch (Exception ignore) { + LOG.debug("No policy found", ignore); + } + + if (includeGlobal) { + try { + AbstractPolicyTO globalPolicy = getGlobalPolicy(type); + if (globalPolicy != null) { + res.add(0, (T) globalPolicy); + } + } catch (Exception ignore) { + LOG.warn("No global policy found", ignore); + } + } + + return res; + } + + public <T extends AbstractPolicyTO> void createPolicy(final T policy) { + getService(PolicyService.class).create(policy); + } + + public <T extends AbstractPolicyTO> void updatePolicy(final T policy) { + getService(PolicyService.class).update(policy.getKey(), policy); + } + + public void delete(final Long id, final Class<? extends AbstractPolicyTO> policyClass) { + getService(PolicyService.class).delete(id); + } + + public List<String> getCorrelationRuleClasses() { + List<String> rules = null; + + try { + rules = SyncopeSession.get().getSyncopeTO().getSyncCorrelationRules(); + } catch (Exception e) { + LOG.error("While getting all correlation rule classes", e); + } + + return rules; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java new file mode 100644 index 0000000..81b58ac --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.ArrayList; +import java.util.List; +import javax.ws.rs.core.Response; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.ReportTO; +import org.apache.syncope.common.lib.types.ReportExecExportFormat; +import org.apache.syncope.common.lib.wrap.ReportletConfClass; +import org.apache.syncope.common.rest.api.service.ReportService; +import org.apache.wicket.extensions.markup.html.repeater.util.SortParam; +import org.springframework.stereotype.Component; + +@Component +public class ReportRestClient extends BaseRestClient implements ExecutionRestClient { + + private static final long serialVersionUID = 1644689667998953604L; + + public List<String> getReportletConfClasses() { + List<String> result = new ArrayList<String>(); + + try { + List<ReportletConfClass> reportletConfClasses = getService(ReportService.class).getReportletConfClasses(); + for (ReportletConfClass clazz : reportletConfClasses) { + result.add(clazz.getElement()); + } + } catch (SyncopeClientException e) { + LOG.error("While getting available reportlet classes", e); + } + + return result; + } + + public ReportTO read(final Long reportId) { + return getService(ReportService.class).read(reportId); + } + + public List<ReportTO> list() { + return getService(ReportService.class).list().getResult(); + } + + public List<ReportTO> list(final int page, final int size, final SortParam<String> sort) { + return getService(ReportService.class).list(page, size, toOrderBy(sort)).getResult(); + } + + public int count() { + return getService(ReportService.class).list(1, 1).getTotalCount(); + } + + public void create(final ReportTO reportTO) { + getService(ReportService.class).create(reportTO); + } + + public void update(final ReportTO reportTO) { + getService(ReportService.class).update(reportTO.getKey(), reportTO); + } + + /** + * Delete specified report. + * + * @param reportId report to delete + */ + public void delete(final Long reportId) { + getService(ReportService.class).delete(reportId); + } + + /** + * Start execution for the specified report. + * + * @param reportId report id + */ + @Override + public void startExecution(final long reportId) { + getService(ReportService.class).execute(reportId); + } + + /** + * Delete specified report execution. + * + * @param reportExecId report execution id + */ + @Override + public void deleteExecution(final long reportExecId) { + getService(ReportService.class).deleteExecution(reportExecId); + } + + public Response exportExecutionResult(final Long executionId, final ReportExecExportFormat fmt) { + return getService(ReportService.class).exportExecutionResult(executionId, fmt); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java new file mode 100644 index 0000000..5ed1f45 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.rest; + +import java.util.List; +import org.apache.syncope.client.console.SyncopeSession; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.AbstractAttributableTO; +import org.apache.syncope.common.lib.to.BulkAction; +import org.apache.syncope.common.lib.to.BulkActionResult; +import org.apache.syncope.common.lib.to.ResourceTO; +import org.apache.syncope.common.lib.to.UserTO; +import org.apache.syncope.common.lib.types.ResourceDeassociationActionType; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.common.lib.wrap.SubjectKey; +import org.apache.syncope.common.rest.api.service.ResourceService; +import org.springframework.stereotype.Component; + +/** + * Console client for invoking Rest Resources services. + */ +@Component +public class ResourceRestClient extends BaseRestClient { + + private static final long serialVersionUID = -6898907679835668987L; + + public List<String> getPropagationActionsClasses() { + return SyncopeSession.get().getSyncopeTO().getPropagationActions(); + } + + public List<ResourceTO> getAll() { + List<ResourceTO> resources = null; + + try { + resources = getService(ResourceService.class).list(); + } catch (SyncopeClientException e) { + LOG.error("While reading all resources", e); + } + + return resources; + } + + public void create(final ResourceTO resourceTO) { + getService(ResourceService.class).create(resourceTO); + } + + public ResourceTO read(final String name) { + ResourceTO resourceTO = null; + + try { + resourceTO = getService(ResourceService.class).read(name); + } catch (SyncopeClientException e) { + LOG.error("While reading a resource", e); + } + return resourceTO; + } + + public void update(final ResourceTO resourceTO) { + getService(ResourceService.class).update(resourceTO.getKey(), resourceTO); + } + + public void delete(final String name) { + getService(ResourceService.class).delete(name); + } + + public BulkActionResult bulkAction(final BulkAction action) { + return getService(ResourceService.class).bulk(action); + } + + public BulkActionResult bulkAssociationAction( + final String resourceName, final Class<? extends AbstractAttributableTO> typeRef, + final ResourceDeassociationActionType type, final List<SubjectKey> subjtectIds) { + + return getService(ResourceService.class).bulkDeassociation(resourceName, + UserTO.class.isAssignableFrom(typeRef) ? SubjectType.USER : SubjectType.ROLE, + type, subjtectIds); + } +}
