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.data;
20
21 import com.fasterxml.jackson.core.type.TypeReference;
22 import java.util.HashSet;
23 import java.util.Set;
24 import java.util.stream.Collectors;
25 import org.apache.syncope.common.lib.SyncopeClientException;
26 import org.apache.syncope.common.lib.SyncopeConstants;
27 import org.apache.syncope.common.lib.to.AnyTypeTO;
28 import org.apache.syncope.common.lib.types.AnyTypeKind;
29 import org.apache.syncope.common.lib.types.CipherAlgorithm;
30 import org.apache.syncope.common.lib.types.ClientExceptionType;
31 import org.apache.syncope.common.lib.types.EntitlementsHolder;
32 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
33 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
34 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
35 import org.apache.syncope.core.persistence.api.entity.AccessToken;
36 import org.apache.syncope.core.persistence.api.entity.AnyType;
37 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
38 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
39 import org.apache.syncope.core.provisioning.api.data.AnyTypeDataBinder;
40 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
41 import org.apache.syncope.core.spring.security.AuthContextUtils;
42 import org.apache.syncope.core.spring.security.Encryptor;
43 import org.apache.syncope.core.spring.security.SecurityProperties;
44 import org.apache.syncope.core.spring.security.SyncopeGrantedAuthority;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 public class AnyTypeDataBinderImpl implements AnyTypeDataBinder {
49
50 protected static final Logger LOG = LoggerFactory.getLogger(AnyTypeDataBinder.class);
51
52 protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
53
54 protected final SecurityProperties securityProperties;
55
56 protected final AnyTypeDAO anyTypeDAO;
57
58 protected final AnyTypeClassDAO anyTypeClassDAO;
59
60 protected final AccessTokenDAO accessTokenDAO;
61
62 protected final EntityFactory entityFactory;
63
64 public AnyTypeDataBinderImpl(
65 final SecurityProperties securityProperties,
66 final AnyTypeDAO anyTypeDAO,
67 final AnyTypeClassDAO anyTypeClassDAO,
68 final AccessTokenDAO accessTokenDAO,
69 final EntityFactory entityFactory) {
70
71 this.securityProperties = securityProperties;
72 this.anyTypeDAO = anyTypeDAO;
73 this.anyTypeClassDAO = anyTypeClassDAO;
74 this.accessTokenDAO = accessTokenDAO;
75 this.entityFactory = entityFactory;
76 }
77
78 @Override
79 public AnyType create(final AnyTypeTO anyTypeTO) {
80 AnyType anyType = entityFactory.newEntity(AnyType.class);
81 update(anyType, anyTypeTO);
82
83 Set<String> added = EntitlementsHolder.getInstance().addFor(anyType.getKey());
84
85 if (!securityProperties.getAdminUser().equals(AuthContextUtils.getUsername())) {
86 AccessToken accessToken = accessTokenDAO.findByOwner(AuthContextUtils.getUsername());
87 try {
88 Set<SyncopeGrantedAuthority> authorities = new HashSet<>(POJOHelper.deserialize(
89 ENCRYPTOR.decode(new String(accessToken.getAuthorities()), CipherAlgorithm.AES),
90 new TypeReference<Set<SyncopeGrantedAuthority>>() {
91 }));
92
93 added.forEach(e -> authorities.add(new SyncopeGrantedAuthority(e, SyncopeConstants.ROOT_REALM)));
94
95 accessToken.setAuthorities(ENCRYPTOR.encode(
96 POJOHelper.serialize(authorities), CipherAlgorithm.AES).
97 getBytes());
98
99 accessTokenDAO.save(accessToken);
100 } catch (Exception e) {
101 LOG.error("Could not fetch or store authorities", e);
102 }
103 }
104
105 return anyType;
106 }
107
108 @Override
109 public void update(final AnyType anyType, final AnyTypeTO anyTypeTO) {
110 if (anyType.getKey() == null) {
111 anyType.setKey(anyTypeTO.getKey());
112 }
113 if (anyType.getKind() == null) {
114 anyType.setKind(anyTypeTO.getKind());
115 }
116 if (anyType.getKind() != anyTypeTO.getKind()) {
117 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidAnyType);
118 sce.getElements().add(AnyTypeKind.class.getSimpleName() + " cannot be changed");
119 throw sce;
120 }
121
122 anyTypeTO.getClasses().forEach(anyTypeClassName -> {
123 AnyTypeClass anyTypeClass = anyTypeClassDAO.find(anyTypeClassName);
124 if (anyTypeClass == null) {
125 LOG.debug("Invalid {} {}, ignoring...", AnyTypeClass.class.getSimpleName(), anyTypeClassName);
126 } else {
127 anyType.add(anyTypeClass);
128 }
129 });
130 anyType.getClasses().removeIf(c -> c == null || !anyTypeTO.getClasses().contains(c.getKey()));
131 }
132
133 @Override
134 public AnyTypeTO delete(final AnyType anyType) {
135 AnyTypeTO deleted = getAnyTypeTO(anyType);
136
137 anyTypeDAO.delete(anyType.getKey());
138
139 Set<String> removed = EntitlementsHolder.getInstance().removeFor(deleted.getKey());
140
141 if (!securityProperties.getAdminUser().equals(AuthContextUtils.getUsername())) {
142 AccessToken accessToken = accessTokenDAO.findByOwner(AuthContextUtils.getUsername());
143 try {
144 Set<SyncopeGrantedAuthority> authorities = new HashSet<>(POJOHelper.deserialize(
145 ENCRYPTOR.decode(new String(accessToken.getAuthorities()), CipherAlgorithm.AES),
146 new TypeReference<Set<SyncopeGrantedAuthority>>() {
147 }));
148
149 authorities.removeAll(authorities.stream().
150 filter(authority -> removed.contains(authority.getAuthority())).collect(Collectors.toList()));
151
152 accessToken.setAuthorities(ENCRYPTOR.encode(
153 POJOHelper.serialize(authorities), CipherAlgorithm.AES).
154 getBytes());
155
156 accessTokenDAO.save(accessToken);
157 } catch (Exception e) {
158 LOG.error("Could not fetch or store authorities", e);
159 }
160 }
161
162 return deleted;
163 }
164
165 @Override
166 public AnyTypeTO getAnyTypeTO(final AnyType anyType) {
167 AnyTypeTO anyTypeTO = new AnyTypeTO();
168 anyTypeTO.setKey(anyType.getKey());
169 anyTypeTO.setKind(anyType.getKind());
170 anyTypeTO.getClasses().addAll(anyType.getClasses().stream().
171 map(AnyTypeClass::getKey).collect(Collectors.toList()));
172 return anyTypeTO;
173 }
174 }