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;
20  
21  import java.io.OutputStream;
22  import java.lang.reflect.Method;
23  import java.util.List;
24  import java.util.Optional;
25  import java.util.stream.Collectors;
26  import org.apache.commons.lang3.StringUtils;
27  import org.apache.commons.lang3.tuple.Pair;
28  import org.apache.syncope.common.keymaster.client.api.ConfParamOps;
29  import org.apache.syncope.common.lib.SyncopeConstants;
30  import org.apache.syncope.common.lib.to.EntityTO;
31  import org.apache.syncope.common.lib.to.GroupTO;
32  import org.apache.syncope.common.lib.to.TypeExtensionTO;
33  import org.apache.syncope.common.lib.types.AnyTypeKind;
34  import org.apache.syncope.common.lib.types.IdRepoEntitlement;
35  import org.apache.syncope.core.persistence.api.content.ContentExporter;
36  import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
37  import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
38  import org.apache.syncope.core.persistence.api.dao.GroupDAO;
39  import org.apache.syncope.core.persistence.api.dao.NotFoundException;
40  import org.apache.syncope.core.persistence.api.dao.RealmDAO;
41  import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
42  import org.apache.syncope.core.persistence.api.dao.search.AttrCond;
43  import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
44  import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
45  import org.apache.syncope.core.persistence.api.entity.Realm;
46  import org.apache.syncope.core.persistence.api.entity.group.Group;
47  import org.apache.syncope.core.persistence.api.entity.group.TypeExtension;
48  import org.apache.syncope.core.provisioning.api.data.GroupDataBinder;
49  import org.apache.syncope.core.spring.security.AuthContextUtils;
50  import org.springframework.security.access.prepost.PreAuthorize;
51  import org.springframework.transaction.annotation.Transactional;
52  
53  @Transactional(readOnly = true)
54  public class SyncopeLogic extends AbstractLogic<EntityTO> {
55  
56      protected final RealmDAO realmDAO;
57  
58      protected final AnyTypeDAO anyTypeDAO;
59  
60      protected final GroupDAO groupDAO;
61  
62      protected final AnySearchDAO anySearchDAO;
63  
64      protected final GroupDataBinder groupDataBinder;
65  
66      protected final ConfParamOps confParamOps;
67  
68      protected final ContentExporter exporter;
69  
70      public SyncopeLogic(
71              final RealmDAO realmDAO,
72              final AnyTypeDAO anyTypeDAO,
73              final GroupDAO groupDAO,
74              final AnySearchDAO anySearchDAO,
75              final GroupDataBinder groupDataBinder,
76              final ConfParamOps confParamOps,
77              final ContentExporter exporter) {
78  
79          this.realmDAO = realmDAO;
80          this.anyTypeDAO = anyTypeDAO;
81          this.groupDAO = groupDAO;
82          this.anySearchDAO = anySearchDAO;
83          this.groupDataBinder = groupDataBinder;
84          this.confParamOps = confParamOps;
85          this.exporter = exporter;
86      }
87  
88      public boolean isSelfRegAllowed() {
89          return confParamOps.get(AuthContextUtils.getDomain(), "selfRegistration.allowed", false, Boolean.class);
90      }
91  
92      public boolean isPwdResetAllowed() {
93          return confParamOps.get(AuthContextUtils.getDomain(), "passwordReset.allowed", false, Boolean.class);
94      }
95  
96      public boolean isPwdResetRequiringSecurityQuestions() {
97          return confParamOps.get(AuthContextUtils.getDomain(), "passwordReset.securityQuestion", true, Boolean.class);
98      }
99  
100     @PreAuthorize("isAuthenticated()")
101     public Pair<Integer, List<GroupTO>> searchAssignableGroups(
102             final String realm,
103             final String term,
104             final int page,
105             final int size) {
106 
107         Realm base = Optional.ofNullable(realmDAO.findByFullPath(realm)).
108                 orElseThrow(() -> new NotFoundException("Realm " + realm));
109 
110         AnyCond termCond;
111         if (StringUtils.isNotBlank(term)) {
112             termCond = new AnyCond(AttrCond.Type.ILIKE);
113             termCond.setSchema("name");
114             termCond.setExpression(term.replace("*", "%"));
115         } else {
116             termCond = new AnyCond(AttrCond.Type.ISNOTNULL);
117             termCond.setSchema("key");
118         }
119         SearchCond searchCond = SearchCond.getLeaf(termCond);
120 
121         int count = anySearchDAO.count(base, true, SyncopeConstants.FULL_ADMIN_REALMS, searchCond, AnyTypeKind.GROUP);
122 
123         OrderByClause orderByClause = new OrderByClause();
124         orderByClause.setField("name");
125         orderByClause.setDirection(OrderByClause.Direction.ASC);
126         List<Group> matching = anySearchDAO.search(
127                 base,
128                 true,
129                 SyncopeConstants.FULL_ADMIN_REALMS,
130                 searchCond,
131                 page,
132                 size,
133                 List.of(orderByClause),
134                 AnyTypeKind.GROUP);
135         List<GroupTO> result = matching.stream().
136                 map(group -> groupDataBinder.getGroupTO(group, false)).collect(Collectors.toList());
137 
138         return Pair.of(count, result);
139     }
140 
141     @PreAuthorize("isAuthenticated()")
142     public TypeExtensionTO readTypeExtension(final String groupName) {
143         Group group = groupDAO.findByName(groupName);
144         if (group == null) {
145             throw new NotFoundException("Group " + groupName);
146         }
147         Optional<? extends TypeExtension> typeExt = group.getTypeExtension(anyTypeDAO.findUser());
148         if (typeExt.isEmpty()) {
149             throw new NotFoundException("TypeExtension in " + groupName + " for users");
150         }
151 
152         return groupDataBinder.getTypeExtensionTO(typeExt.get());
153     }
154 
155     @PreAuthorize("hasRole('" + IdRepoEntitlement.KEYMASTER + "')")
156     @Transactional(readOnly = true)
157     public void exportInternalStorageContent(final int tableThreshold, final OutputStream os) {
158         try {
159             exporter.export(
160                     AuthContextUtils.getDomain(),
161                     tableThreshold,
162                     os);
163             LOG.debug("Internal storage content successfully exported");
164         } catch (Exception e) {
165             LOG.error("While exporting internal storage content", e);
166         }
167     }
168 
169     @Override
170     protected EntityTO resolveReference(final Method method, final Object... args)
171             throws UnresolvedReferenceException {
172 
173         throw new UnresolvedReferenceException();
174     }
175 }