1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.provisioning.java.propagation;
20
21 import java.util.Optional;
22 import java.util.Set;
23 import org.apache.syncope.common.lib.types.AnyTypeKind;
24 import org.apache.syncope.common.lib.types.CipherAlgorithm;
25 import org.apache.syncope.common.lib.types.ConnConfProperty;
26 import org.apache.syncope.core.persistence.api.dao.UserDAO;
27 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
28 import org.apache.syncope.core.persistence.api.entity.task.PropagationData;
29 import org.apache.syncope.core.persistence.api.entity.user.User;
30 import org.apache.syncope.core.provisioning.api.propagation.PropagationActions;
31 import org.apache.syncope.core.provisioning.api.propagation.PropagationManager;
32 import org.apache.syncope.core.provisioning.api.propagation.PropagationTaskInfo;
33 import org.apache.syncope.core.spring.implementation.InstanceScope;
34 import org.apache.syncope.core.spring.implementation.SyncopeImplementation;
35 import org.identityconnectors.common.security.GuardedString;
36 import org.identityconnectors.framework.common.objects.Attribute;
37 import org.identityconnectors.framework.common.objects.AttributeBuilder;
38 import org.identityconnectors.framework.common.objects.AttributeUtil;
39 import org.identityconnectors.framework.common.objects.OperationalAttributes;
40 import org.springframework.beans.factory.annotation.Autowired;
41 import org.springframework.transaction.annotation.Transactional;
42
43
44
45
46
47
48 @SyncopeImplementation(scope = InstanceScope.PER_CONTEXT)
49 public class DBPasswordPropagationActions implements PropagationActions {
50
51 protected static final String CLEARTEXT = "CLEARTEXT";
52
53 @Autowired
54 protected UserDAO userDAO;
55
56 protected String getCipherAlgorithm(final ConnInstance connInstance) {
57 Optional<ConnConfProperty> cipherAlgorithm = connInstance.getConf().stream().
58 filter(property -> "cipherAlgorithm".equals(property.getSchema().getName())
59 && property.getValues() != null && !property.getValues().isEmpty()).findFirst();
60
61 return cipherAlgorithm.map(a -> (String) a.getValues().get(0)).orElse(CLEARTEXT);
62 }
63
64 protected boolean cipherAlgorithmMatches(final String connectorAlgorithm, final CipherAlgorithm userAlgorithm) {
65 if (userAlgorithm == null) {
66 return false;
67 }
68
69 if (connectorAlgorithm.equals(userAlgorithm.name())) {
70 return true;
71 }
72
73
74 return "SHA1".equals(connectorAlgorithm) && "SHA".equals(userAlgorithm.name());
75 }
76
77 @Transactional(readOnly = true)
78 @Override
79 public void before(final PropagationTaskInfo taskInfo) {
80 if (AnyTypeKind.USER == taskInfo.getAnyTypeKind()) {
81 User user = userDAO.find(taskInfo.getEntityKey());
82
83 PropagationData data = taskInfo.getPropagationData();
84 if (user != null && user.getPassword() != null && data.getAttributes() != null) {
85 Set<Attribute> attrs = data.getAttributes();
86
87 Attribute missing = AttributeUtil.find(PropagationManager.MANDATORY_MISSING_ATTR_NAME, attrs);
88
89 ConnInstance connInstance = taskInfo.getResource().getConnector();
90 if (missing != null && missing.getValue() != null && missing.getValue().size() == 1
91 && missing.getValue().get(0).equals(OperationalAttributes.PASSWORD_NAME)
92 && cipherAlgorithmMatches(getCipherAlgorithm(connInstance), user.getCipherAlgorithm())) {
93
94 Attribute passwordAttribute = AttributeBuilder.buildPassword(
95 new GuardedString(user.getPassword().toCharArray()));
96
97 attrs.add(passwordAttribute);
98 attrs.remove(missing);
99
100 Attribute hashedPasswordAttribute = AttributeBuilder.build(
101 AttributeUtil.createSpecialName("HASHED_PASSWORD"), Boolean.TRUE);
102 attrs.add(hashedPasswordAttribute);
103 }
104 }
105 }
106 }
107 }