View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.logic.wa;
20  
21  import java.time.LocalDateTime;
22  import java.util.List;
23  import java.util.function.Predicate;
24  import java.util.stream.Collectors;
25  import org.apache.syncope.common.lib.types.IdRepoEntitlement;
26  import org.apache.syncope.common.lib.wa.GoogleMfaAuthToken;
27  import org.apache.syncope.core.logic.AbstractAuthProfileLogic;
28  import org.apache.syncope.core.persistence.api.dao.AuthProfileDAO;
29  import org.apache.syncope.core.persistence.api.dao.NotFoundException;
30  import org.apache.syncope.core.persistence.api.entity.EntityFactory;
31  import org.apache.syncope.core.persistence.api.entity.am.AuthProfile;
32  import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
33  import org.springframework.security.access.prepost.PreAuthorize;
34  import org.springframework.transaction.annotation.Transactional;
35  
36  public class GoogleMfaAuthTokenLogic extends AbstractAuthProfileLogic {
37  
38      protected final EntityFactory entityFactory;
39  
40      public GoogleMfaAuthTokenLogic(
41              final EntityFactory entityFactory,
42              final AuthProfileDAO authProfileDAO,
43              final AuthProfileDataBinder binder) {
44  
45          super(authProfileDAO, binder);
46          this.entityFactory = entityFactory;
47      }
48  
49      protected void removeTokenAndSave(final AuthProfile profile, final Predicate<GoogleMfaAuthToken> criteria) {
50          List<GoogleMfaAuthToken> tokens = profile.getGoogleMfaAuthTokens();
51          if (tokens.removeIf(criteria)) {
52              profile.setGoogleMfaAuthTokens(tokens);
53              authProfileDAO.save(profile);
54          }
55      }
56  
57      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
58      public void delete(final LocalDateTime expirationDate) {
59          authProfileDAO.findAll(-1, -1).forEach(profile -> removeTokenAndSave(
60                  profile, token -> token.getIssueDate().compareTo(expirationDate) >= 0));
61      }
62  
63      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
64      public void delete(final String owner, final int otp) {
65          authProfileDAO.findByOwner(owner).
66                  ifPresent(profile -> removeTokenAndSave(profile, token -> token.getOtp() == otp));
67      }
68  
69      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
70      public void delete(final String owner) {
71          authProfileDAO.findByOwner(owner).ifPresent(profile -> {
72              profile.setGoogleMfaAuthTokens(List.of());
73              authProfileDAO.save(profile);
74          });
75      }
76  
77      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
78      public void delete(final int otp) {
79          authProfileDAO.findAll(-1, -1).forEach(profile -> removeTokenAndSave(
80                  profile, token -> token.getOtp() == otp));
81      }
82  
83      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
84      public void deleteAll() {
85          authProfileDAO.findAll(-1, -1).forEach(profile -> {
86              profile.setGoogleMfaAuthTokens(List.of());
87              authProfileDAO.save(profile);
88          });
89      }
90  
91      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
92      public void store(final String owner, final GoogleMfaAuthToken token) {
93          AuthProfile profile = authProfileDAO.findByOwner(owner).orElseGet(() -> {
94              AuthProfile authProfile = entityFactory.newEntity(AuthProfile.class);
95              authProfile.setOwner(owner);
96              return authProfile;
97          });
98  
99          List<GoogleMfaAuthToken> tokens = profile.getGoogleMfaAuthTokens();
100         tokens.removeIf(t -> t.getOtp() == token.getOtp());
101         tokens.add(token);
102         profile.setGoogleMfaAuthTokens(tokens);
103         authProfileDAO.save(profile);
104     }
105 
106     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
107     @Transactional(readOnly = true)
108     public GoogleMfaAuthToken read(final String owner, final int otp) {
109         return authProfileDAO.findByOwner(owner).
110                 stream().
111                 map(AuthProfile::getGoogleMfaAuthTokens).
112                 flatMap(List::stream).
113                 filter(token -> token.getOtp() == otp).
114                 findFirst().
115                 orElseThrow(() -> new NotFoundException("Could not find token for owner " + owner + " and otp " + otp));
116     }
117 
118     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
119     @Transactional(readOnly = true)
120     public List<GoogleMfaAuthToken> list() {
121         return authProfileDAO.findAll(-1, -1).stream().
122                 map(AuthProfile::getGoogleMfaAuthTokens).
123                 flatMap(List::stream).
124                 collect(Collectors.toList());
125     }
126 
127     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
128     @Transactional(readOnly = true)
129     public List<GoogleMfaAuthToken> read(final String owner) {
130         return authProfileDAO.findByOwner(owner).
131                 map(AuthProfile::getGoogleMfaAuthTokens).
132                 orElse(List.of());
133     }
134 }