1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.core.logic;
20
21 import java.lang.reflect.Method;
22 import java.time.OffsetDateTime;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.stream.Collectors;
26 import org.apache.commons.lang3.tuple.Pair;
27 import org.apache.syncope.common.lib.SyncopeClientException;
28 import org.apache.syncope.common.lib.to.AccessTokenTO;
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.IdRepoEntitlement;
32 import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
33 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
34 import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
35 import org.apache.syncope.core.persistence.api.entity.AccessToken;
36 import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
37 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
38 import org.apache.syncope.core.spring.security.AuthContextUtils;
39 import org.apache.syncope.core.spring.security.Encryptor;
40 import org.apache.syncope.core.spring.security.SecurityProperties;
41 import org.springframework.security.access.prepost.PreAuthorize;
42
43 public class AccessTokenLogic extends AbstractTransactionalLogic<AccessTokenTO> {
44
45 protected static final Encryptor ENCRYPTOR = Encryptor.getInstance();
46
47 protected static byte[] getAuthorities() {
48 byte[] authorities = null;
49 try {
50 authorities = ENCRYPTOR.encode(POJOHelper.serialize(
51 AuthContextUtils.getAuthorities()), CipherAlgorithm.AES).
52 getBytes();
53 } catch (Exception e) {
54 LOG.error("Could not fetch authorities", e);
55 }
56
57 return authorities;
58 }
59
60 protected final SecurityProperties securityProperties;
61
62 protected final AccessTokenDataBinder binder;
63
64 protected final AccessTokenDAO accessTokenDAO;
65
66 public AccessTokenLogic(
67 final SecurityProperties securityProperties,
68 final AccessTokenDataBinder binder,
69 final AccessTokenDAO accessTokenDAO) {
70
71 this.securityProperties = securityProperties;
72 this.binder = binder;
73 this.accessTokenDAO = accessTokenDAO;
74 }
75
76 @PreAuthorize("isAuthenticated()")
77 public Pair<String, OffsetDateTime> login() {
78 if (securityProperties.getAnonymousUser().equals(AuthContextUtils.getUsername())) {
79 SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
80 sce.getElements().add(securityProperties.getAnonymousUser() + " cannot be granted an access token");
81 throw sce;
82 }
83
84 return binder.create(
85 AuthContextUtils.getUsername(),
86 Collections.<String, Object>emptyMap(),
87 getAuthorities(),
88 false);
89 }
90
91 @PreAuthorize("isAuthenticated()")
92 public Pair<String, OffsetDateTime> refresh() {
93 AccessToken accessToken = accessTokenDAO.findByOwner(AuthContextUtils.getUsername());
94 if (accessToken == null) {
95 throw new NotFoundException("AccessToken for " + AuthContextUtils.getUsername());
96 }
97
98 return binder.update(accessToken, getAuthorities());
99 }
100
101 @PreAuthorize("isAuthenticated()")
102 public void logout() {
103 AccessToken accessToken = accessTokenDAO.findByOwner(AuthContextUtils.getUsername());
104 if (accessToken == null) {
105 throw new NotFoundException("AccessToken for " + AuthContextUtils.getUsername());
106 }
107
108 delete(accessToken.getKey());
109 }
110
111 @PreAuthorize("hasRole('" + IdRepoEntitlement.ACCESS_TOKEN_LIST + "')")
112 public Pair<Integer, List<AccessTokenTO>> list(
113 final int page,
114 final int size,
115 final List<OrderByClause> orderByClauses) {
116
117 Integer count = accessTokenDAO.count();
118
119 List<AccessTokenTO> result = accessTokenDAO.findAll(page, size, orderByClauses).stream().
120 map(binder::getAccessTokenTO).collect(Collectors.toList());
121
122 return Pair.of(count, result);
123 }
124
125 @PreAuthorize("hasRole('" + IdRepoEntitlement.ACCESS_TOKEN_DELETE + "')")
126 public void delete(final String key) {
127 accessTokenDAO.delete(key);
128 }
129
130 @Override
131 protected AccessTokenTO resolveReference(final Method method, final Object... args)
132 throws UnresolvedReferenceException {
133
134 throw new UnresolvedReferenceException();
135 }
136 }