From f7ff44b49352d6a9d930d1741cc1fb45eedce33d Mon Sep 17 00:00:00 2001 From: David Lemaignent Date: Thu, 28 Jan 2021 18:41:20 +0100 Subject: [PATCH] fix OTP + improve authentication --- pom.xml | 10 +- .../config/GlobalProperties.java | 21 +++ .../config/security/WebSecurityConfig.java | 4 +- .../otp/OtpAuthenticationProvider.java | 4 +- .../esupsignature/config/sms/SmsConfig.java | 2 +- .../dss/config/DSSBeanConfig.java | 15 +-- .../esupsignature/entity/User.java | 14 +- .../esupsignature/entity/UserPropertie.java | 46 +------ .../esupsignature/entity/UserShare.java | 21 +++ .../repository/SignBookRepository.java | 3 + .../repository/UserPropertieRepository.java | 10 +- .../repository/UserShareRepository.java | 1 + .../esupsignature/service/DataService.java | 6 - .../esupsignature/service/FormService.java | 7 - .../service/SignBookService.java | 4 + .../service/SignRequestService.java | 43 ++++-- .../service/UserPropertieService.java | 101 +++++--------- .../esupsignature/service/UserService.java | 26 ++-- .../service/UserShareService.java | 97 ++++++++++---- .../service/WorkflowService.java | 38 ++---- .../{utils => interfaces}/sms/SmsService.java | 2 +- .../sms/impl/SMSUSmsService.java | 4 +- .../service/ldap/LdapAliasService.java | 3 +- .../service/ldap/LdapGroupService.java | 25 ++-- .../service/ldap/LdapPersonService.java | 1 - .../oauth/OAuthSecurityServiceImpl.java | 2 +- .../ShibAuthenticatedUserDetailsService.java | 14 +- .../service/utils/mail/MailService.java | 6 +- .../GlobalAttributsControllerAdvice.java | 5 +- .../web/controller/user/DataController.java | 5 +- .../controller/user/SignBookController.java | 13 +- .../user/SignRequestController.java | 24 +++- .../web/controller/user/UserController.java | 119 +++-------------- .../controller/user/UserShareController.java | 126 ++++++++++++++++++ .../web/controller/user/WizardController.java | 13 +- .../controller/user/WorkflowController.java | 10 ++ .../web/otp/WsOtpSignController.java | 2 +- src/main/resources/application.yml | 1 + .../static/js/modules/ui/GlobalUi.js | 2 +- .../resources/static/js/modules/ui/HomeUi.js | 11 ++ .../resources/static/js/modules/ui/WizUi.js | 2 +- .../js/modules/ui/datas/CreateDataUi.js | 2 +- .../ui/signrequests/ListSignRequestUi.js | 28 ++-- .../modules/ui/signrequests/SignPosition.js | 23 ++-- .../modules/ui/signrequests/WorkspacePdf.js | 36 ++++- .../static/js/modules/ui/users/ShareUi.js | 33 ++++- .../static/js/modules/ui/users/UserUi.js | 12 ++ .../static/js/modules/utils/PdfViewer.js | 12 +- .../static/js/modules/utils/SelectUser.js | 67 +++++++--- .../static/js/prototypes/SignRequestParams.js | 4 +- .../admin/workflows/cards/stepscard.html | 4 +- .../resources/templates/fragments/head.html | 3 + .../resources/templates/fragments/nav.html | 13 +- .../resources/templates/fragments/new.html | 4 +- .../templates/fragments/side-user.html | 2 +- .../templates/user/datas/create.html | 4 - .../includes/modals/attachment.html | 4 +- .../templates/user/signrequests/show.html | 8 +- .../templates/user/users/properties.html | 18 +-- .../templates/user/users/shares/list.html | 32 ++++- .../templates/user/users/shares/update.html | 111 ++++++++------- .../templates/user/workflows/show.html | 2 +- src/main/resources/update_1.4_clean.sql | 2 +- 63 files changed, 782 insertions(+), 505 deletions(-) rename src/main/java/org/esupportail/esupsignature/service/{utils => interfaces}/sms/SmsService.java (78%) rename src/main/java/org/esupportail/esupsignature/service/{utils => interfaces}/sms/impl/SMSUSmsService.java (94%) create mode 100644 src/main/java/org/esupportail/esupsignature/web/controller/user/UserShareController.java diff --git a/pom.xml b/pom.xml index d0ad4e00c..8bd15d92f 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,7 @@ org.esupportail esup-signature - 1.6-SNAPSHOT + 1.6.1-SNAPSHOT esup-signature org.esupportail.esupsignature.EsupSignatureApplication @@ -135,7 +135,7 @@ org.webjars popper.js - 2.0.2 + 2.5.4 @@ -205,6 +205,12 @@ 4.17.47 + + org.webjars.bower + bootbox.js + 5.3.2 + + org.webjars summernote diff --git a/src/main/java/org/esupportail/esupsignature/config/GlobalProperties.java b/src/main/java/org/esupportail/esupsignature/config/GlobalProperties.java index 3022f481f..1aae2bc40 100644 --- a/src/main/java/org/esupportail/esupsignature/config/GlobalProperties.java +++ b/src/main/java/org/esupportail/esupsignature/config/GlobalProperties.java @@ -10,6 +10,9 @@ @ConfigurationProperties(prefix="global") public class GlobalProperties implements Cloneable { + /** + * Chemin d'acces à l'application + */ private String rootUrl; private String domain; private String nexuUrl; @@ -28,6 +31,16 @@ public class GlobalProperties implements Cloneable { private String version = ""; private String applicationEmail = "esup.signature@univ-ville.fr"; private int hoursBeforeRefreshNotif = 24; + /** + * Choisir le fonctionnement des délégations : + *
    + *
  • 0 : système de délégation désactivé
  • + *
  • 1 : le délégué ne peut signer qu'avec sa propre signature
  • + *
  • 2 : le délégué ne peut signer qu'avec la signature du mandant
  • + *
  • 2 : le mandant ne peut choisir la signature du délégué
  • + *
+ */ + private int shareMode = 0; public String getRootUrl() { return rootUrl; @@ -172,4 +185,12 @@ public int getHoursBeforeRefreshNotif() { public void setHoursBeforeRefreshNotif(int hoursBeforeRefreshNotif) { this.hoursBeforeRefreshNotif = hoursBeforeRefreshNotif; } + + public int getShareMode() { + return shareMode; + } + + public void setShareMode(int shareMode) { + this.shareMode = shareMode; + } } diff --git a/src/main/java/org/esupportail/esupsignature/config/security/WebSecurityConfig.java b/src/main/java/org/esupportail/esupsignature/config/security/WebSecurityConfig.java index 924c2a2a5..c6f121ed5 100644 --- a/src/main/java/org/esupportail/esupsignature/config/security/WebSecurityConfig.java +++ b/src/main/java/org/esupportail/esupsignature/config/security/WebSecurityConfig.java @@ -105,8 +105,8 @@ private void setAuthorizeRequests(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/admin/", "/admin/**").access("hasRole('ROLE_ADMIN')") - .antMatchers("/user/", "/user/**").access("hasRole('ROLE_USER')") - .antMatchers("/sse/", "/sse/**").access("hasRole('ROLE_USER')") + .antMatchers("/user/", "/user/**").access("hasAnyRole('ROLE_USER', 'ROLE_OTP')") + .antMatchers("/sse/", "/sse/**").access("hasAnyRole('ROLE_USER', 'ROLE_OTP')") .antMatchers("/public/", "/public/**").permitAll() .antMatchers("/h2-console/**").access("hasRole('ROLE_ADMIN')") .antMatchers("/webjars/**").permitAll(); diff --git a/src/main/java/org/esupportail/esupsignature/config/security/otp/OtpAuthenticationProvider.java b/src/main/java/org/esupportail/esupsignature/config/security/otp/OtpAuthenticationProvider.java index 9d439c35a..65dcc0d27 100644 --- a/src/main/java/org/esupportail/esupsignature/config/security/otp/OtpAuthenticationProvider.java +++ b/src/main/java/org/esupportail/esupsignature/config/security/otp/OtpAuthenticationProvider.java @@ -15,9 +15,9 @@ public class OtpAuthenticationProvider implements AuthenticationProvider { public Authentication authenticate(Authentication authentication) throws AuthenticationException { String name = authentication.getName(); String password = authentication.getCredentials().toString(); - SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_OTP"); List simpleGrantedAuthorities = new ArrayList<>(); - simpleGrantedAuthorities.add(authority); + simpleGrantedAuthorities.add(new SimpleGrantedAuthority("ROLE_OTP")); +// simpleGrantedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER")); return new UsernamePasswordAuthenticationToken(name, password, simpleGrantedAuthorities); } diff --git a/src/main/java/org/esupportail/esupsignature/config/sms/SmsConfig.java b/src/main/java/org/esupportail/esupsignature/config/sms/SmsConfig.java index 7579e58e4..fd611c5fb 100644 --- a/src/main/java/org/esupportail/esupsignature/config/sms/SmsConfig.java +++ b/src/main/java/org/esupportail/esupsignature/config/sms/SmsConfig.java @@ -1,6 +1,6 @@ package org.esupportail.esupsignature.config.sms; -import org.esupportail.esupsignature.service.utils.sms.SmsService; +import org.esupportail.esupsignature.service.interfaces.sms.SmsService; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/org/esupportail/esupsignature/dss/config/DSSBeanConfig.java b/src/main/java/org/esupportail/esupsignature/dss/config/DSSBeanConfig.java index da501660a..bdc08890d 100644 --- a/src/main/java/org/esupportail/esupsignature/dss/config/DSSBeanConfig.java +++ b/src/main/java/org/esupportail/esupsignature/dss/config/DSSBeanConfig.java @@ -156,14 +156,13 @@ public OnlineOCSPSource onlineOcspSource() { public KeyStoreCertificateSource ojContentKeyStore() throws IOException { File keystoreFile = new File(dssProperties.getKsFilename()); KeyStoreCertificateSource keyStoreCertificateSource = null; - if(!keystoreFile.exists()) { - log.info("creating oj file in " + keystoreFile.getAbsolutePath()); - if(keystoreFile.createNewFile()) { - keyStoreCertificateSource = new KeyStoreCertificateSource((InputStream) null, dssProperties.getKsType(), dssProperties.getKsPassword()); - } - } else { - log.info("using exising oj file " + keystoreFile.getAbsolutePath()); - keyStoreCertificateSource = new KeyStoreCertificateSource(keystoreFile, dssProperties.getKsType(), dssProperties.getKsPassword()); + if(keystoreFile.exists()) { + log.info("delete old oj file"); + keystoreFile.delete(); + } + log.info("creating oj file in " + keystoreFile.getAbsolutePath()); + if(keystoreFile.createNewFile()) { + keyStoreCertificateSource = new KeyStoreCertificateSource((InputStream) null, dssProperties.getKsType(), dssProperties.getKsPassword()); } return keyStoreCertificateSource; } diff --git a/src/main/java/org/esupportail/esupsignature/entity/User.java b/src/main/java/org/esupportail/esupsignature/entity/User.java index 6124e1460..59b6759fb 100644 --- a/src/main/java/org/esupportail/esupsignature/entity/User.java +++ b/src/main/java/org/esupportail/esupsignature/entity/User.java @@ -31,6 +31,7 @@ public class User { private String email; @ElementCollection + @JsonIgnore private Map uiParams = new LinkedHashMap<>(); private String formMessages = ""; @@ -55,6 +56,9 @@ public class User { @Transient private String signImageBase64; + @Transient + private Long userShareId; + @JsonIgnore @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, orphanRemoval = true) private Document keystore = new Document(); @@ -193,7 +197,15 @@ public void setSignImageBase64(String signImageBase64) { this.signImageBase64 = signImageBase64; } - public Document getKeystore() { + public Long getUserShareId() { + return userShareId; + } + + public void setUserShareId(Long userShareId) { + this.userShareId = userShareId; + } + + public Document getKeystore() { return this.keystore; } diff --git a/src/main/java/org/esupportail/esupsignature/entity/UserPropertie.java b/src/main/java/org/esupportail/esupsignature/entity/UserPropertie.java index faa23d0f8..d3595e263 100644 --- a/src/main/java/org/esupportail/esupsignature/entity/UserPropertie.java +++ b/src/main/java/org/esupportail/esupsignature/entity/UserPropertie.java @@ -3,8 +3,7 @@ import org.springframework.beans.factory.annotation.Configurable; import javax.persistence.*; -import java.util.ArrayList; -import java.util.List; +import java.util.*; @Entity @Configurable @@ -14,18 +13,11 @@ public class UserPropertie { @GeneratedValue(strategy = GenerationType.AUTO) private Long id; - private Integer score = 0; - @ManyToOne(fetch = FetchType.LAZY) private User user; - @ManyToOne(fetch = FetchType.LAZY) - private WorkflowStep workflowStep; - - @ManyToMany - private List users = new ArrayList<>(); - - private String targetEmail; + @ElementCollection + private Map favorites = new HashMap<>(); public Long getId() { return this.id; @@ -35,14 +27,6 @@ public void setId(Long id) { this.id = id; } - public Integer getScore() { - return score; - } - - public void setScore(Integer score) { - this.score = score; - } - public User getUser() { return user; } @@ -51,27 +35,11 @@ public void setUser(User user) { this.user = user; } - public WorkflowStep getWorkflowStep() { - return workflowStep; - } - - public void setWorkflowStep(WorkflowStep workflowStep) { - this.workflowStep = workflowStep; - } - - public List getUsers() { - return users; - } - - public void setUsers(List users) { - this.users = users; - } - - public String getTargetEmail() { - return targetEmail; + public Map getFavorites() { + return favorites; } - public void setTargetEmail(String targetEmail) { - this.targetEmail = targetEmail; + public void setFavorites(Map users) { + this.favorites = users; } } diff --git a/src/main/java/org/esupportail/esupsignature/entity/UserShare.java b/src/main/java/org/esupportail/esupsignature/entity/UserShare.java index 8a8cd0012..6be24b161 100644 --- a/src/main/java/org/esupportail/esupsignature/entity/UserShare.java +++ b/src/main/java/org/esupportail/esupsignature/entity/UserShare.java @@ -20,12 +20,16 @@ public class UserShare { @ManyToMany private List toUsers = new ArrayList<>(); + private Boolean signWithOwnSign = true; + @ManyToOne(fetch = FetchType.LAZY) private Form form; @ManyToOne(fetch = FetchType.LAZY) private Workflow workflow; + private Boolean allSignRequests = false; + @Temporal(TemporalType.TIMESTAMP) private Date beginDate; @@ -59,6 +63,15 @@ public void setToUsers(List toUsers) { this.toUsers = toUsers; } + + public Boolean getSignWithOwnSign() { + return signWithOwnSign; + } + + public void setSignWithOwnSign(Boolean signWithOwnSign) { + this.signWithOwnSign = signWithOwnSign; + } + public Form getForm() { return form; } @@ -75,6 +88,14 @@ public void setWorkflow(Workflow workflow) { this.workflow = workflow; } + public Boolean getAllSignRequests() { + return allSignRequests; + } + + public void setAllSignRequests(Boolean all) { + this.allSignRequests = all; + } + public Date getBeginDate() { return beginDate; } diff --git a/src/main/java/org/esupportail/esupsignature/repository/SignBookRepository.java b/src/main/java/org/esupportail/esupsignature/repository/SignBookRepository.java index bbcaa8ad2..928217ad1 100644 --- a/src/main/java/org/esupportail/esupsignature/repository/SignBookRepository.java +++ b/src/main/java/org/esupportail/esupsignature/repository/SignBookRepository.java @@ -6,6 +6,7 @@ import org.esupportail.esupsignature.repository.custom.SignBookRepositoryCustom; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.Param; import java.util.List; @@ -13,6 +14,8 @@ public interface SignBookRepository extends CrudRepository, Sign List findByName(String name); List findByCreateByEppn(String createByEppn); List findByStatus(SignRequestStatus signRequestStatus); + @Query("select count(s.id) from SignBook s join s.liveWorkflow.currentStep.recipients r where s.status = 'pending' and r.user.eppn = :recipientUserEppn and r.signed is false") + Long countByRecipientUserToSign(@Param("recipientUserEppn") String recipientUserEppn); @Query("select s from SignBook s where s.status = :signRequestStatus and s.liveWorkflow.documentsTargetUri is not null") List findByStatusAndDocumentsTargetUriIsNotNull(SignRequestStatus signRequestStatus); @Query("select s from SignBook s where s.status = :signRequestStatus and s.liveWorkflow.workflow.id = :workflowId") diff --git a/src/main/java/org/esupportail/esupsignature/repository/UserPropertieRepository.java b/src/main/java/org/esupportail/esupsignature/repository/UserPropertieRepository.java index 80d1a4472..b2e4b09ff 100644 --- a/src/main/java/org/esupportail/esupsignature/repository/UserPropertieRepository.java +++ b/src/main/java/org/esupportail/esupsignature/repository/UserPropertieRepository.java @@ -1,16 +1,8 @@ package org.esupportail.esupsignature.repository; -import org.esupportail.esupsignature.entity.User; import org.esupportail.esupsignature.entity.UserPropertie; -import org.esupportail.esupsignature.entity.WorkflowStep; import org.springframework.data.repository.CrudRepository; -import java.util.List; - public interface UserPropertieRepository extends CrudRepository { - List findByUserEppn(String userEppn); - List findByWorkflowStep(WorkflowStep workflowStep); - List findByUserEppnAndWorkflowStepId(String userEppn, Long workflowStepId); - List findByUserAndWorkflowStepAndUsersIn(User user, WorkflowStep workflowStep, List users); - List findByUserAndTargetEmailAndWorkflowStep(User user, String targetEmail, WorkflowStep workflowStep); + UserPropertie findByUserEppn(String userEppn); } diff --git a/src/main/java/org/esupportail/esupsignature/repository/UserShareRepository.java b/src/main/java/org/esupportail/esupsignature/repository/UserShareRepository.java index fc058a09c..5b9eb2e4d 100644 --- a/src/main/java/org/esupportail/esupsignature/repository/UserShareRepository.java +++ b/src/main/java/org/esupportail/esupsignature/repository/UserShareRepository.java @@ -17,6 +17,7 @@ public interface UserShareRepository extends CrudRepository { List findByWorkflowId(Long workflowId); List findByFormId(Long formId); List findByUserEppnAndToUsersEppnInAndWorkflowAndShareTypesContains(String userEppn, List toUsers, Workflow workflow, ShareType shareType); + List findByUserEppnAndToUsersEppnInAndAllSignRequestsIsTrueAndShareTypesContains(String userEppn, List toUsers,ShareType shareType); List findByUserEppnAndToUsersEppnInAndFormAndShareTypesContains(String userEppn, List toUsers, Form form, ShareType shareType); List findByToUsersEppnInAndShareTypesContains(List toUsers, ShareType shareType); } diff --git a/src/main/java/org/esupportail/esupsignature/service/DataService.java b/src/main/java/org/esupportail/esupsignature/service/DataService.java index d47fab39c..b91795a4a 100644 --- a/src/main/java/org/esupportail/esupsignature/service/DataService.java +++ b/src/main/java/org/esupportail/esupsignature/service/DataService.java @@ -44,9 +44,6 @@ public class DataService { @Resource private PreFillService preFillService; - @Resource - private UserPropertieService userPropertieService; - @Resource private SignRequestService signRequestService; @@ -89,8 +86,6 @@ public SignBook sendForSign(Data data, List recipientEmails, List|]", "-").replace("\t", ""); Workflow modelWorkflow = workflowService.getWorkflowByName(data.getForm().getWorkflowType()); @@ -110,7 +105,6 @@ public SignBook sendForSign(Data data, List recipientEmails, List managers, String[] formRepository.save(form); } - public void deleteForm(Long formId) { Form form = formRepository.findById(formId).get(); List userShares = userShareService.getUserSharesByForm(form); @@ -150,12 +149,6 @@ public void deleteForm(Long formId) { userShareService.delete(userShare); } dataService.nullifyForm(form); - for (WorkflowStep workflowStep : workflowService.getWorkflowByName(form.getWorkflowType()).getWorkflowSteps()) { - List userProperties = userPropertieService.getByWorkflowStep(workflowStep); - for(UserPropertie userPropertie : userProperties) { - userPropertieService.delete(userPropertie); - } - } formRepository.delete(form); } diff --git a/src/main/java/org/esupportail/esupsignature/service/SignBookService.java b/src/main/java/org/esupportail/esupsignature/service/SignBookService.java index fdaed9982..aa47a7881 100644 --- a/src/main/java/org/esupportail/esupsignature/service/SignBookService.java +++ b/src/main/java/org/esupportail/esupsignature/service/SignBookService.java @@ -510,5 +510,9 @@ public List getByLiveWorkflowAndStatus(LiveWorkflow liveWorkflow, Sign return signBookRepository.findByLiveWorkflowAndStatus(liveWorkflow, signRequestStatus); } + public Long nbToSignSignBooks(String userEppn) { + return signBookRepository.countByRecipientUserToSign(userEppn); + } + } diff --git a/src/main/java/org/esupportail/esupsignature/service/SignRequestService.java b/src/main/java/org/esupportail/esupsignature/service/SignRequestService.java index 126e075dd..4a9af29a1 100644 --- a/src/main/java/org/esupportail/esupsignature/service/SignRequestService.java +++ b/src/main/java/org/esupportail/esupsignature/service/SignRequestService.java @@ -156,7 +156,7 @@ public List getSignRequestsForCurrentUserByStatus(String userEppn, List signRequests = getSignRequestsByStatus(userEppn, statusFilter); if(!userEppn.equals(authUserEppn)) { for(SignRequest signRequest: signRequests) { - if(userShareService.checkShare(userEppn, authUserEppn, signRequest)) { + if(userShareService.checkShare(userEppn, authUserEppn, signRequest) || getSharedSignedSignRequests(authUserEppn).contains(signRequest)) { signRequestList.add(signRequest); } } @@ -166,6 +166,18 @@ public List getSignRequestsForCurrentUserByStatus(String userEppn, return signRequestList.stream().sorted(Comparator.comparing(SignRequest::getId)).collect(Collectors.toList()); } + public boolean isUserInRecipients(SignRequest signRequest, String userEppn) { + boolean isInRecipients = false; + Set recipients = signRequest.getRecipientHasSigned().keySet(); + for(Recipient recipient : recipients) { + if (recipient.getUser().getEppn().equals(userEppn)) { + isInRecipients = true; + break; + } + } + return isInRecipients; + } + public List getSignRequestsByStatus(String userEppn, String statusFilter) { Set signRequests = new HashSet<>(); if (statusFilter != null) { @@ -198,7 +210,7 @@ public List getSignRequestsByStatus(String userEppn, String statusF return new ArrayList<>(signRequests); } - public Long nbToSignRequests(String userEppn) { + public Long nbToSignSignRequests(String userEppn) { return signRequestRepository.countByRecipientUserToSign(userEppn); } @@ -301,7 +313,7 @@ public void pendingSignRequest(SignRequest signRequest, String authUserEppn) { } @Transactional - public boolean initSign(Long signRequestId, String sseId, String signRequestParamsJsonString, String comment, String formData, Boolean visual, String password, String userEppn, String authUserEppn) { + public boolean initSign(Long signRequestId, String sseId, String signRequestParamsJsonString, String comment, String formData, Boolean visual, String password, Long userShareId, String userEppn, String authUserEppn) { SignRequest signRequest = getSignRequestsFullById(signRequestId, userEppn, authUserEppn); Map formDataMap = null; List toRemoveKeys = new ArrayList<>(); @@ -344,7 +356,7 @@ public boolean initSign(Long signRequestId, String sseId, String signRequestPara signRequest.setComment(comment); User user = userService.getByEppn(userEppn); User authUser = userService.getByEppn(authUserEppn); - sign(signRequest, password, visual, signRequestParamses, formDataMap, sseId, user, authUser); + sign(signRequest, password, visual, signRequestParamses, formDataMap, sseId, user, authUser, userShareId); TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization(){ public void afterCommit(){ eventService.publishEvent(new JsonMessage("end", "Signature terminée", null), "sign", sseId); @@ -360,7 +372,14 @@ public void afterCommit(){ } @Transactional - public void sign(SignRequest signRequest, String password, boolean visual, List signRequestParamses, Map formDataMap, String sseId, User user, User authUser) throws EsupSignatureException, IOException, InterruptedException { + public void sign(SignRequest signRequest, String password, boolean visual, List signRequestParamses, Map formDataMap, String sseId, User user, User authUser, Long userShareId) throws EsupSignatureException, IOException, InterruptedException { + User signerUser = user; + if(userShareId != null) { + UserShare userShare = userShareService.getById(userShareId); + if (userShare.getUser().getEppn().equals(user.getEppn()) && userShare.getSignWithOwnSign() != null && userShare.getSignWithOwnSign()) { + signerUser = userService.getByEppn(authUser.getEppn()); + } + } List toSignDocuments = getToSignDocuments(signRequest.getId()); SignType signType = signRequest.getCurrentSignType(); InputStream filledInputStream; @@ -393,7 +412,7 @@ public void sign(SignRequest signRequest, String password, boolean visual, List< if (toSignDocuments.size() == 1 && toSignDocuments.get(0).getContentType().equals("application/pdf") && visual) { eventService.publishEvent(new JsonMessage("step", "Apposition de la signature", null), "sign", sseId); for(SignRequestParams signRequestParams : signRequestParamses) { - signedInputStream = pdfService.stampImage(signedInputStream, signRequest, signRequestParams, user); + signedInputStream = pdfService.stampImage(signedInputStream, signRequest, signRequestParams, signerUser); updateStatus(signRequest, signRequest.getStatus(), "Apposition de la signature", "SUCCESS", signRequestParams.getSignPageNumber(), signRequestParams.getxPos(), signRequestParams.getyPos(), signRequest.getParentSignBook().getLiveWorkflow().getCurrentStepNumber(), user.getEppn(), authUser.getEppn()); } } @@ -406,7 +425,7 @@ public void sign(SignRequest signRequest, String password, boolean visual, List< signRequestParamsService.copySignRequestParams(signRequest, signRequestParamses); toSignDocuments.get(0).setTransientInputStream(filledInputStream); } - certSign(signRequest, user, password, visual, sseId); + certSign(signRequest, signerUser, password, visual, sseId); } if (signType.equals(SignType.visa)) { if(signRequest.getComment() != null && !signRequest.getComment().isEmpty()) { @@ -1042,10 +1061,9 @@ public SignRequest getPreviousSignRequest(Long signRequestId, String userEppn, S } @Transactional - public List getSignImageForSignRequest(SignRequest signRequestRef, String userEppn, String authUserEppn) throws EsupSignatureUserException, IOException { + public List getSignImagesForSignRequest(SignRequest signRequestRef, String userEppn, String authUserEppn, Long userShareId) throws EsupSignatureUserException, IOException { SignRequest signRequest = getSignRequestsFullById(signRequestRef.getId(), userEppn, authUserEppn); signRequestRef.setSignable(signRequest.getSignable()); - User user = userService.getByEppn(userEppn); List signImages = new ArrayList<>(); if (signRequest.getSignedDocuments().size() > 0 || signRequest.getOriginalDocuments().size() > 0) { List toSignDocuments = getToSignDocuments(signRequest.getId()); @@ -1053,6 +1071,13 @@ public List getSignImageForSignRequest(SignRequest signRequestRef, Strin if(signRequest.getParentSignBook().getLiveWorkflow().getCurrentStep().getSignType().equals(SignType.visa)) { signImages.add(fileService.getBase64Image(SignRequestService.class.getResourceAsStream("/sceau.png"), "sceau.png")); } else { + User user = userService.getByEppn(userEppn); + if(userShareId != null) { + UserShare userShare = userShareService.getById(userShareId); + if (userShare.getUser().getEppn().equals(userEppn) && userShare.getSignWithOwnSign() != null && userShare.getSignWithOwnSign()) { + user = userService.getByEppn(authUserEppn); + } + } if (user.getSignImages().size() > 0 && user.getSignImages().get(0) != null && user.getSignImages().get(0).getSize() > 0) { if (checkUserSignRights(signRequest, userEppn, authUserEppn) && user.getKeystore() == null && signRequest.getParentSignBook().getLiveWorkflow().getCurrentStep().getSignType().equals(SignType.certSign)) { signRequestRef.setSignable(false); diff --git a/src/main/java/org/esupportail/esupsignature/service/UserPropertieService.java b/src/main/java/org/esupportail/esupsignature/service/UserPropertieService.java index 854047b2e..d0fb3a70f 100644 --- a/src/main/java/org/esupportail/esupsignature/service/UserPropertieService.java +++ b/src/main/java/org/esupportail/esupsignature/service/UserPropertieService.java @@ -2,105 +2,70 @@ import org.esupportail.esupsignature.entity.User; import org.esupportail.esupsignature.entity.UserPropertie; -import org.esupportail.esupsignature.entity.WorkflowStep; import org.esupportail.esupsignature.repository.UserPropertieRepository; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.ArrayList; +import java.util.Date; import java.util.List; -import java.util.stream.Collectors; +import java.util.Map; @Service public class UserPropertieService { @Resource - private UserService userService; + private UserPropertieRepository userPropertieRepository; @Resource - private UserPropertieRepository userPropertieRepository; + private UserService userService; - public void createUserPropertie(User user, WorkflowStep workflowStep, List users) { - List userProperties = getUserProperties(user.getEppn(), workflowStep.getId()); - if (userProperties.size() == 0) { - addPropertie(user, users, workflowStep); - } else { - for(UserPropertie userPropertie : userProperties) { - if(userPropertie.getUsers().containsAll(users)) { - userPropertie.setScore(userPropertie.getScore() + 1); - } else { - addPropertie(user, users, workflowStep); - } - userPropertieRepository.save(userPropertie); - } + public void createUserPropertieFromMails(User user, List recipientEmails) { + for (String recipientEmail : recipientEmails) { + User favoriteUser = userService.getUserByEmail(recipientEmail); + createUserPropertie(user, favoriteUser); } } - private void addPropertie(User user, List users, WorkflowStep workflowStep) { - UserPropertie userPropertie = new UserPropertie(); - userPropertie.setWorkflowStep(workflowStep); - userPropertie.setScore(1); - userPropertie.getUsers().addAll(users); - userPropertie.setUser(user); - userPropertieRepository.save(userPropertie); - } - - public void createTargetPropertie(User user, WorkflowStep workflowStep, String targetEmail) { - List userProperties = userPropertieRepository.findByUserAndTargetEmailAndWorkflowStep(user, targetEmail, workflowStep); - if (userProperties.size() == 0) { - UserPropertie userPropertie = new UserPropertie(); - userPropertie.setWorkflowStep(workflowStep); - userPropertie.setTargetEmail(targetEmail); - userPropertie.setUser(user); - userPropertieRepository.save(userPropertie); + public void createUserPropertie(User user, User favoriteUser) { + UserPropertie userPropertie = getUserProperties(user.getEppn()); + if (userPropertie == null) { + addPropertie(user, favoriteUser); } else { - UserPropertie userPropertie = userProperties.get(0); - userPropertie.setScore(userPropertie.getScore() + 1); + userPropertie.getFavorites().put(favoriteUser, new Date()); userPropertieRepository.save(userPropertie); } } - public List getFavoritesEmails(String userEppn, Long workflowStepId) { - List userProperties = getUserProperties(userEppn, workflowStepId); - List favoriteUsers = new ArrayList<>(); - int bestScore = 0; - for (UserPropertie userPropertie : userProperties) { - if (userPropertie.getScore() > bestScore) { - favoriteUsers.clear(); - favoriteUsers.addAll(userPropertie.getUsers()); - bestScore = userPropertie.getScore(); - } - } - return favoriteUsers; - } - - public List getUserProperties(String userEppn, Long workflowStepId) { - return userPropertieRepository.findByUserEppnAndWorkflowStepId(userEppn, workflowStepId); + private void addPropertie(User user, User favoriteUser) { + UserPropertie userPropertie = new UserPropertie(); + userPropertie.getFavorites().put(favoriteUser, new Date()); + userPropertie.setUser(user); + userPropertieRepository.save(userPropertie); } - @Transactional - public List getFavoriteRecipientEmail(int stepNumber, WorkflowStep workflowStep, List recipientEmails, String userEppn) { - List users = new ArrayList<>(); - if (recipientEmails != null && recipientEmails.size() > 0) { - recipientEmails = recipientEmails.stream().filter(r -> r.startsWith(String.valueOf(stepNumber))).collect(Collectors.toList()); - for (String recipientEmail : recipientEmails) { - String userEmail = recipientEmail.split("\\*")[1]; - users.add(userService.getUserByEmail(userEmail)); + public List getFavoritesEmails(String userEppn) { + List favoriteUserEmails = new ArrayList<>(); + UserPropertie userPropertie = getUserProperties(userEppn); + if(userPropertie != null) { + Map favorites = userPropertie.getFavorites(); + if (favorites.size() > 0) { + List> entrySet = new ArrayList<>(favorites.entrySet()); + entrySet.sort(Map.Entry.comparingByValue().reversed()); + for (int i = 0; i < Math.min(entrySet.size(), 5); i++) { + favoriteUserEmails.add(entrySet.get(i).getKey().getEmail()); + } } - } else { - List favoritesEmail = getFavoritesEmails(userEppn, workflowStep.getId()); - users.addAll(favoritesEmail); } - return users; + return favoriteUserEmails; } - public List getUserPropertiesByUserEppn(String userEppn) { + public UserPropertie getUserProperties(String userEppn) { return userPropertieRepository.findByUserEppn(userEppn); } - public List getByWorkflowStep(WorkflowStep workflowStep) { - return userPropertieRepository.findByWorkflowStep(workflowStep); + public UserPropertie getUserPropertiesByUserEppn(String userEppn) { + return userPropertieRepository.findByUserEppn(userEppn); } public void delete(UserPropertie userPropertie) { diff --git a/src/main/java/org/esupportail/esupsignature/service/UserService.java b/src/main/java/org/esupportail/esupsignature/service/UserService.java index 92f13daf8..a829071ef 100644 --- a/src/main/java/org/esupportail/esupsignature/service/UserService.java +++ b/src/main/java/org/esupportail/esupsignature/service/UserService.java @@ -184,15 +184,15 @@ public User createUserWithEmail(String mail) { @Transactional public User createUserWithAuthentication(Authentication authentication) { + if(ldapPersonService.getIfAvailable() == null) { + throw new EsupSignatureRuntimeException("Creation of user not implemented without ldap configuration"); + } String uid; if (authentication.getName().contains("@")) { uid = authentication.getName().substring(0, authentication.getName().indexOf("@")); } else { uid = authentication.getName(); } - if(ldapPersonService.getIfAvailable() == null) { - throw new EsupSignatureRuntimeException("Creation of user not implemented without ldap configuration"); - } logger.info("controle de l'utilisateur " + uid); List personLdaps = ldapPersonService.getIfAvailable().getPersonLdap(uid); String eppn = personLdaps.get(0).getEduPersonPrincipalName(); @@ -205,7 +205,7 @@ public User createUserWithAuthentication(Authentication authentication) { return createUser(eppn, name, firstName, mail, UserType.ldap); } - @Transactional + @Transactional public User createUser(String eppn, String name, String firstName, String email, UserType userType) { User user; if (userRepository.countByEppn(eppn) > 0) { @@ -216,7 +216,6 @@ public User createUser(String eppn, String name, String firstName, String email, logger.info("creation de l'utilisateur " + eppn); user = new User(); user.setKeystore(null); - } user.setName(name); user.setFirstname(firstName); @@ -226,16 +225,13 @@ public User createUser(String eppn, String name, String firstName, String email, if(!user.getUserType().equals(UserType.system)) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); if (auth != null) { - String userName = buildEppn(auth.getName()); - if (webSecurityProperties.getGroupToRoleFilterPattern() != null && eppn.equals(userName)) { - logger.info("Mise à jour des rôles de l'utilisateur " + eppn); - Collection authorities = (Collection) auth.getAuthorities(); - if (authorities.size() > 0) { - user.getRoles().clear(); - for (GrantedAuthority authority : authorities) { - if(authority.getAuthority().startsWith("ROLE_")) { - user.getRoles().add(authority.getAuthority()); - } + logger.info("Mise à jour des rôles de l'utilisateur " + eppn); + Collection authorities = (Collection) auth.getAuthorities(); + if (authorities.size() > 0) { + user.getRoles().clear(); + for (GrantedAuthority authority : authorities) { + if(authority.getAuthority().startsWith("ROLE_")) { + user.getRoles().add(authority.getAuthority()); } } } diff --git a/src/main/java/org/esupportail/esupsignature/service/UserShareService.java b/src/main/java/org/esupportail/esupsignature/service/UserShareService.java index c804f2fd4..16c55ec53 100644 --- a/src/main/java/org/esupportail/esupsignature/service/UserShareService.java +++ b/src/main/java/org/esupportail/esupsignature/service/UserShareService.java @@ -1,5 +1,6 @@ package org.esupportail.esupsignature.service; +import org.esupportail.esupsignature.config.GlobalProperties; import org.esupportail.esupsignature.entity.*; import org.esupportail.esupsignature.entity.enums.ShareType; import org.esupportail.esupsignature.exception.EsupSignatureUserException; @@ -7,6 +8,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.text.ParseException; @@ -18,6 +20,9 @@ public class UserShareService { private static final Logger logger = LoggerFactory.getLogger(UserShareService.class); + @Resource + private GlobalProperties globalProperties; + @Resource private UserService userService; @@ -36,11 +41,17 @@ public class UserShareService { @Resource private WorkflowService workflowService; + private static final String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm"; + public List getSuUsers(String authUserEppn) { List suUsers = new ArrayList<>(); - for (UserShare userShare : userShareRepository.findByToUsersEppnIn(Arrays.asList(authUserEppn))) { - if(!suUsers.contains(userShare.getUser()) && checkUserShareDate(userShare)) { - suUsers.add(userShare.getUser()); + if(globalProperties.getShareMode() > 0) { + for (UserShare userShare : userShareRepository.findByToUsersEppnIn(Arrays.asList(authUserEppn))) { + if (!suUsers.contains(userShare.getUser()) && checkUserShareDate(userShare)) { + User user = userShare.getUser(); + user.setUserShareId(userShare.getId()); + suUsers.add(user); + } } } return suUsers; @@ -50,10 +61,16 @@ public List getByWorkflowId(Long id) { return userShareRepository.findByWorkflowId(id); } - - public void createUserShare(List formsIds, List workflowsIds, String[] types, List userEmails, Date beginDate, Date endDate, User user) throws EsupSignatureUserException { + public void createUserShare(Boolean signWithOwnSign, List formsIds, List workflowsIds, String[] types, List userEmails, Date beginDate, Date endDate, User user) throws EsupSignatureUserException { UserShare userShare = new UserShare(); userShare.setUser(user); + if(globalProperties.getShareMode() > 2) { + userShare.setSignWithOwnSign(signWithOwnSign); + } else if(globalProperties.getShareMode() > 1) { + userShare.setSignWithOwnSign(false); + } else if(globalProperties.getShareMode() > 0) { + userShare.setSignWithOwnSign(true); + } List shareTypes = new ArrayList<>(); for(String type : types) { shareTypes.add(ShareType.valueOf(type)); @@ -79,13 +96,16 @@ public void createUserShare(List formsIds, List workflowsIds, String throw new EsupSignatureUserException("Une délégation pour ce circuit existe déjà, merci de la modifier"); } } + if(formsIds.size() == 0 && workflowsIds.size() == 0) { + userShare.setAllSignRequests(true); + } userShare.getToUsers().addAll(userEmails); userShare.setBeginDate(beginDate); userShare.setEndDate(endDate); userShareRepository.save(userShare); } - public void addUserShare(User authUser, Long[] form, Long[] workflow, String[] types, String[] userEmails, String beginDate, String endDate) throws EsupSignatureUserException { + public void addUserShare(User authUser, Boolean signWithOwnSign, Long[] form, Long[] workflow, String[] types, String[] userEmails, String beginDate, String endDate) throws EsupSignatureUserException { List users = new ArrayList<>(); for (String userEmail : userEmails) { users.add(userService.getUserByEmail(userEmail)); @@ -94,16 +114,26 @@ public void addUserShare(User authUser, Long[] form, Long[] workflow, String[] t Date endDateDate = null; if (beginDate != null && endDate != null) { try { - beginDateDate = new SimpleDateFormat("yyyy-MM-dd").parse(beginDate); - endDateDate = new SimpleDateFormat("yyyy-MM-dd").parse(endDate); + beginDateDate = new SimpleDateFormat(DATE_PATTERN).parse(beginDate); + endDateDate = new SimpleDateFormat(DATE_PATTERN).parse(endDate); } catch (ParseException e) { logger.error("error on parsing dates"); } } - createUserShare(Arrays.asList(form), Arrays.asList(workflow), types, users, beginDateDate, endDateDate, authUser); + createUserShare(signWithOwnSign, Arrays.asList(form), Arrays.asList(workflow), types, users, beginDateDate, endDateDate, authUser); } - public void updateUserShare(User authUser, String[] types, String[] userEmails, String beginDate, String endDate, UserShare userShare) { + @Transactional + public void updateUserShare(String authUserEppn, String[] types, String[] userEmails, String beginDate, String endDate, Long userShareId, Boolean signWithOwnSign) { + User authUser = userService.getUserByEppn(authUserEppn); + UserShare userShare = getById(userShareId); + if(globalProperties.getShareMode() > 2) { + userShare.setSignWithOwnSign(signWithOwnSign); + } else if(globalProperties.getShareMode() > 1) { + userShare.setSignWithOwnSign(false); + } else if(globalProperties.getShareMode() > 0) { + userShare.setSignWithOwnSign(true); + } if(userShare.getUser().equals(authUser)) { userShare.getToUsers().clear(); for (String userEmail : userEmails) { @@ -117,6 +147,9 @@ public void updateUserShare(User authUser, String[] types, String[] userEmails, if(userShare.getForm() != null ) { authorizedShareTypes.addAll(userShare.getForm().getAuthorizedShareTypes()); } + if(userShare.getAllSignRequests()) { + authorizedShareTypes.addAll(Arrays.asList(ShareType.values())); + } for(String type : types) { if(authorizedShareTypes.contains(ShareType.valueOf(type))) { userShare.getShareTypes().add(ShareType.valueOf(type)); @@ -124,8 +157,8 @@ public void updateUserShare(User authUser, String[] types, String[] userEmails, } if (beginDate != null && endDate != null) { try { - userShare.setBeginDate(new SimpleDateFormat("yyyy-MM-dd").parse(beginDate)); - userShare.setEndDate(new SimpleDateFormat("yyyy-MM-dd").parse(endDate)); + userShare.setBeginDate(new SimpleDateFormat(DATE_PATTERN).parse(beginDate)); + userShare.setEndDate(new SimpleDateFormat(DATE_PATTERN).parse(endDate)); } catch (ParseException e) { logger.error("error on parsing dates"); } @@ -134,22 +167,19 @@ public void updateUserShare(User authUser, String[] types, String[] userEmails, } public Boolean checkShare(String fromUserEppn, String toUserEppn, SignRequest signRequest, ShareType shareType) { + List userShares = userShareRepository.findByUserEppnAndToUsersEppnInAndAllSignRequestsIsTrueAndShareTypesContains(fromUserEppn, Arrays.asList(toUserEppn), shareType); if (signRequest.getParentSignBook().getLiveWorkflow().getWorkflow() != null) { Workflow workflow = signRequest.getParentSignBook().getLiveWorkflow().getWorkflow(); - List userShares = userShareRepository.findByUserEppnAndToUsersEppnInAndWorkflowAndShareTypesContains(fromUserEppn, Arrays.asList(toUserEppn), workflow, shareType); - for (UserShare userShare : userShares) { - if (checkUserShareDate(userShare)) { - return true; - } - } + userShares.addAll(userShareRepository.findByUserEppnAndToUsersEppnInAndWorkflowAndShareTypesContains(fromUserEppn, Arrays.asList(toUserEppn), workflow, shareType)); + } Data data = dataService.getBySignRequest(signRequest); if(data != null) { - List userShares = userShareRepository.findByUserEppnAndToUsersEppnInAndFormAndShareTypesContains(fromUserEppn, Arrays.asList(toUserEppn), data.getForm(), shareType); - for (UserShare userShare : userShares) { - if (checkUserShareDate(userShare)) { - return true; - } + userShares.addAll(userShareRepository.findByUserEppnAndToUsersEppnInAndFormAndShareTypesContains(fromUserEppn, Arrays.asList(toUserEppn), data.getForm(), shareType)); + } + for (UserShare userShare : userShares) { + if (checkUserShareDate(userShare) && checkUserShareDate(userShare, signRequest.getCreateDate())) { + return true; } } return false; @@ -203,14 +233,21 @@ public List getUserShares(String fromUserEppn, List toUsers, return userShareRepository.findByUserEppnAndToUsersEppnInAndShareTypesContains(fromUserEppn, toUsers, shareType); } - public Boolean checkUserShareDate(UserShare userShare) { - Date today = new Date(); - if((userShare.getBeginDate() == null || today.after(userShare.getBeginDate())) && (userShare.getEndDate() == null || today.before(userShare.getEndDate()))) { + public Boolean checkUserShareDate(UserShare userShare, Date checkDate) { + if((userShare.getBeginDate() == null + || checkDate.after(userShare.getBeginDate())) + && (userShare.getEndDate() == null + || checkDate.before(userShare.getEndDate()))) { return true; } return false; } + public Boolean checkUserShareDate(UserShare userShare) { + Date checkDate = new Date(); + return checkUserShareDate(userShare, checkDate); + } + public List getUserSharesByUser(String authUserEppn) { return userShareRepository.findByUserEppn(authUserEppn); } @@ -219,6 +256,14 @@ public UserShare getById(Long id) { return userShareRepository.findById(id).get(); } + public void delete(Long userShareId, String authUserEppn) { + User authUser = userService.getUserByEppn(authUserEppn); + UserShare userShare = getById(userShareId); + if (userShare.getUser().equals(authUser)) { + delete(userShare); + } + } + public void delete(UserShare userShare) { userShareRepository.delete(userShare); } diff --git a/src/main/java/org/esupportail/esupsignature/service/WorkflowService.java b/src/main/java/org/esupportail/esupsignature/service/WorkflowService.java index dd69c2eb2..d70b7feec 100644 --- a/src/main/java/org/esupportail/esupsignature/service/WorkflowService.java +++ b/src/main/java/org/esupportail/esupsignature/service/WorkflowService.java @@ -395,7 +395,7 @@ public Workflow computeWorkflow(Long workflowId, List recipientEmails, S for (WorkflowStep workflowStep : modelWorkflow.getWorkflowSteps()) { replaceStepSystemUsers(userEppn, workflowStep.getId()); if (workflowStep.getChangeable() != null && workflowStep.getChangeable()) { - List recipients = userPropertieService.getFavoriteRecipientEmail(step, workflowStep, recipientEmails, userEppn); + List recipients = this.getFavoriteRecipientEmail(step, recipientEmails); if(recipients.size() > 0 && !computeForDisplay) { workflowStep.getUsers().clear(); for (User oneUser : recipients) { @@ -412,6 +412,19 @@ public Workflow computeWorkflow(Long workflowId, List recipientEmails, S } } + @Transactional + public List getFavoriteRecipientEmail(int stepNumber, List recipientEmails) { + List users = new ArrayList<>(); + if (recipientEmails != null && recipientEmails.size() > 0) { + recipientEmails = recipientEmails.stream().filter(r -> r.startsWith(String.valueOf(stepNumber))).collect(Collectors.toList()); + for (String recipientEmail : recipientEmails) { + String userEmail = recipientEmail.split("\\*")[1]; + users.add(userService.getUserByEmail(userEmail)); + } + } + return users; + } + public void replaceStepSystemUsers(String userEppn, Long workflowStepId) { User user = userService.getByEppn(userEppn); WorkflowStep workflowStep = workflowStepService.getById(workflowStepId); @@ -428,17 +441,6 @@ public void replaceStepSystemUsers(String userEppn, Long workflowStepId) { } } - public void saveProperties(User user, Workflow modelWorkflow, Workflow computedWorkflow) { - int i = 0; - for (WorkflowStep workflowStep : modelWorkflow.getWorkflowSteps()) { - List recipients = computedWorkflow.getWorkflowSteps().get(i).getUsers(); - if(recipients.size() > 0 && workflowStep.getChangeable() != null && workflowStep.getChangeable()) { - userPropertieService.createUserPropertie(user, workflowStep, recipients); - } - i++; - } - } - public void delete(Workflow workflow) { List liveWorkflows = liveWorkflowService.getByWorkflow(workflow); List deleteLiveWorkflows = liveWorkflows.stream().filter(l -> l.getLiveWorkflowSteps().isEmpty()).collect(Collectors.toList()); @@ -517,18 +519,6 @@ public void setUpdateByAndUpdateDate(Workflow workflow, String updateBy) { workflow.setUpdateDate(new Date()); } - - public String[] getTargetEmails(String userEppn, Form form) { - List userProperties = userPropertieService.getUserProperties(userEppn, getWorkflowByName(form.getWorkflowType()).getWorkflowSteps().get(0).getId()); - userProperties = userProperties.stream().sorted(Comparator.comparing(UserPropertie::getId).reversed()).collect(Collectors.toList()); - if(userProperties.size() > 0 ) { - if(userProperties.get(0).getTargetEmail() != null) { - return userProperties.get(0).getTargetEmail().split(","); - } - } - return null; - } - public List getWorkflowStepsFromSignRequest(SignRequest signRequest, String userEppn) throws EsupSignatureException { List workflowSteps = new ArrayList<>(); if(signRequest.getParentSignBook().getLiveWorkflow().getWorkflow() != null) { diff --git a/src/main/java/org/esupportail/esupsignature/service/utils/sms/SmsService.java b/src/main/java/org/esupportail/esupsignature/service/interfaces/sms/SmsService.java similarity index 78% rename from src/main/java/org/esupportail/esupsignature/service/utils/sms/SmsService.java rename to src/main/java/org/esupportail/esupsignature/service/interfaces/sms/SmsService.java index d758990f4..cce11ae2d 100644 --- a/src/main/java/org/esupportail/esupsignature/service/utils/sms/SmsService.java +++ b/src/main/java/org/esupportail/esupsignature/service/interfaces/sms/SmsService.java @@ -1,4 +1,4 @@ -package org.esupportail.esupsignature.service.utils.sms; +package org.esupportail.esupsignature.service.interfaces.sms; import org.esupportail.esupsignature.exception.EsupSignatureException; diff --git a/src/main/java/org/esupportail/esupsignature/service/utils/sms/impl/SMSUSmsService.java b/src/main/java/org/esupportail/esupsignature/service/interfaces/sms/impl/SMSUSmsService.java similarity index 94% rename from src/main/java/org/esupportail/esupsignature/service/utils/sms/impl/SMSUSmsService.java rename to src/main/java/org/esupportail/esupsignature/service/interfaces/sms/impl/SMSUSmsService.java index 0b3f63a39..6dd2eeb09 100644 --- a/src/main/java/org/esupportail/esupsignature/service/utils/sms/impl/SMSUSmsService.java +++ b/src/main/java/org/esupportail/esupsignature/service/interfaces/sms/impl/SMSUSmsService.java @@ -1,4 +1,4 @@ -package org.esupportail.esupsignature.service.utils.sms.impl; +package org.esupportail.esupsignature.service.interfaces.sms.impl; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -11,7 +11,7 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.esupportail.esupsignature.config.sms.SmsProperties; import org.esupportail.esupsignature.exception.EsupSignatureException; -import org.esupportail.esupsignature.service.utils.sms.SmsService; +import org.esupportail.esupsignature.service.interfaces.sms.SmsService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/esupportail/esupsignature/service/ldap/LdapAliasService.java b/src/main/java/org/esupportail/esupsignature/service/ldap/LdapAliasService.java index 26521b127..56d20823b 100644 --- a/src/main/java/org/esupportail/esupsignature/service/ldap/LdapAliasService.java +++ b/src/main/java/org/esupportail/esupsignature/service/ldap/LdapAliasService.java @@ -2,17 +2,18 @@ import org.esupportail.esupsignature.repository.ldap.AliasLdapRepository; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; import java.util.List; @Service +@ConditionalOnProperty({"spring.ldap.base", "ldap.search-base"}) public class LdapAliasService { @Autowired(required = false) private AliasLdapRepository aliasLdapRepository; - public List searchAlias(String searchString) { return aliasLdapRepository.findByMailAliasStartingWithOrCnStartingWithAndMailAliasNotNull(searchString, searchString); } diff --git a/src/main/java/org/esupportail/esupsignature/service/ldap/LdapGroupService.java b/src/main/java/org/esupportail/esupsignature/service/ldap/LdapGroupService.java index f30268912..1c3c4ff71 100644 --- a/src/main/java/org/esupportail/esupsignature/service/ldap/LdapGroupService.java +++ b/src/main/java/org/esupportail/esupsignature/service/ldap/LdapGroupService.java @@ -4,6 +4,8 @@ import org.springframework.ldap.core.ContextMapper; import org.springframework.ldap.core.DirContextAdapter; import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.query.LdapQuery; +import org.springframework.ldap.query.LdapQueryBuilder; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -15,8 +17,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import static org.springframework.ldap.query.LdapQueryBuilder.query; - public class LdapGroupService implements GroupService { Map ldapFiltersGroups; @@ -74,40 +74,35 @@ public List getGroups(String eppn) { String username = eppn.replaceAll("@.*", ""); - List dns = ldapTemplate.search(query().where("uid").is(username), + List dns = ldapTemplate.search(LdapQueryBuilder.query().attributes("dn").where("uid").is(username), (ContextMapper) ctx -> { DirContextAdapter searchResultContext = (DirContextAdapter) ctx; - String dn = searchResultContext.getNameInNamespace(); - return dn; + return searchResultContext.getNameInNamespace(); }); List groups = new ArrayList<>(); if(!dns.isEmpty()) { String userDn = dns.get(0); - String formattedFilter = MessageFormat.format(groupSearchFilter, new String[] { userDn, username }); - - groups = ldapTemplate.search( - groupSearchBase, formattedFilter, (ContextMapper) ctx -> { - DirContextAdapter searchResultContext = (DirContextAdapter)ctx; + String formattedGroupSearchFilter = MessageFormat.format(groupSearchFilter, new String[] { userDn, username }); + LdapQuery groupSearchQuery = LdapQueryBuilder.query().attributes("cn").base(groupSearchBase).filter(formattedGroupSearchFilter); + groups = ldapTemplate.search(groupSearchQuery, (ContextMapper) ctx -> { + DirContextAdapter searchResultContext = (DirContextAdapter) ctx; return searchResultContext.getStringAttribute("cn"); }); } for(String ldapFilter: ldapFiltersGroups.keySet()) { - String hardcodedFilter = MessageFormat.format(memberSearchFilter, new String[] {username, ldapFilter}); - - List filterDns = ldapTemplate.search(query().filter(hardcodedFilter), + List filterDns = ldapTemplate.search(LdapQueryBuilder.query().attributes("dn").filter(hardcodedFilter), (ContextMapper) ctx -> { - DirContextAdapter searchResultContext = (DirContextAdapter)ctx; + DirContextAdapter searchResultContext = (DirContextAdapter) ctx; return searchResultContext.getNameInNamespace(); }); if(!filterDns.isEmpty()) { groups.add(ldapFiltersGroups.get(ldapFilter)); } - } return groups; } diff --git a/src/main/java/org/esupportail/esupsignature/service/ldap/LdapPersonService.java b/src/main/java/org/esupportail/esupsignature/service/ldap/LdapPersonService.java index 9769193f5..49cc437c1 100644 --- a/src/main/java/org/esupportail/esupsignature/service/ldap/LdapPersonService.java +++ b/src/main/java/org/esupportail/esupsignature/service/ldap/LdapPersonService.java @@ -28,7 +28,6 @@ public class LdapPersonService { public List search(String searchString) { return personLdapRepository.findByDisplayNameStartingWithIgnoreCaseOrCnStartingWithIgnoreCaseOrUidStartingWithOrMailStartingWith(searchString, searchString, searchString, searchString); - } public PersonLdapRepository getPersonLdapRepository() { diff --git a/src/main/java/org/esupportail/esupsignature/service/security/oauth/OAuthSecurityServiceImpl.java b/src/main/java/org/esupportail/esupsignature/service/security/oauth/OAuthSecurityServiceImpl.java index 2662c53b7..f9b3befbe 100644 --- a/src/main/java/org/esupportail/esupsignature/service/security/oauth/OAuthSecurityServiceImpl.java +++ b/src/main/java/org/esupportail/esupsignature/service/security/oauth/OAuthSecurityServiceImpl.java @@ -82,7 +82,7 @@ public ClientRegistrationRepository clientRegistrationRepository() { .clientId(clientId) .clientSecret(clientSecret) .scope("profile", "email") - .redirectUriTemplate("http://esup-signature.univ-ville.fr/login/oauth2/code/google") + .redirectUriTemplate("http://esup-signature.univ-ville.fr/login/oauth2/code/google") .build(); return new InMemoryClientRegistrationRepository(Arrays.asList(registration)); diff --git a/src/main/java/org/esupportail/esupsignature/service/security/shib/ShibAuthenticatedUserDetailsService.java b/src/main/java/org/esupportail/esupsignature/service/security/shib/ShibAuthenticatedUserDetailsService.java index 39de3a3cc..90d793137 100644 --- a/src/main/java/org/esupportail/esupsignature/service/security/shib/ShibAuthenticatedUserDetailsService.java +++ b/src/main/java/org/esupportail/esupsignature/service/security/shib/ShibAuthenticatedUserDetailsService.java @@ -30,6 +30,8 @@ import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -64,6 +66,7 @@ public void setGroup2UserRoleService(Group2UserRoleService group2UserRoleService public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) throws AuthenticationException { Set grantedAuthorities = new HashSet<>(); + Set ldapGroups = new HashSet<>(); if(!token.getCredentials().equals("")) { logger.debug("load user details from : " + token.getName()); String credentials = (String) token.getCredentials(); @@ -71,6 +74,13 @@ public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) th String[] splitCredentials = credentials.split(";"); try { for (String credential : splitCredentials) { + LdapName ln = new LdapName(credential); + for(Rdn rdn : ln.getRdns()) { + if(rdn.getType().equalsIgnoreCase("CN")) { + ldapGroups.add(rdn.getValue().toString()); + break; + } + } for(String mappingGroupesRole : mappingGroupesRoles.keySet()) { if (credential.contains(mappingGroupesRole)) { grantedAuthorities.add(new SimpleGrantedAuthority(mappingGroupesRoles.get(mappingGroupesRole))); @@ -91,8 +101,8 @@ public UserDetails loadUserDetails(PreAuthenticatedAuthenticationToken token) th logger.debug("loading authorities : " + simpleGrantedAuthority.getAuthority()); } if (ldapGroupService != null && ldapGroupService.getDomain().equals(token.getName().split("@")[1])) { - List ldapGroups = ldapGroupService.getGroups(token.getName()); - ldapGroupService.addLdapRoles(grantedAuthorities, ldapGroups, groupPrefixRoleName, mappingGroupesRoles); + ldapGroups.addAll(ldapGroupService.getGroups(token.getName())); + ldapGroupService.addLdapRoles(grantedAuthorities, new ArrayList<>(ldapGroups), groupPrefixRoleName, mappingGroupesRoles); } } catch (Exception e) { logger.warn("unable to find authorities", e); diff --git a/src/main/java/org/esupportail/esupsignature/service/utils/mail/MailService.java b/src/main/java/org/esupportail/esupsignature/service/utils/mail/MailService.java index 246c89264..1ef591d9e 100644 --- a/src/main/java/org/esupportail/esupsignature/service/utils/mail/MailService.java +++ b/src/main/java/org/esupportail/esupsignature/service/utils/mail/MailService.java @@ -130,8 +130,10 @@ public void sendSignRequestAlert(List recipientsEmails, SignRequest sign final Context ctx = new Context(Locale.FRENCH); PersonLdap personLdap = userService.findPersonLdapByUser(signRequest.getCreateBy()); - OrganizationalUnitLdap organizationalUnitLdap = userService.findOrganizationalUnitLdapByPersonLdap(personLdap); - ctx.setVariable("organizationalUnitLdap", organizationalUnitLdap); + if(personLdap != null) { + OrganizationalUnitLdap organizationalUnitLdap = userService.findOrganizationalUnitLdapByPersonLdap(personLdap); + ctx.setVariable("organizationalUnitLdap", organizationalUnitLdap); + } ctx.setVariable("signRequest", signRequest); ctx.setVariable("rootUrl", globalProperties.getRootUrl()); ctx.setVariable("userService", userService); diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/GlobalAttributsControllerAdvice.java b/src/main/java/org/esupportail/esupsignature/web/controller/GlobalAttributsControllerAdvice.java index 8765e2e64..988bbd4da 100644 --- a/src/main/java/org/esupportail/esupsignature/web/controller/GlobalAttributsControllerAdvice.java +++ b/src/main/java/org/esupportail/esupsignature/web/controller/GlobalAttributsControllerAdvice.java @@ -27,6 +27,9 @@ public class GlobalAttributsControllerAdvice { @Resource private SignRequestService signRequestService; + @Resource + private SignBookService signBookService; + @Resource private FormService formService; @@ -84,7 +87,7 @@ public void globalAttributes(@ModelAttribute("userEppn") String userEppn, @Model model.addAttribute("signTypes", signTypes); model.addAttribute("nbDatas", dataService.getNbCreateByAndStatus(userEppn)); model.addAttribute("nbSignRequests", signRequestService.getNbByCreateAndStatus(userEppn)); - model.addAttribute("nbToSign", signRequestService.nbToSignRequests(userEppn)); + model.addAttribute("nbToSign", signBookService.nbToSignSignBooks(userEppn)); } public void parseRoles(User user) { diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/user/DataController.java b/src/main/java/org/esupportail/esupsignature/web/controller/user/DataController.java index 8ea777b4f..65e58276a 100644 --- a/src/main/java/org/esupportail/esupsignature/web/controller/user/DataController.java +++ b/src/main/java/org/esupportail/esupsignature/web/controller/user/DataController.java @@ -67,6 +67,9 @@ public String getActiveMenu() { @Resource private UserService userService; + @Resource + private UserPropertieService userPropertieService; + @GetMapping public String list(@ModelAttribute("userEppn") String userEppn, @ModelAttribute("authUserEppn") String authUserEppn, @SortDefault(value = "createDate", direction = Direction.DESC) @PageableDefault(size = 10) Pageable pageable, Model model) { @@ -130,7 +133,6 @@ public String updateData(@ModelAttribute("userEppn") String userEppn, @PathVaria if(data.getStatus().equals(SignRequestStatus.draft)) { Form form = data.getForm(); model.addAttribute("fields", dataService.setFieldsDefaultsValues(data, form)); - model.addAttribute("targetEmails", workflowService.getTargetEmails(userEppn, form)); if (data.getSignBook() != null && recipientService.needSign(data.getSignBook().getLiveWorkflow().getCurrentStep().getRecipients(), userEppn)) { model.addAttribute("toSign", true); } @@ -195,6 +197,7 @@ public String sendDataById(@ModelAttribute("userEppn") String userEppn, @ModelAt User user = (User) model.getAttribute("user"); User authUser = (User) model.getAttribute("authUser"); try { + userPropertieService.createUserPropertieFromMails(userService.getByEppn(authUserEppn), recipientEmails); SignBook signBook = dataService.initSendData(id, user, recipientEmails, targetEmails, authUser); redirectAttributes.addFlashAttribute("message", new JsonMessage("success", signBook.getComment())); return "redirect:/user/signrequests/" + signBook.getSignRequests().get(0).getId(); diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/user/SignBookController.java b/src/main/java/org/esupportail/esupsignature/web/controller/user/SignBookController.java index 5c505933c..c4ae80b55 100644 --- a/src/main/java/org/esupportail/esupsignature/web/controller/user/SignBookController.java +++ b/src/main/java/org/esupportail/esupsignature/web/controller/user/SignBookController.java @@ -7,10 +7,7 @@ import org.esupportail.esupsignature.entity.enums.SignType; import org.esupportail.esupsignature.exception.EsupSignatureException; import org.esupportail.esupsignature.exception.EsupSignatureIOException; -import org.esupportail.esupsignature.service.LogService; -import org.esupportail.esupsignature.service.SignBookService; -import org.esupportail.esupsignature.service.SignRequestService; -import org.esupportail.esupsignature.service.WorkflowService; +import org.esupportail.esupsignature.service.*; import org.esupportail.esupsignature.web.ws.json.JsonMessage; import org.esupportail.esupsignature.web.ws.json.JsonWorkflowStep; import org.slf4j.Logger; @@ -24,6 +21,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.annotation.Resource; +import java.util.Arrays; @RequestMapping("/user/signbooks") @Controller @@ -44,6 +42,12 @@ public class SignBookController { @Resource private SignRequestService signRequestService; + @Resource + private UserPropertieService userPropertieService; + + @Resource + private UserService userService; + @PreAuthorize("@preAuthorizeService.signBookView(#id, #userEppn)") @GetMapping(value = "/{id}") public String show(@ModelAttribute("userEppn") String userEppn, @PathVariable("id") Long id) { @@ -94,6 +98,7 @@ public String addStep(@ModelAttribute("authUserEppn") String authUserEppn, @Path @RequestParam(name="allSignToComplete", required = false) Boolean allSignToComplete, @RequestParam("signType") String signType, RedirectAttributes redirectAttributes) { try { + userPropertieService.createUserPropertieFromMails(userService.getByEppn(authUserEppn), Arrays.asList(recipientsEmails)); signBookService.addLiveStep(id, recipientsEmails, stepNumber, allSignToComplete, signType, false); redirectAttributes.addFlashAttribute("message", new JsonMessage("success", "Étape ajoutée")); } catch (EsupSignatureException e) { diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/user/SignRequestController.java b/src/main/java/org/esupportail/esupsignature/web/controller/user/SignRequestController.java index f8ade4af4..65d43e724 100644 --- a/src/main/java/org/esupportail/esupsignature/web/controller/user/SignRequestController.java +++ b/src/main/java/org/esupportail/esupsignature/web/controller/user/SignRequestController.java @@ -43,6 +43,7 @@ import javax.mail.MessagingException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; @@ -94,6 +95,9 @@ public String getActiveMenu() { @Resource private TemplateEngine templateEngine; + @Resource + private UserPropertieService userPropertieService; + // // @Resource // private SedaExportService sedaExportService; @@ -126,7 +130,7 @@ public String listWs(@ModelAttribute(name = "userEppn") String userEppn, @ModelA @PreAuthorize("@preAuthorizeService.signRequestView(#id, #userEppn, #authUserEppn)") @GetMapping(value = "/{id}") - public String show(@ModelAttribute("userEppn") String userEppn, @ModelAttribute("authUserEppn") String authUserEppn, @PathVariable("id") Long id, @RequestParam(required = false) Boolean frameMode, Model model) throws IOException, EsupSignatureException { + public String show(@ModelAttribute("userEppn") String userEppn, @ModelAttribute("authUserEppn") String authUserEppn, @PathVariable("id") Long id, @RequestParam(required = false) Boolean frameMode, Model model, HttpSession httpSession) throws IOException, EsupSignatureException { SignRequest signRequest = signRequestService.getById(id); if (signRequest.getLastNotifDate() == null) { model.addAttribute("notifTime", 0); @@ -144,7 +148,10 @@ public String show(@ModelAttribute("userEppn") String userEppn, @ModelAttribute( model.addAttribute("uiParams", userService.getUiParams(authUserEppn)); if(!signRequest.getStatus().equals(SignRequestStatus.draft)) { try { - model.addAttribute("signImages", signRequestService.getSignImageForSignRequest(signRequest, userEppn, authUserEppn)); + Object userShareString = httpSession.getAttribute("userShareId"); + Long userShareId = null; + if(userShareString != null) userShareId = Long.valueOf(userShareString.toString()); + model.addAttribute("signImages", signRequestService.getSignImagesForSignRequest(signRequest, userEppn, authUserEppn, userShareId)); } catch (EsupSignatureUserException e) { logger.error(e.getMessage()); model.addAttribute("message", new JsonMessage("warn", e.getMessage())); @@ -195,9 +202,13 @@ public ResponseEntity sign(@ModelAttribute("userEppn") String userEppn, @RequestParam(value = "comment", required = false) String comment, @RequestParam(value = "formData", required = false) String formData, @RequestParam(value = "visual", required = false) Boolean visual, - @RequestParam(value = "password", required = false) String password) { + @RequestParam(value = "password", required = false) String password, + HttpSession httpSession) { if (visual == null) visual = true; - if(signRequestService.initSign(id, sseId, signRequestParamsJsonString, comment, formData, visual, password, userEppn, authUserEppn)) { + Object userShareString = httpSession.getAttribute("userShareId"); + Long userShareId = null; + if(userShareString != null) userShareId = Long.valueOf(userShareString.toString()); + if(signRequestService.initSign(id, sseId, signRequestParamsJsonString, comment, formData, visual, password, userShareId, userEppn, authUserEppn)) { new ResponseEntity<>(HttpStatus.OK); } return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); @@ -275,6 +286,7 @@ public String sendSignBook(@ModelAttribute("userEppn") String userEppn, @ModelAt logger.info(user.getEmail() + " envoi d'une demande de signature à " + Arrays.toString(recipientsEmails)); if (multipartFiles != null) { try { + userPropertieService.createUserPropertieFromMails(userService.getByEppn(authUserEppn), Arrays.asList(recipientsEmails)); Map signBookStringMap = signRequestService.sendSignRequest(multipartFiles, recipientsEmails, allSignToComplete, userSignFirst, pending, comment, signType, user, authUser); if (signBookStringMap.values().iterator().next() != null) { redirectAttributes.addFlashAttribute("message", new JsonMessage("warn", signBookStringMap.get(0))); @@ -435,6 +447,9 @@ public String pending(@ModelAttribute("userEppn") String userEppn, @ModelAttribu if(comment != null && !comment.isEmpty()) { signRequestService.addPostit(id, comment, userEppn, authUserEppn); } + if(recipientEmails != null) { + userPropertieService.createUserPropertieFromMails(userService.getByEppn(authUserEppn), recipientEmails); + } redirectAttributes.addFlashAttribute("message", new JsonMessage("success", "Votre demande à bien été transmise")); return "redirect:/user/signrequests/" + id; } @@ -446,6 +461,7 @@ public String addRecipients(@ModelAttribute("authUserEppn") String authUserEppn, @RequestParam(name = "signType") SignType signType, @RequestParam(name = "allSignToComplete", required = false) Boolean allSignToComplete) { signRequestService.addStep(id, recipientsEmails, signType, allSignToComplete); + userPropertieService.createUserPropertieFromMails(userService.getByEppn(authUserEppn), Arrays.asList(recipientsEmails)); return "redirect:/user/signrequests/" + id + "/?form"; } diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/user/UserController.java b/src/main/java/org/esupportail/esupsignature/web/controller/user/UserController.java index 294709643..830182957 100644 --- a/src/main/java/org/esupportail/esupsignature/web/controller/user/UserController.java +++ b/src/main/java/org/esupportail/esupsignature/web/controller/user/UserController.java @@ -3,11 +3,8 @@ import org.apache.commons.io.IOUtils; import org.esupportail.esupsignature.entity.User; import org.esupportail.esupsignature.entity.UserPropertie; -import org.esupportail.esupsignature.entity.UserShare; import org.esupportail.esupsignature.entity.enums.EmailAlertFrequency; -import org.esupportail.esupsignature.entity.enums.ShareType; import org.esupportail.esupsignature.entity.enums.SignType; -import org.esupportail.esupsignature.exception.EsupSignatureUserException; import org.esupportail.esupsignature.service.*; import org.esupportail.esupsignature.service.ldap.AliasLdap; import org.esupportail.esupsignature.service.ldap.LdapAliasService; @@ -28,7 +25,6 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URLEncoder; @@ -52,25 +48,19 @@ public String getActiveMenu() { @Resource private FormService formService; - @Resource - private WorkflowService workflowService; - @Autowired(required=false) private UserKeystoreService userKeystoreService; @Resource private UserService userService; - @Resource - private UserShareService userShareService; - @Resource private UserPropertieService userPropertieService; @Resource private MessageService messageService; - @Resource + @Autowired(required = false) private LdapAliasService ldapAliasService; @Resource @@ -137,7 +127,10 @@ public List searchLdap(@RequestParam(value="searchString") String se @ResponseBody public List searchList(@RequestParam(value="searchString") String searchString) { logger.debug("ldap search for : " + searchString); - return ldapAliasService.searchAlias(searchString); + if(ldapAliasService != null) { + return ldapAliasService.searchAlias(searchString); + } + return new ArrayList<>(); } @GetMapping(value = "/search-user-list") @@ -148,100 +141,20 @@ public List searchUserList(@RequestParam(value="searchString") String se @GetMapping("/properties") public String properties(@ModelAttribute("authUserEppn") String authUserEppn, Model model) { - List userProperties = userPropertieService.getUserPropertiesByUserEppn(authUserEppn); - model.addAttribute("userProperties", userProperties); + UserPropertie userPropertie = userPropertieService.getUserPropertiesByUserEppn(authUserEppn); + if (userPropertie != null) { + List> entrySet = new ArrayList<>(userPropertie.getFavorites().entrySet()); + entrySet.sort(Map.Entry.comparingByValue().reversed()); + Map sortedMap = new LinkedHashMap<>(); + entrySet.forEach(e -> sortedMap.put(e.getKey(), e.getValue())); + model.addAttribute("favorites", sortedMap); + } model.addAttribute("forms", formService.getFormsByUser(authUserEppn, authUserEppn)); model.addAttribute("users", userService.getAllUsers()); model.addAttribute("activeMenu", "properties"); return "user/users/properties"; } - @GetMapping("/shares") - public String params(@ModelAttribute("authUserEppn") String authUserEppn, Model model) { - List userShares = userShareService.getUserSharesByUser(authUserEppn); - model.addAttribute("userShares", userShares); - model.addAttribute("shareTypes", ShareType.values()); - model.addAttribute("forms", formService. getAuthorizedToShareForms()); - model.addAttribute("workflows", workflowService.getAuthorizedToShareWorkflows()); - model.addAttribute("users", userService.getAllUsers()); - model.addAttribute("activeMenu", "shares"); - return "user/users/shares/list"; - } - - @GetMapping("/shares/update/{id}") - public String params(@ModelAttribute("authUserEppn") String authUserEppn, @PathVariable("id") Long id, Model model, RedirectAttributes redirectAttributes) { - model.addAttribute("activeMenu", "shares"); - UserShare userShare = userShareService.getById(id); - if(userShare.getUser().getEppn().equals(authUserEppn)) { - model.addAttribute("shareTypes", ShareType.values()); - model.addAttribute("userShare", userShare); - return "user/users/shares/update"; - } else { - redirectAttributes.addFlashAttribute("message", new JsonMessage("error", "Accès refusé")); - return "redirect:/user/users/shares"; - } - } - - @PostMapping("/add-share") - public String addShare(@ModelAttribute("authUserEppn") String authUserEppn, - @RequestParam(value = "form", required = false) Long[] form, - @RequestParam(value = "workflow", required = false) Long[] workflow, - @RequestParam("types") String[] types, - @RequestParam("userIds") String[] userEmails, - @RequestParam("beginDate") String beginDate, - @RequestParam("endDate") String endDate, Model model, - RedirectAttributes redirectAttributes) { - User authUser = (User) model.getAttribute("authUser"); - if(form == null) form = new Long[] {}; - if(workflow == null) workflow = new Long[] {}; - try { - userShareService.addUserShare(authUser, form, workflow, types, userEmails, beginDate, endDate); - } catch (EsupSignatureUserException e) { - redirectAttributes.addFlashAttribute("message", new JsonMessage("error", e.getMessage())); - } - return "redirect:/user/users/shares"; - } - - @PostMapping("/update-share/{id}") - public String updateShare(@ModelAttribute("authUserEppn") String authUserEppn, - @PathVariable("id") Long id, - @RequestParam("types") String[] types, - @RequestParam("userIds") String[] userEmails, - @RequestParam("beginDate") String beginDate, - @RequestParam("endDate") String endDate, Model model) { - User authUser = (User) model.getAttribute("authUser"); - UserShare userShare = userShareService.getById(id); - userShareService.updateUserShare(authUser, types, userEmails, beginDate, endDate, userShare); - return "redirect:/user/users/shares"; - } - - @DeleteMapping("/del-share/{id}") - public String delShare(@ModelAttribute("authUserEppn") String authUserEppn, @PathVariable long id, Model model, RedirectAttributes redirectAttributes) { - User authUser = (User) model.getAttribute("authUser"); - UserShare userShare = userShareService.getById(id); - if (userShare.getUser().equals(authUser)) { - userShareService.delete(userShare); - } - redirectAttributes.addFlashAttribute("message", new JsonMessage("info", "Élément supprimé")); - return "redirect:/user/users/shares"; - } - - @GetMapping("/change-share") - public String change(@ModelAttribute("authUserEppn") String authUserEppn, @RequestParam(required = false) String eppn, RedirectAttributes redirectAttributes, HttpSession httpSession, HttpServletRequest httpServletRequest) { - if(eppn == null || eppn.isEmpty()) { - httpSession.setAttribute("suEppn", null); - redirectAttributes.addFlashAttribute("message", new JsonMessage("success", "Délégation désactivée")); - } else { - if(userShareService.checkShare(eppn, authUserEppn)) { - httpSession.setAttribute("suEppn", eppn); - redirectAttributes.addFlashAttribute("message", new JsonMessage("success", "Délégation activée : " + eppn)); - } else { - redirectAttributes.addFlashAttribute("message", new JsonMessage("error", "Aucune délégation active en ce moment")); - } - } - String referer = httpServletRequest.getHeader("Referer"); - return "redirect:"+ referer; - } @GetMapping("/mark-intro-as-read/{name}") public String markIntroAsRead(@ModelAttribute("authUserEppn") String authUserEppn, @PathVariable String name, HttpServletRequest httpServletRequest) { @@ -292,4 +205,10 @@ private List checkUserCertificate(@RequestBody List userEmails) { return userService.getUserWithoutCertificate(userEmails); } + @ResponseBody + @GetMapping("/get-favorites") + private List getFavorites(@ModelAttribute("authUserEppn") String authUserEppn) { + return userPropertieService.getFavoritesEmails(authUserEppn); + } + } diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/user/UserShareController.java b/src/main/java/org/esupportail/esupsignature/web/controller/user/UserShareController.java new file mode 100644 index 000000000..4f2f35c47 --- /dev/null +++ b/src/main/java/org/esupportail/esupsignature/web/controller/user/UserShareController.java @@ -0,0 +1,126 @@ +package org.esupportail.esupsignature.web.controller.user; + +import org.esupportail.esupsignature.entity.User; +import org.esupportail.esupsignature.entity.UserShare; +import org.esupportail.esupsignature.entity.enums.ShareType; +import org.esupportail.esupsignature.exception.EsupSignatureUserException; +import org.esupportail.esupsignature.service.FormService; +import org.esupportail.esupsignature.service.UserService; +import org.esupportail.esupsignature.service.UserShareService; +import org.esupportail.esupsignature.service.WorkflowService; +import org.esupportail.esupsignature.web.ws.json.JsonMessage; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import java.util.List; + +@CrossOrigin(origins = "*") +@RequestMapping("user/users/shares") +@Controller +@ConditionalOnExpression("${global.share-mode} > 0") +public class UserShareController { + + @Resource + private UserShareService userShareService; + + @Resource + private UserService userService; + + @Resource + private FormService formService; + + @Resource + private WorkflowService workflowService; + + @GetMapping + public String params(@ModelAttribute("authUserEppn") String authUserEppn, Model model) { + List userShares = userShareService.getUserSharesByUser(authUserEppn); + model.addAttribute("userShares", userShares); + model.addAttribute("shareTypes", ShareType.values()); + model.addAttribute("forms", formService.getAuthorizedToShareForms()); + model.addAttribute("workflows", workflowService.getAuthorizedToShareWorkflows()); + model.addAttribute("users", userService.getAllUsers()); + model.addAttribute("activeMenu", "shares"); + return "user/users/shares/list"; + } + + @GetMapping("/update/{id}") + public String params(@ModelAttribute("authUserEppn") String authUserEppn, @PathVariable("id") Long id, Model model, RedirectAttributes redirectAttributes) { + model.addAttribute("activeMenu", "shares"); + UserShare userShare = userShareService.getById(id); + if(userShare.getUser().getEppn().equals(authUserEppn)) { + model.addAttribute("shareTypes", ShareType.values()); + model.addAttribute("userShare", userShare); + return "user/users/shares/update"; + } else { + redirectAttributes.addFlashAttribute("message", new JsonMessage("error", "Accès refusé")); + return "redirect:/user/users/shares"; + } + } + + @PostMapping("/add") + public String addShare(@ModelAttribute("authUserEppn") String authUserEppn, + @RequestParam(value = "signWithOwnSign", required = false) Boolean signWithOwnSign, + @RequestParam(value = "form", required = false) Long[] form, + @RequestParam(value = "workflow", required = false) Long[] workflow, + @RequestParam("types") String[] types, + @RequestParam("userIds") String[] userEmails, + @RequestParam("beginDate") String beginDate, + @RequestParam("endDate") String endDate, Model model, + RedirectAttributes redirectAttributes) { + User authUser = (User) model.getAttribute("authUser"); + if(form == null) form = new Long[] {}; + if(workflow == null) workflow = new Long[] {}; + if(signWithOwnSign == null) signWithOwnSign = false; + try { + userShareService.addUserShare(authUser, signWithOwnSign, form, workflow, types, userEmails, beginDate, endDate); + } catch (EsupSignatureUserException e) { + redirectAttributes.addFlashAttribute("message", new JsonMessage("error", e.getMessage())); + } + return "redirect:/user/users/shares"; + } + + @PostMapping("/update/{id}") + public String updateShare(@ModelAttribute("authUserEppn") String authUserEppn, + @PathVariable("id") Long id, + @RequestParam(value = "signWithOwnSign", required = false) Boolean signWithOwnSign, + @RequestParam("types") String[] types, + @RequestParam("userIds") String[] userEmails, + @RequestParam("beginDate") String beginDate, + @RequestParam("endDate") String endDate) { + userShareService.updateUserShare(authUserEppn, types, userEmails, beginDate, endDate, id, signWithOwnSign); + return "redirect:/user/users/shares"; + } + + @DeleteMapping("/del/{id}") + public String delShare(@ModelAttribute("authUserEppn") String authUserEppn, @PathVariable long id, RedirectAttributes redirectAttributes) { + userShareService.delete(id, authUserEppn); + redirectAttributes.addFlashAttribute("message", new JsonMessage("info", "Élément supprimé")); + return "redirect:/user/users/shares"; + } + + @GetMapping("/change") + public String change(@ModelAttribute("authUserEppn") String authUserEppn, @RequestParam(required = false) String eppn, @RequestParam(required = false) Long userShareId, RedirectAttributes redirectAttributes, HttpSession httpSession, HttpServletRequest httpServletRequest) { + if(eppn == null || eppn.isEmpty()) { + httpSession.setAttribute("suEppn", null); + redirectAttributes.addFlashAttribute("message", new JsonMessage("success", "Délégation désactivée")); + } else { + if(userShareService.checkShare(eppn, authUserEppn)) { + httpSession.setAttribute("suEppn", eppn); + httpSession.setAttribute("userShareId", userShareId); + redirectAttributes.addFlashAttribute("message", new JsonMessage("success", "Délégation activée : " + eppn)); + } else { + redirectAttributes.addFlashAttribute("message", new JsonMessage("error", "Aucune délégation active en ce moment")); + } + } + return "redirect:/"; + } + + +} diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/user/WizardController.java b/src/main/java/org/esupportail/esupsignature/web/controller/user/WizardController.java index 8305d13e8..47cc6898a 100644 --- a/src/main/java/org/esupportail/esupsignature/web/controller/user/WizardController.java +++ b/src/main/java/org/esupportail/esupsignature/web/controller/user/WizardController.java @@ -5,9 +5,7 @@ import org.esupportail.esupsignature.entity.Workflow; import org.esupportail.esupsignature.entity.enums.SignType; import org.esupportail.esupsignature.exception.EsupSignatureException; -import org.esupportail.esupsignature.service.LiveWorkflowStepService; -import org.esupportail.esupsignature.service.SignBookService; -import org.esupportail.esupsignature.service.WorkflowService; +import org.esupportail.esupsignature.service.*; import org.esupportail.esupsignature.service.event.EventService; import org.esupportail.esupsignature.web.ws.json.JsonMessage; import org.esupportail.esupsignature.web.ws.json.JsonWorkflowStep; @@ -19,6 +17,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.annotation.Resource; +import java.util.Arrays; @RequestMapping("/user/wizard") @Controller @@ -39,6 +38,12 @@ public class WizardController { @Resource private EventService eventService; + @Resource + private UserPropertieService userPropertieService; + + @Resource + private UserService userService; + @GetMapping(value = "/wiz-start-by-docs", produces = "text/html") public String wiz2(@RequestParam(value = "workflowId", required = false) Long workflowId, Model model) { logger.debug("Choix des fichiers"); @@ -77,6 +82,7 @@ public String wizX(@ModelAttribute("userEppn") String userEppn, @ModelAttribute( if(step.getRecipientsEmails() != null && step.getRecipientsEmails().size() > 0) { String[] recipientsEmailsArray = new String[step.getRecipientsEmails().size()]; recipientsEmailsArray = step.getRecipientsEmails().toArray(recipientsEmailsArray); + userPropertieService.createUserPropertieFromMails(userService.getByEppn(authUserEppn), Arrays.asList(recipientsEmailsArray)); liveWorkflowStepService.addNewStepToSignBook(SignType.valueOf(step.getSignType()), step.getAllSignToComplete(), recipientsEmailsArray, id); if (addNew != null) { model.addAttribute("signTypes", SignType.values()); @@ -130,6 +136,7 @@ public String wizXWorkflow(@ModelAttribute("userEppn") String userEppn, User user = (User) model.getAttribute("user"); String[] recipientsEmailsArray = new String[step.getRecipientsEmails().size()]; recipientsEmailsArray = step.getRecipientsEmails().toArray(recipientsEmailsArray); + userPropertieService.createUserPropertieFromMails(userService.getByEppn(userEppn), Arrays.asList(recipientsEmailsArray)); Workflow workflow = workflowService.addStepToWorkflow(step.getWorkflowId(), SignType.valueOf(step.getSignType()), step.getAllSignToComplete(), recipientsEmailsArray, user); model.addAttribute("workflow", workflow); if(end != null && end) { diff --git a/src/main/java/org/esupportail/esupsignature/web/controller/user/WorkflowController.java b/src/main/java/org/esupportail/esupsignature/web/controller/user/WorkflowController.java index 871031896..e7e881ed6 100644 --- a/src/main/java/org/esupportail/esupsignature/web/controller/user/WorkflowController.java +++ b/src/main/java/org/esupportail/esupsignature/web/controller/user/WorkflowController.java @@ -3,6 +3,8 @@ import org.esupportail.esupsignature.entity.Workflow; import org.esupportail.esupsignature.entity.WorkflowStep; import org.esupportail.esupsignature.entity.enums.SignType; +import org.esupportail.esupsignature.service.UserPropertieService; +import org.esupportail.esupsignature.service.UserService; import org.esupportail.esupsignature.service.WorkflowService; import org.esupportail.esupsignature.service.WorkflowStepService; import org.esupportail.esupsignature.web.ws.json.JsonMessage; @@ -13,6 +15,7 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes; import javax.annotation.Resource; +import java.util.Arrays; @Controller @RequestMapping("/user/workflows") @@ -25,6 +28,12 @@ public class WorkflowController { @Resource private WorkflowStepService workflowStepService; + @Resource + private UserService userService; + + @Resource + private UserPropertieService userPropertieService; + @PreAuthorize("@preAuthorizeService.workflowOwner(#id, #userEppn)") @GetMapping(value = "/{id}", produces = "text/html") public String show(@ModelAttribute("userEppn") String userEppn, @PathVariable("id") Long id, Model model) { @@ -45,6 +54,7 @@ public String addStep(@ModelAttribute("userEppn") String userEppn, @PathVariable @RequestParam(name="changeable", required = false) Boolean changeable, @RequestParam(name="allSignToComplete", required = false) Boolean allSignToComplete) { Workflow workflow = workflowService.getById(id); + userPropertieService.createUserPropertieFromMails(userService.getByEppn(userEppn), Arrays.asList(recipientsEmails)); workflowStepService.addStep(id, signType, description, recipientsEmails, changeable, allSignToComplete); return "redirect:/user/workflows/" + workflow.getName(); } diff --git a/src/main/java/org/esupportail/esupsignature/web/otp/WsOtpSignController.java b/src/main/java/org/esupportail/esupsignature/web/otp/WsOtpSignController.java index 4e9490801..ce59604c4 100644 --- a/src/main/java/org/esupportail/esupsignature/web/otp/WsOtpSignController.java +++ b/src/main/java/org/esupportail/esupsignature/web/otp/WsOtpSignController.java @@ -6,7 +6,7 @@ import org.esupportail.esupsignature.service.UserService; import org.esupportail.esupsignature.service.security.otp.Otp; import org.esupportail.esupsignature.service.security.otp.OtpService; -import org.esupportail.esupsignature.service.utils.sms.SmsService; +import org.esupportail.esupsignature.service.interfaces.sms.SmsService; import org.esupportail.esupsignature.web.ws.json.JsonMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 6ace310e7..43a55bc7d 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -16,6 +16,7 @@ global: enable-splash: true application-email: esup.signature@univ-ville.fr hours-before-refresh-notif: 24 + share-mode: 3 #tomcat: # ajp: # port: 6009 diff --git a/src/main/resources/static/js/modules/ui/GlobalUi.js b/src/main/resources/static/js/modules/ui/GlobalUi.js index 9d193cccf..59e6891f1 100644 --- a/src/main/resources/static/js/modules/ui/GlobalUi.js +++ b/src/main/resources/static/js/modules/ui/GlobalUi.js @@ -136,7 +136,7 @@ export class GlobalUi { stringChain += data[i].firstname + " " + data[i].name + " "; } stringChain += "Confirmez-vous l'envoie de la demande ? " - if (data.length < 1 || window.confirm(stringChain)) { + if (data.length < 1 || bootbox.confirm(stringChain)) { $("#pending").val(true); $("#sendButton").click(); } diff --git a/src/main/resources/static/js/modules/ui/HomeUi.js b/src/main/resources/static/js/modules/ui/HomeUi.js index 9d7e9b72a..13b84d482 100644 --- a/src/main/resources/static/js/modules/ui/HomeUi.js +++ b/src/main/resources/static/js/modules/ui/HomeUi.js @@ -17,6 +17,17 @@ export class HomeUi { this.globalFilterButton.on('click', e => this.globalWorkflows(e)); this.formFilterButton.on('click', e => this.filterForms(e)); this.noFilterButton.on('click', e => this.filterNothing(e)); + $('[id^="deleteWorkflow_"]').each(function (){ + $(this).on('submit', function (e){ + e.preventDefault(); + let target = e.currentTarget; + bootbox.confirm("Voulez-vous vraiment supprimer ce circuit ?", function (result) { + if(result) { + target.submit(); + } + }); + }); + }); } toggleNewMenu() { diff --git a/src/main/resources/static/js/modules/ui/WizUi.js b/src/main/resources/static/js/modules/ui/WizUi.js index 3399d982f..84966eb8f 100644 --- a/src/main/resources/static/js/modules/ui/WizUi.js +++ b/src/main/resources/static/js/modules/ui/WizUi.js @@ -24,7 +24,7 @@ export class WizUi { checkOnModalClose() { let workflowId = $("#wizWorkflowId").val(); if(this.signBookId || workflowId) { - if (confirm("Attention si vous fermez cette fenêtre, les modifications seront perdues")) { + if (bootbox.confirm("Attention si vous fermez cette fenêtre, les modifications seront perdues")) { if(workflowId) { $.ajax({ method: "DELETE", diff --git a/src/main/resources/static/js/modules/ui/datas/CreateDataUi.js b/src/main/resources/static/js/modules/ui/datas/CreateDataUi.js index f2858ece3..4cdec8f60 100644 --- a/src/main/resources/static/js/modules/ui/datas/CreateDataUi.js +++ b/src/main/resources/static/js/modules/ui/datas/CreateDataUi.js @@ -177,7 +177,7 @@ export class CreateDataUi { let savedField = pdfViewer.savedFields.get(dataField.name) formData[dataField.name]= savedField; if(dataField.required && (savedField === "" || savedField == null)) { - alert("Un champ n'est pas rempli en page " + dataField.page); + bootbox.alert("Un champ n'est pas rempli en page " + dataField.page); openModal = false; pdfViewer.renderPage(dataField.page); } diff --git a/src/main/resources/static/js/modules/ui/signrequests/ListSignRequestUi.js b/src/main/resources/static/js/modules/ui/signrequests/ListSignRequestUi.js index 8e6414a61..53763123b 100644 --- a/src/main/resources/static/js/modules/ui/signrequests/ListSignRequestUi.js +++ b/src/main/resources/static/js/modules/ui/signrequests/ListSignRequestUi.js @@ -45,19 +45,21 @@ export default class ListSignRequestUi { }); if(ids.length > 0) { - if(confirm("Voulez-vous supprimer définitivement les demandes sélectionnées ?")) { - let csrf = this.csrf; - $.ajax({ - url: "/user/signrequests/delete-multiple?" + csrf.parameterName + "=" + csrf.token, - type: 'POST', - dataType : 'json', - contentType: "application/json", - data: JSON.stringify(ids), - success: function(){ - location.reload(); - } - }); - } + let csrf = this.csrf; + bootbox.confirm("Voulez-vous supprimer définitivement les demandes sélectionnées ?", function(result) { + if(result) { + $.ajax({ + url: "/user/signrequests/delete-multiple?" + csrf.parameterName + "=" + csrf.token, + type: 'POST', + dataType: 'json', + contentType: "application/json", + data: JSON.stringify(ids), + success: function () { + location.reload(); + } + }); + } + }); } } diff --git a/src/main/resources/static/js/modules/ui/signrequests/SignPosition.js b/src/main/resources/static/js/modules/ui/signrequests/SignPosition.js index 8d07a4838..d14004402 100644 --- a/src/main/resources/static/js/modules/ui/signrequests/SignPosition.js +++ b/src/main/resources/static/js/modules/ui/signrequests/SignPosition.js @@ -17,9 +17,14 @@ export class SignPosition extends EventFactory { let signRequestParams = new SignRequestParams(); this.signImages = signImages; if(this.signImages != null && this.signImages.length > 0) { - signRequestParams.xPos = parseInt(xPos, 10) * this.currentScale; - signRequestParams.yPos = parseInt(yPos, 10) * this.currentScale; - signRequestParams.signPageNumber = signPageNumber; + if(xPos === 0 && yPos === 0) { + signRequestParams.xPos = -1; + signRequestParams.yPos = -1; + } else { + signRequestParams.xPos = parseInt(xPos, 10) * this.currentScale; + signRequestParams.yPos = parseInt(yPos, 10) * this.currentScale; + signRequestParams.signPageNumber = signPageNumber; + } } this.signRequestParamses = new Map(); this.signRequestParamses.set("0", signRequestParams); @@ -140,8 +145,8 @@ export class SignPosition extends EventFactory { this.hideButtons(); console.info("add sign"); let signRequestParams = new SignRequestParams(); - signRequestParams.xPos = 0; - signRequestParams.yPos = 0; + signRequestParams.xPos -1; + signRequestParams.yPos = -1; signRequestParams.signPageNumber = this.getCurrentSignParams().signPageNumber; signRequestParams.addExtra = this.getCurrentSignParams().addExtra; signRequestParams.extraWidth = this.getCurrentSignParams().extraWidth; @@ -348,8 +353,8 @@ export class SignPosition extends EventFactory { updateCrossPosition() { console.debug("update cross pos to : " + this.getUiXpos() + " " + this.getUiYpos()); console.debug("update sign pos to : " + this.getCurrentSignParams().xPos + " " + this.getCurrentSignParams().yPos); - if(this.posX < 0) this.posX = 0; - if(this.posY < 0) this.posY = 0; + if(this.posX < 0) this.posX = -1; + if(this.posY < 0) this.posY = -1; // this.cross.css('backgroundColor', 'rgba(0, 255, 0, .5)'); this.cross.css('left', this.getUiXpos() + "px"); this.cross.css('top', this.getUiYpos() + "px"); @@ -470,8 +475,8 @@ export class SignPosition extends EventFactory { enableConfirmLeaveSign() { - window.onbeforeunload = function(){ - return confirm("Une signature est en cours sur ce document, voulez abandonner les modifications ?"); + window.beforeunload = function(e) { + return true; }; } diff --git a/src/main/resources/static/js/modules/ui/signrequests/WorkspacePdf.js b/src/main/resources/static/js/modules/ui/signrequests/WorkspacePdf.js index 8bd6a1243..51a078983 100644 --- a/src/main/resources/static/js/modules/ui/signrequests/WorkspacePdf.js +++ b/src/main/resources/static/js/modules/ui/signrequests/WorkspacePdf.js @@ -13,6 +13,7 @@ export class WorkspacePdf { this.postits = postits; this.signable = signable; this.signRequestId = id; + this.signType = signType; this.signPosition = new SignPosition( signType, this.currentSignRequestParams[0].xPos, @@ -74,6 +75,30 @@ export class WorkspacePdf { postitButton.on('click', e => this.focusComment(postit)); }); } + $('[id^="deleteAttachement_"]').each(function (){ + $(this).on('click', function (e){ + e.preventDefault(); + let target = e.currentTarget; + bootbox.confirm("Confimez la suppression de la pièce jointe ?", function (result) { + if(result) { + location.href = $(target).attr('href'); + } + }); + }); + }); + + $('[id^="deleteLink_"]').each(function (){ + $(this).on('click', function (e){ + e.preventDefault(); + let target = e.currentTarget; + bootbox.confirm("Confirmez la suppression du lien ?", function (result) { + if(result) { + location.href = $(target).attr('href'); + } + }); + }); + }); + $("#visaLaunchButton").on('click', e => this.launchSignModal()); $("#signLaunchButton").on('click', e => this.launchSignModal()); $("#refuseLaunchButton").on('click', function (){ @@ -96,8 +121,12 @@ export class WorkspacePdf { launchSignModal() { console.info("launch sign modal"); window.onbeforeunload = null; - if(WorkspacePdf.validateForm()) { - $("#signModal").modal('toggle'); + if(this.signPosition.getCurrentSignParams().xPos === -1 && this.signType !== "visa") { + bootbox.alert("Merci de placer la signature"); + } else { + if (WorkspacePdf.validateForm()) { + $("#signModal").modal('toggle'); + } } } @@ -292,9 +321,6 @@ export class WorkspacePdf { localStorage.setItem('mode', 'read'); this.signPosition.pointItEnable = false; this.pdfViewer.scale = 0.5; - if(this.isFloat(localStorage.getItem('scale'))) { - this.pdfViewer.scale = localStorage.getItem('scale'); - } $('#readModeButton').toggleClass('btn-outline-secondary'); $('#rotateleft').prop('disabled', false); $('#rotateright').prop('disabled', false); diff --git a/src/main/resources/static/js/modules/ui/users/ShareUi.js b/src/main/resources/static/js/modules/ui/users/ShareUi.js index fe984c253..27fc4c86b 100644 --- a/src/main/resources/static/js/modules/ui/users/ShareUi.js +++ b/src/main/resources/static/js/modules/ui/users/ShareUi.js @@ -9,6 +9,13 @@ export default class ShareUi { $('#selectTarget').on('change', e => this.toggleShareForm()); $('#selectWorkflow').on('change', e => this.updateTypeCheckboxes(e)); $('#selectForm').on('change', e => this.updateTypeCheckboxes(e)); + let checkSign = $("#check-sign"); + if(checkSign) { + this.listenToCheckSign(); + if(checkSign.prop("checked") === true) { + $('#sign-mod').removeClass("d-none"); + } + } } toggleShareForm() { @@ -17,9 +24,17 @@ export default class ShareUi { if(selectedTargetValue === 'form') { $('#selectFormDiv').removeClass('d-none'); $('#selectWorkflowDiv').addClass('d-none'); - } else { + } else if(selectedTargetValue === 'workflow') { $('#selectFormDiv').addClass('d-none'); $('#selectWorkflowDiv').removeClass('d-none'); + } else { + let self = this; + $("input[id^='check-']").each(function() { + $(this).removeAttr("disabled"); + if($(this).attr("id").split("-")[1] === "sign") { + self.listenToCheckSign(); + } + }); } } @@ -31,13 +46,27 @@ export default class ShareUi { let authorizedSignTypesData = optionSelected.attr("data"); if(authorizedSignTypesData) { let authorizedSignTypes = authorizedSignTypesData.replace("[", "").replace("]", "").split(","); + let self = this; $.each(authorizedSignTypes, function (id, value) { - $("#check-" + value.trim()).removeAttr("disabled"); + let checkBox = $("#check-" + value.trim()); + checkBox.removeAttr("disabled"); + if(value.trim() === "sign") { + self.listenToCheckSign(); + } console.log(value); }); } } + listenToCheckSign() { + $("#check-sign").on('click', function () { + if ($(this).prop("checked") === true) { + $('#sign-mod').removeClass("d-none"); + } else { + $('#sign-mod').addClass("d-none"); + } + }); + } } \ No newline at end of file diff --git a/src/main/resources/static/js/modules/ui/users/UserUi.js b/src/main/resources/static/js/modules/ui/users/UserUi.js index 556a68cd2..af5fb4b47 100644 --- a/src/main/resources/static/js/modules/ui/users/UserUi.js +++ b/src/main/resources/static/js/modules/ui/users/UserUi.js @@ -17,6 +17,18 @@ export default class UserUi { initListeners() { this.userSignatureCrop.addEventListener("started", e => this.userSignaturePad.clear()); this.emailAlertFrequencySelect.addEventListener("change", e => this.checkAlertFrequency()); + $('[id^="deleteSign_"]').each(function() { + $(this).on('click', function (e){ + e.preventDefault(); + let target = e.currentTarget; + bootbox.confirm("Voulez-vous vraiment supprimer cette signature ?", function(result){ + if(result) { + location.href = $(target).attr('href'); + } + }) + }); + }); + } checkAlertFrequency() { diff --git a/src/main/resources/static/js/modules/utils/PdfViewer.js b/src/main/resources/static/js/modules/utils/PdfViewer.js index f9fd0b34a..71371cf43 100644 --- a/src/main/resources/static/js/modules/utils/PdfViewer.js +++ b/src/main/resources/static/js/modules/utils/PdfViewer.js @@ -11,6 +11,9 @@ export class PdfViewer extends EventFactory { this.pdfPageView = null; this.currentStepNumber = currentStepNumber; this.scale = 1; + if(localStorage.getItem('scale')) { + this.scale = parseFloat(localStorage.getItem('scale')); + } this.zoomStep = 0.10; this.canvas = document.getElementById('pdf'); this.pdfDoc = null; @@ -103,8 +106,8 @@ export class PdfViewer extends EventFactory { adjustZoom() { console.info("adjust zoom to screen wide " + window.innerWidth); let newScale = 1; - if(this.isFloat(localStorage.getItem('scale'))) { - newScale = localStorage.getItem('scale'); + if(localStorage.getItem('scale')) { + newScale = parseFloat(localStorage.getItem('scale')); } if (window.innerWidth < 1200) { newScale = 0.9; @@ -157,10 +160,10 @@ export class PdfViewer extends EventFactory { } renderTask(page) { - console.info("launch render task"); + console.info("launch render task" + this.scale); this.page = page; let scale = this.scale; - localStorage.setItem('scale', this.scale); + localStorage.setItem('scale', scale); let rotation = this.rotation; let viewport = page.getViewport({scale, rotation}); if(this.pdfPageView == null) { @@ -293,7 +296,6 @@ export class PdfViewer extends EventFactory { $('#' + items[i].fieldName.split(/\\$|#|!/)[0] + ' option').each(function() { if(this.savedFields.get(items[i].fieldName) === $(this).value) { - alert("test"); $(this).prop("selected", true); } }); diff --git a/src/main/resources/static/js/modules/utils/SelectUser.js b/src/main/resources/static/js/modules/utils/SelectUser.js index 5fcc862b9..2bd90b263 100644 --- a/src/main/resources/static/js/modules/utils/SelectUser.js +++ b/src/main/resources/static/js/modules/utils/SelectUser.js @@ -8,6 +8,7 @@ export default class SelectUser { this.valuePrefix = ""; this.limit = 99; this.flag = false; + this.favorites = null; let selectNameSplit = selectName.split("_"); if(selectNameSplit.length === 2) { this.valuePrefix = selectNameSplit[1] + "*"; @@ -17,6 +18,7 @@ export default class SelectUser { } this.createUserSelect(selectName, this.valuePrefix); this.selectField.addClass("slim-select-hack"); + this.populateWithFavorites(); this.initListeners(); } @@ -49,21 +51,28 @@ export default class SelectUser { } addListMembers(data, selectValue) { - this.flag = false; - let array = []; - let array2 = []; - for (let i = 0; i < this.slimSelect.data.data.length ; i++) { - if (this.slimSelect.data.data[i].text !== selectValue && this.slimSelect.data.data[i].value !== "undefined") { - array.push({text: this.slimSelect.data.data[i].text, value: this.slimSelect.data.data[i].value, display: true}); - array2.push(this.slimSelect.data.data[i].value); + if(data.length > 0) { + this.flag = false; + let array = []; + let array2 = []; + for (let i = 0; i < this.slimSelect.data.data.length; i++) { + let prevData = this.slimSelect.data.data[i]; + if (prevData.text !== selectValue && prevData.value !== "undefined" && prevData.value !== "") { + array.push({ + text: this.slimSelect.data.data[i].text, + value: this.slimSelect.data.data[i].value, + display: true + }); + array2.push(this.slimSelect.data.data[i].value); + } } + for (let i = 0; i < data.length; i++) { + array.push({text: data[i], value: this.valuePrefix + data[i], display: true}) + array2.push(data[i]); + } + this.slimSelect.setData(array); + this.slimSelect.set(array2); } - for(let i = 0; i < data.length; i++) { - array.push({text: data[i], value: this.valuePrefix + data[i], display: true}) - array2.push(data[i]); - } - this.slimSelect.setData(array); - this.slimSelect.set(array2); } displayTempUsersSuccess(data) { @@ -98,11 +107,35 @@ export default class SelectUser { return false; } + setFavorites(response) { + let typeValues = []; + for(let j = 0; j < response.length; j++) { + let value = response[j]; + typeValues[j] = {text : value}; + } + this.favorites = typeValues; + console.log(this.favorites); + this.slimSelect.setData(this.favorites); + this.slimSelect.set(); + } + + populateWithFavorites() { + $.ajax({ + url: "/user/users/get-favorites", + type: 'GET', + dataType: 'json', + contentType: "application/json", + success: response => this.setFavorites(response) + }); + } + createUserSelect(selectName, valuePrefix) { - var controller = new AbortController() - var signal = controller.signal + let controller = new AbortController(); + let signal = controller.signal; + console.log(this.favorites); this.slimSelect = new SlimSelect({ select: "#" + selectName, + data: this.favorites, placeholder: 'Choisir un ou plusieurs participants', searchText: 'Aucun résultat', searchPlaceholder: 'Rechercher', @@ -154,7 +187,9 @@ export default class SelectUser { for (let i = 0; i < json.length; i++) { data.push({text: json[i].mailAlias, value: valuePrefix + json[i].mailAlias}); } - callback(data); + if(data.length > 0) { + callback(data); + } }) } }) diff --git a/src/main/resources/static/js/prototypes/SignRequestParams.js b/src/main/resources/static/js/prototypes/SignRequestParams.js index 9d4c105ce..d6f5d830a 100644 --- a/src/main/resources/static/js/prototypes/SignRequestParams.js +++ b/src/main/resources/static/js/prototypes/SignRequestParams.js @@ -6,8 +6,8 @@ export class SignRequestParams { this.signPageNumber; this.signWidth; this.signHeight; - this.xPos; - this.yPos; + this.xPos = -1; + this.yPos = -1; this.addExtra = true; this.extraOnTop = true; this.extraWidth = 0; diff --git a/src/main/resources/templates/admin/workflows/cards/stepscard.html b/src/main/resources/templates/admin/workflows/cards/stepscard.html index df60adfb0..2f9400083 100644 --- a/src/main/resources/templates/admin/workflows/cards/stepscard.html +++ b/src/main/resources/templates/admin/workflows/cards/stepscard.html @@ -67,7 +67,7 @@
Étape : @@ -95,7 +95,7 @@
Étape : diff --git a/src/main/resources/templates/fragments/head.html b/src/main/resources/templates/fragments/head.html index 7a9c6f471..b67517f4a 100644 --- a/src/main/resources/templates/fragments/head.html +++ b/src/main/resources/templates/fragments/head.html @@ -8,6 +8,9 @@ + + + diff --git a/src/main/resources/templates/fragments/nav.html b/src/main/resources/templates/fragments/nav.html index f38d62cfc..d2a341d8f 100644 --- a/src/main/resources/templates/fragments/nav.html +++ b/src/main/resources/templates/fragments/nav.html @@ -56,7 +56,7 @@ class="nav-item-label d-none d-xl-inline">Tableau de bord - - - - @@ -165,7 +164,7 @@

Délégations
-
+ - - - @@ -15,7 +16,8 @@ @@ -28,61 +30,72 @@
- -
-
+ +
+
-
-
+
+
-
- - -
+
+ + +
- - - - - - - - - - + + + + + + + + + + -
- - -
- - -
-
-
+
+ + +
+ + +
+
+
-
- - + + + + +
+ +
+ + -
-
- - -
-
- - -
+ +
+
+ + +
+
+ + +
diff --git a/src/main/resources/templates/user/workflows/show.html b/src/main/resources/templates/user/workflows/show.html index 5a5229e00..d41051bc7 100644 --- a/src/main/resources/templates/user/workflows/show.html +++ b/src/main/resources/templates/user/workflows/show.html @@ -35,7 +35,7 @@
  • -
    + diff --git a/src/main/resources/update_1.4_clean.sql b/src/main/resources/update_1.4_clean.sql index add7d03b4..7ece82368 100644 --- a/src/main/resources/update_1.4_clean.sql +++ b/src/main/resources/update_1.4_clean.sql @@ -1,3 +1,3 @@ -drop table live_workflow_workflow_steps; + drop table live_workflow_workflow_steps; drop table sign_request_recipients; drop table sign_book_workflow_steps; \ No newline at end of file