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.provisioning.java.data;
20  
21  import java.text.ParseException;
22  import java.util.regex.Matcher;
23  import org.apache.commons.lang3.StringUtils;
24  import org.apache.syncope.common.lib.SyncopeClientException;
25  import org.apache.syncope.common.lib.to.NotificationTO;
26  import org.apache.syncope.common.lib.types.AnyTypeKind;
27  import org.apache.syncope.common.lib.types.ClientExceptionType;
28  import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
29  import org.apache.syncope.core.persistence.api.dao.ImplementationDAO;
30  import org.apache.syncope.core.persistence.api.dao.MailTemplateDAO;
31  import org.apache.syncope.core.persistence.api.entity.AnyAbout;
32  import org.apache.syncope.core.persistence.api.entity.AnyType;
33  import org.apache.syncope.core.persistence.api.entity.Entity;
34  import org.apache.syncope.core.persistence.api.entity.EntityFactory;
35  import org.apache.syncope.core.persistence.api.entity.Implementation;
36  import org.apache.syncope.core.persistence.api.entity.MailTemplate;
37  import org.apache.syncope.core.persistence.api.entity.Notification;
38  import org.apache.syncope.core.provisioning.api.IntAttrNameParser;
39  import org.apache.syncope.core.provisioning.api.data.NotificationDataBinder;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  public class NotificationDataBinderImpl implements NotificationDataBinder {
44  
45      protected static final Logger LOG = LoggerFactory.getLogger(NotificationDataBinder.class);
46  
47      protected final MailTemplateDAO mailTemplateDAO;
48  
49      protected final AnyTypeDAO anyTypeDAO;
50  
51      protected final ImplementationDAO implementationDAO;
52  
53      protected final EntityFactory entityFactory;
54  
55      protected final IntAttrNameParser intAttrNameParser;
56  
57      public NotificationDataBinderImpl(
58              final MailTemplateDAO mailTemplateDAO,
59              final AnyTypeDAO anyTypeDAO,
60              final ImplementationDAO implementationDAO,
61              final EntityFactory entityFactory,
62              final IntAttrNameParser intAttrNameParser) {
63  
64          this.mailTemplateDAO = mailTemplateDAO;
65          this.anyTypeDAO = anyTypeDAO;
66          this.implementationDAO = implementationDAO;
67          this.entityFactory = entityFactory;
68          this.intAttrNameParser = intAttrNameParser;
69      }
70  
71      @Override
72      public NotificationTO getNotificationTO(final Notification notification) {
73          NotificationTO notificationTO = new NotificationTO();
74          notificationTO.setKey(notification.getKey());
75          notificationTO.setTemplate(notification.getTemplate().getKey());
76          notificationTO.getEvents().addAll(notification.getEvents());
77          notificationTO.setRecipientsFIQL(notification.getRecipientsFIQL());
78          notificationTO.getStaticRecipients().addAll(notification.getStaticRecipients());
79          notificationTO.setRecipientAttrName(notification.getRecipientAttrName());
80          notificationTO.setSelfAsRecipient(notification.isSelfAsRecipient());
81          notificationTO.setSender(notification.getSender());
82          notificationTO.setSubject(notification.getSubject());
83          notificationTO.setTraceLevel(notification.getTraceLevel());
84          notificationTO.setActive(notification.isActive());
85  
86          notification.getAbouts().forEach(about -> notificationTO.getAbouts().
87                  put(about.getAnyType().getKey(), about.get()));
88  
89          if (notification.getRecipientsProvider() != null) {
90              notificationTO.setRecipientsProvider(notification.getRecipientsProvider().getKey());
91          }
92  
93          return notificationTO;
94      }
95  
96      @Override
97      public Notification create(final NotificationTO notificationTO) {
98          Notification result = entityFactory.newEntity(Notification.class);
99          update(result, notificationTO);
100         return result;
101     }
102 
103     @Override
104     public void update(final Notification notification, final NotificationTO notificationTO) {
105         notification.setRecipientsFIQL(notificationTO.getRecipientsFIQL());
106 
107         notification.getStaticRecipients().clear();
108         notification.getStaticRecipients().addAll(notificationTO.getStaticRecipients());
109 
110         notification.setRecipientAttrName(notificationTO.getRecipientAttrName());
111         notification.setSelfAsRecipient(notificationTO.isSelfAsRecipient());
112         notification.setSender(notificationTO.getSender());
113         notification.setSubject(notificationTO.getSubject());
114         notification.setTraceLevel(notificationTO.getTraceLevel());
115         notification.setActive(notificationTO.isActive());
116 
117         notification.getEvents().clear();
118         notification.getEvents().addAll(notificationTO.getEvents());
119 
120         SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.RequiredValuesMissing);
121 
122         MailTemplate template = mailTemplateDAO.find(notificationTO.getTemplate());
123         if (template == null) {
124             sce.getElements().add("template");
125         }
126         notification.setTemplate(template);
127 
128         if (notification.getEvents().isEmpty()) {
129             sce.getElements().add("events");
130         }
131 
132         if (!notification.getStaticRecipients().isEmpty()) {
133             notification.getStaticRecipients().forEach(mail -> {
134                 Matcher matcher = Entity.EMAIL_PATTERN.matcher(mail);
135                 if (!matcher.matches()) {
136                     LOG.error("Invalid mail address: {}", mail);
137                     sce.getElements().add("staticRecipients: " + mail);
138                 }
139             });
140         }
141 
142         if (!sce.isEmpty()) {
143             throw sce;
144         }
145 
146         // 1. add or update all (valid) abouts from TO
147         notificationTO.getAbouts().entrySet().stream().
148                 filter(entry -> StringUtils.isNotBlank(entry.getValue())).
149                 forEachOrdered((entry) -> {
150 
151                     AnyType anyType = anyTypeDAO.find(entry.getKey());
152                     if (anyType == null) {
153                         LOG.debug("Invalid AnyType {} specified, ignoring...", entry.getKey());
154                     } else {
155                         AnyAbout about = notification.getAbout(anyType).orElse(null);
156                         if (about == null) {
157                             about = entityFactory.newEntity(AnyAbout.class);
158                             about.setAnyType(anyType);
159                             about.setNotification(notification);
160 
161                             notification.add(about);
162                         }
163                         about.set(entry.getValue());
164                     }
165                 });
166 
167         // 2. remove all abouts not contained in the TO
168         notification.getAbouts().
169                 removeIf(anyAbout -> !notificationTO.getAbouts().containsKey(anyAbout.getAnyType().getKey()));
170 
171         // 3. verify recipientAttrName
172         try {
173             intAttrNameParser.parse(notification.getRecipientAttrName(), AnyTypeKind.USER);
174         } catch (ParseException e) {
175             SyncopeClientException invalidRequest = SyncopeClientException.build(ClientExceptionType.InvalidRequest);
176             invalidRequest.getElements().add(e.getMessage());
177             throw invalidRequest;
178         }
179 
180         if (notificationTO.getRecipientsProvider() == null) {
181             notification.setRecipientsProvider(null);
182         } else {
183             Implementation recipientsProvider = implementationDAO.find(notificationTO.getRecipientsProvider());
184             if (recipientsProvider == null) {
185                 LOG.debug("Invalid " + Implementation.class.getSimpleName() + " {}, ignoring...",
186                         notificationTO.getRecipientsProvider());
187             } else {
188                 notification.setRecipientsProvider(recipientsProvider);
189             }
190         }
191     }
192 }