Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ public ReconTaskPanel(

if (taskTO instanceof PushTaskTO) {
form.add(new Label("realm", ""));
form.add(new Label("remediation", ""));
} else {
boolean isSearchEnabled = RealmsUtils.isSearchEnabled();
AutoCompleteSettings settings = new AutoCompleteSettings();
Expand Down Expand Up @@ -155,6 +156,9 @@ protected Iterator<String> getChoices(final String input) {
realm.setEnabled(false);
}
form.add(realm);

form.add(new AjaxCheckBoxPanel(
"remediation", "remediation", new PropertyModel<>(taskTO, "remediation"), false));
}

AjaxPalettePanel<String> actions = new AjaxPalettePanel.Builder<String>().
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<div class="form-group form-palette">
<span wicket:id="actions">[actions]</span>
</div>
<div class="form-group"><span wicket:id="remediation">[remediation]</span></div>
<div class="form-group"><span wicket:id="realm">[realm]</span></div>
<div class="form-group"><span wicket:id="matchingRule">[matchingRule]</span></div>
<div class="form-group"><span wicket:id="unmatchingRule">[unmatchingRule]</span></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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.
destinationRealm=Destination realm
remediation=Remediation
matchingRule=Matching rule
unmatchingRule=Unmatching rule
performCreate=Allow create
performUpdate=Allow update
performDelete=Allow delete
syncStatus=Sync status
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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.
destinationRealm=Domaine de destination
remediation=Remise en \u00e9tat
matchingRule=R\u00e8gle correspondante
unmatchingRule=R\u00e8gle non correspondante
performCreate=Permettre cr\u00e9ation
performUpdate=Permettre mise \u00e0 jour
performDelete=Permettre suppression
syncStatus=Statut sync
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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.
destinationRealm=Realm destinazione
remediation=Bonifica
matchingRule=Regola di matching
unmatchingRule=Regola di unmatching
performCreate=Consenti creazione
performUpdate=Consenti modifica
performDelete=Consenti cancellazione
syncStatus=Allinea stato
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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.
destinationRealm=\u5b9b\u5148\u30ec\u30eb\u30e0
remediation=\u5fa9\u65e7
matchingRule=\u4e00\u81f4\u30eb\u30fc\u30eb
unmatchingRule=\u4e0d\u4e00\u81f4\u30eb\u30fc\u30eb
performCreate=\u4f5c\u6210\u3092\u8a31\u53ef
performUpdate=\u66f4\u65b0\u3092\u8a31\u53ef
performDelete=\u524a\u9664\u3092\u8a31\u53ef
syncStatus=\u540c\u671f\u30b9\u30c6\u30fc\u30bf\u30b9
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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.
destinationRealm=Destination realm
remediation=Remediation
matchingRule=Matching rule
unmatchingRule=Unmatching rule
performCreate=Allow create
performUpdate=Allow update
performDelete=Allow delete
syncStatus=Sync status
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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.
destinationRealm=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f
remediation=\u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435
matchingRule=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0438
unmatchingRule=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u0438 \u043d\u0435\u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0438
performCreate=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435
performUpdate=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435
performDelete=\u0420\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435
syncStatus=\u0421\u0442\u0430\u0442\u0443\u0441 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c
execute=\u0417\u0430\u043f\u0443\u0441\u043a
executeDryRun=\u041f\u0440\u043e\u0431\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a
latestExecStatus=\u0421\u0442\u0430\u0442\u0443\u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430
remediation=Remediation
remediation=\u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
import org.identityconnectors.framework.common.objects.filter.Filter;
import org.identityconnectors.framework.spi.SearchResultsHandler;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.transaction.annotation.Transactional;

@Component
public class ReconciliationLogic extends AbstractTransactionalLogic<EntityTO> {
Expand Down Expand Up @@ -454,6 +455,7 @@ private List<ProvisioningReport> pull(
}

@PreAuthorize("hasRole('" + StandardEntitlement.TASK_EXECUTE + "')")
@Transactional(noRollbackFor = SyncopeClientException.class)
public List<ProvisioningReport> pull(
final String anyTypeKey,
final String resourceKey,
Expand Down Expand Up @@ -484,6 +486,7 @@ public List<ProvisioningReport> pull(
}

@PreAuthorize("hasRole('" + StandardEntitlement.TASK_EXECUTE + "')")
@Transactional(noRollbackFor = SyncopeClientException.class)
public List<ProvisioningReport> pull(
final String anyTypeKey,
final String resourceKey,
Expand Down Expand Up @@ -626,6 +629,7 @@ public List<ProvisioningReport> push(
}

@PreAuthorize("hasRole('" + StandardEntitlement.TASK_EXECUTE + "')")
@Transactional(noRollbackFor = SyncopeClientException.class)
public List<ProvisioningReport> pull(final CSVPullSpec spec, final InputStream csv) {
AnyType anyType = anyTypeDAO.find(spec.getAnyTypeKey());
if (anyType == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.apache.syncope.common.lib.to.ProvisioningReport;
import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
import org.apache.syncope.core.persistence.api.dao.PullMatch;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.provisioning.api.cache.VirAttrCacheKey;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullExecutor;
import org.apache.syncope.core.provisioning.api.pushpull.SyncopePullResultHandler;
Expand Down Expand Up @@ -88,6 +89,9 @@ public abstract class AbstractPullResultHandler extends AbstractSyncopeResultHan
@Autowired
protected UserDAO userDAO;

@Autowired
protected TaskDAO taskDAO;

@Autowired
protected RemediationDAO remediationDAO;

Expand Down Expand Up @@ -206,19 +210,18 @@ protected List<ProvisioningReport> provision(
result.setKey(null);
end(provision.getAnyType().getKind(), UnmatchingRule.toEventName(rule), Result.SUCCESS, null, null, delta);
} else {
for (PullActions action : profile.getActions()) {
if (rule == UnmatchingRule.ASSIGN) {
action.beforeAssign(profile, delta, anyTO);
} else if (rule == UnmatchingRule.PROVISION) {
action.beforeProvision(profile, delta, anyTO);
}
}
result.setName(getName(anyTO));

Object output;
Result resultStatus;

try {
for (PullActions action : profile.getActions()) {
if (rule == UnmatchingRule.ASSIGN) {
action.beforeAssign(profile, delta, anyTO);
} else if (rule == UnmatchingRule.PROVISION) {
action.beforeProvision(profile, delta, anyTO);
}
}
result.setName(getName(anyTO));

AnyTO created = doCreate(anyTO, delta);
output = created;
result.setKey(created.getKey());
Expand Down Expand Up @@ -253,7 +256,9 @@ protected List<ProvisioningReport> provision(
entity.setError(result.getMessage());
entity.setInstant(new Date());
entity.setRemoteName(delta.getObject().getName().getNameValue());
entity.setPullTask(profile.getTask());
if (taskDAO.find(profile.getTask().getKey()) != null) {
entity.setPullTask(profile.getTask());
}

remediationDAO.save(entity);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,15 @@
import org.apache.syncope.common.lib.types.ImplementationType;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.types.ExecStatus;
import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.ResourceDeassociationAction;
import org.apache.syncope.common.lib.types.PullMode;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.lib.types.UnmatchingRule;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
import org.apache.syncope.common.rest.api.beans.ReconQuery;
import org.apache.syncope.common.rest.api.beans.RemediationQuery;
import org.apache.syncope.common.rest.api.beans.TaskQuery;
import org.apache.syncope.common.rest.api.service.ConnectorService;
Expand Down Expand Up @@ -810,6 +813,61 @@ public void remediation() {
}
}

@Test
public void remediationSinglePull() throws IOException {
// First of all, clear any potential conflict with existing user / group
ldapCleanup();

ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
ldap.setKey("ldapForRemediationSinglePull");

ProvisionTO provision = ldap.getProvision(AnyTypeKind.USER.name()).get();
provision.getMapping().getItems().removeIf(item -> "userId".equals(item.getIntAttrName()));
provision.getMapping().getItems().removeIf(item -> "email".equals(item.getIntAttrName()));
provision.getVirSchemas().clear();

ldap.getProvisions().clear();
ldap.getProvisions().add(provision);

ldap = createResource(ldap);

try {
// 2. pull an user
PullTaskTO pullTask = new PullTaskTO();
pullTask.setResource(ldap.getKey());
pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM);
pullTask.setRemediation(true);
pullTask.setPerformCreate(true);
pullTask.setPerformUpdate(true);
pullTask.setUnmatchingRule(UnmatchingRule.ASSIGN);
pullTask.setMatchingRule(MatchingRule.UPDATE);

try {
reconciliationService.pull(new ReconQuery.Builder(AnyTypeKind.USER.name(), ldap.getKey()).fiql(
"uid==pullFromLDAP").build(), pullTask);
fail("Should not arrive here");
} catch (SyncopeClientException sce) {
assertEquals(ClientExceptionType.Reconciliation, sce.getType());
}
Optional<RemediationTO> remediation = remediationService.list(
new RemediationQuery.Builder().page(1).size(1000).build()).getResult().stream().
filter(r -> "uid=pullFromLDAP,ou=People,o=isp".equalsIgnoreCase(r.getRemoteName())).
findFirst();
assertTrue(remediation.isPresent());
assertEquals(AnyTypeKind.USER.name(), remediation.get().getAnyType());
assertEquals(ResourceOperation.CREATE, remediation.get().getOperation());
assertNotNull(remediation.get().getAnyTOPayload());
assertNull(remediation.get().getAnyPatchPayload());
assertNull(remediation.get().getKeyPayload());
assertTrue(remediation.get().getError().contains(
"SyncopeClientCompositeException: {[RequiredValuesMissing [userId]]}"));
} finally {
resourceService.delete(ldap.getKey());
remediationService.list(new RemediationQuery.Builder().page(1).size(10).build()).getResult().forEach(
r -> remediationService.delete(r.getKey()));
}
}

@Test
public void issueSYNCOPE68() {
//-----------------------------
Expand Down