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.util.List;
22  import java.util.Objects;
23  import java.util.stream.Collectors;
24  import org.apache.syncope.common.lib.types.IdRepoEntitlement;
25  import org.apache.syncope.common.lib.wa.GoogleMfaAuthAccount;
26  import org.apache.syncope.core.logic.AbstractAuthProfileLogic;
27  import org.apache.syncope.core.persistence.api.dao.AuthProfileDAO;
28  import org.apache.syncope.core.persistence.api.dao.NotFoundException;
29  import org.apache.syncope.core.persistence.api.entity.EntityFactory;
30  import org.apache.syncope.core.persistence.api.entity.am.AuthProfile;
31  import org.apache.syncope.core.provisioning.api.data.AuthProfileDataBinder;
32  import org.springframework.security.access.prepost.PreAuthorize;
33  import org.springframework.transaction.annotation.Transactional;
34  
35  public class GoogleMfaAuthAccountLogic extends AbstractAuthProfileLogic {
36  
37      protected final EntityFactory entityFactory;
38  
39      public GoogleMfaAuthAccountLogic(
40              final EntityFactory entityFactory,
41              final AuthProfileDAO authProfileDAO,
42              final AuthProfileDataBinder binder) {
43  
44          super(authProfileDAO, binder);
45          this.entityFactory = entityFactory;
46      }
47  
48      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
49      @Transactional(readOnly = true)
50      public List<GoogleMfaAuthAccount> list() {
51          return authProfileDAO.findAll(-1, -1).
52                  stream().
53                  map(AuthProfile::getGoogleMfaAuthAccounts).
54                  filter(Objects::nonNull).
55                  flatMap(List::stream).
56                  collect(Collectors.toList());
57      }
58  
59      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
60      public void delete(final String owner) {
61          authProfileDAO.findByOwner(owner).ifPresent(profile -> {
62              profile.setGoogleMfaAuthAccounts(List.of());
63              authProfileDAO.save(profile);
64          });
65      }
66  
67      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
68      public void delete(final long id) {
69          authProfileDAO.findAll(-1, -1).
70                  stream().
71                  filter(Objects::nonNull).
72                  filter(profile -> profile.
73                  getGoogleMfaAuthAccounts().
74                  stream().
75                  allMatch(acct -> acct.getId() == id)).
76                  findFirst().
77                  ifPresentOrElse(
78                          profile -> {
79                              if (profile.getGoogleMfaAuthAccounts().removeIf(acct -> acct.getId() == id)) {
80                                  authProfileDAO.save(profile);
81                              }
82                          },
83                          () -> {
84                              throw new NotFoundException("Could not find account for id " + id);
85                          });
86      }
87  
88      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
89      public void deleteAll() {
90          authProfileDAO.findAll(-1, -1).forEach(profile -> {
91              profile.setGoogleMfaAuthAccounts(List.of());
92              authProfileDAO.save(profile);
93          });
94      }
95  
96      @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
97      public void create(final String owner, final GoogleMfaAuthAccount account) {
98          AuthProfile profile = authProfileDAO.findByOwner(owner).orElseGet(() -> {
99              AuthProfile authProfile = entityFactory.newEntity(AuthProfile.class);
100             authProfile.setOwner(owner);
101             return authProfile;
102         });
103 
104         List<GoogleMfaAuthAccount> accounts = profile.getGoogleMfaAuthAccounts();
105         accounts.add(account);
106         profile.setGoogleMfaAuthAccounts(accounts);
107         authProfileDAO.save(profile);
108     }
109 
110     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
111     public void update(final String owner, final GoogleMfaAuthAccount account) {
112         AuthProfile authProfile = authProfileDAO.findByOwner(owner).
113                 orElseThrow(() -> new NotFoundException("Could not find account for Owner " + owner));
114         List<GoogleMfaAuthAccount> accounts = authProfile.getGoogleMfaAuthAccounts();
115         if (accounts.removeIf(acct -> acct.getId() == account.getId())) {
116             accounts.add(account);
117             authProfile.setGoogleMfaAuthAccounts(accounts);
118             authProfileDAO.save(authProfile);
119         }
120     }
121 
122     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
123     public List<GoogleMfaAuthAccount> read(final String owner) {
124         return authProfileDAO.findByOwner(owner).
125                 stream().
126                 map(AuthProfile::getGoogleMfaAuthAccounts).
127                 filter(Objects::nonNull).
128                 filter(accounts -> !accounts.isEmpty()).
129                 findFirst().
130                 orElseThrow(() -> new NotFoundException("Could not find account for Owner " + owner));
131     }
132 
133     @PreAuthorize("hasRole('" + IdRepoEntitlement.ANONYMOUS + "')")
134     @Transactional(readOnly = true)
135     public GoogleMfaAuthAccount read(final long id) {
136         return authProfileDAO.findAll(-1, -1).
137                 stream().
138                 map(AuthProfile::getGoogleMfaAuthAccounts).
139                 filter(Objects::nonNull).
140                 map(accounts -> accounts.stream().
141                 filter(acct -> acct.getId() == id).
142                 findFirst().
143                 orElse(null)).
144                 filter(Objects::nonNull).
145                 findFirst().
146                 orElse(null);
147     }
148 }