From 30ca30742146ff93e55a97af5cbc0fb0a1a8b1b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Antonio=20Ram=C3=ADrez=20Galv=C3=A1n?= Date: Tue, 16 Jul 2024 13:02:21 -0600 Subject: [PATCH] =?UTF-8?q?se=20agrego=20la=20funcionalidad=20de=20que=20s?= =?UTF-8?q?i=20un=20usuario=20no=20existe=20en=20proyman=20en=20automatico?= =?UTF-8?q?=20cuando=20proporciones=20su=20usuario=20y=20contrase=C3=B1a?= =?UTF-8?q?=20este=20se=20creara=20en=20proyman(Redmine)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 +- .../gob/jumapacelaya/api/RedmineClient.java | 39 +++++++++ .../gob/jumapacelaya/api/SecurityConfig.java | 27 ++++++ .../gob/jumapacelaya/api/SecurityService.java | 1 + .../models/CustomUserDetails.java | 85 +++++++++++++++++++ .../models/RedmineUser_Model.java | 2 - .../java/mx/gob/jumapacelaya/models/User.java | 0 .../gob/jumapacelaya/models/UserElement.java | 0 .../jumapacelaya/services/LdapService.java | 46 ++++++++++ .../jumapacelaya/services/UserService.java | 44 ++++++++-- .../CrearnuevoTicketView.java | 2 +- src/main/resources/application.properties | 12 ++- 12 files changed, 249 insertions(+), 18 deletions(-) create mode 100644 src/main/java/mx/gob/jumapacelaya/models/CustomUserDetails.java delete mode 100644 src/main/java/mx/gob/jumapacelaya/models/RedmineUser_Model.java delete mode 100644 src/main/java/mx/gob/jumapacelaya/models/User.java delete mode 100644 src/main/java/mx/gob/jumapacelaya/models/UserElement.java create mode 100644 src/main/java/mx/gob/jumapacelaya/services/LdapService.java diff --git a/pom.xml b/pom.xml index 59b0699..18d76a9 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,6 @@ line-awesome 2.0.0 - org.springframework.boot spring-boot-starter-validation @@ -94,6 +93,14 @@ ch.qos.logback logback-classic + + org.springframework.boot + spring-boot-starter-data-ldap + + + org.springframework.ldap + spring-ldap-core + diff --git a/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java b/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java index 6b9ed63..d6e7821 100644 --- a/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java +++ b/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java @@ -346,4 +346,43 @@ public class RedmineClient { } + public static RedmineUser createRedmineUser(String username, String firstname, String lastname, String mail) { + HttpClient client = HttpClient.newHttpClient(); + Map user = new HashMap<>(); + user.put("login", username); + user.put("firstname", firstname); + user.put("lastname", lastname); + user.put("mail", mail); + user.put("auth_source_id", "1"); + + Map payload = new HashMap<>(); + payload.put("user", user); + String jsonPayload = new Gson().toJson(payload); + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(REDMINE_URL + "/users.json")) + .header("Content-Type", "application/json") + .header("X-Redmine-API-Key", API_KEY) + .POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) + .build(); + + try { + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject(); + JsonObject userJson = jsonObject.get("user").getAsJsonObject(); + + RedmineUser newUser = new RedmineUser(); + newUser.setId(userJson.get("id").getAsInt()); + newUser.setLogin(userJson.get("login").getAsString()); + newUser.setFirstname(userJson.get("firstname").getAsString()); + newUser.setLastname(userJson.get("lastname").getAsString()); + newUser.setMail(userJson.get("mail").getAsString()); + + return newUser; + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } } diff --git a/src/main/java/mx/gob/jumapacelaya/api/SecurityConfig.java b/src/main/java/mx/gob/jumapacelaya/api/SecurityConfig.java index abb9180..1dae8dc 100644 --- a/src/main/java/mx/gob/jumapacelaya/api/SecurityConfig.java +++ b/src/main/java/mx/gob/jumapacelaya/api/SecurityConfig.java @@ -4,8 +4,11 @@ import com.vaadin.flow.spring.security.VaadinWebSecurity; import mx.gob.jumapacelaya.services.UserService; import mx.gob.jumapacelaya.views.login.LoginView; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; +import org.springframework.ldap.core.support.LdapContextSource; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -56,6 +59,30 @@ public class SecurityConfig extends VaadinWebSecurity { public void setUserService(UserService userService) { this.userService = userService; }*/ + + @Value("${spring.ldap.urls}") + private String ldapUrls; + + @Value("${spring.ldap.base}") + private String ldapBase; + + @Value("${spring.ldap.password}") + private String ldapPassword; + + + @Bean + public LdapContextSource ldapContextSource() { + LdapContextSource contextSource = new LdapContextSource(); + contextSource.setUrl(ldapUrls); + contextSource.setBase(ldapBase); + contextSource.setUserDn("administrator"); + contextSource.setPassword(ldapPassword); + contextSource.setPooled(true); + contextSource.setReferral("follow"); + return contextSource; + } + + } diff --git a/src/main/java/mx/gob/jumapacelaya/api/SecurityService.java b/src/main/java/mx/gob/jumapacelaya/api/SecurityService.java index fae395b..1afc286 100644 --- a/src/main/java/mx/gob/jumapacelaya/api/SecurityService.java +++ b/src/main/java/mx/gob/jumapacelaya/api/SecurityService.java @@ -26,4 +26,5 @@ public class SecurityService { public void logout() { authenticationContext.logout(); } + } diff --git a/src/main/java/mx/gob/jumapacelaya/models/CustomUserDetails.java b/src/main/java/mx/gob/jumapacelaya/models/CustomUserDetails.java new file mode 100644 index 0000000..7fd79d7 --- /dev/null +++ b/src/main/java/mx/gob/jumapacelaya/models/CustomUserDetails.java @@ -0,0 +1,85 @@ +package mx.gob.jumapacelaya.models; + +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.Collection; + +public class CustomUserDetails implements UserDetails { + + private String username; + private String firstName; + private String lastName; + private String email; + private Collection authorities; + private String password; + + public CustomUserDetails(String username, String firstName, String lastName, String email, Collection authorities, String password) { + this.username = username; + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + this.authorities = authorities; + this.password = password; + } + + // Getters and setters + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public Collection getAuthorities() { + return authorities; + } + + @Override + public String getPassword() { + return password; + } + + @Override + public String getUsername() { + return username; + } + + @Override + public boolean isAccountNonExpired() { + return true; + } + + @Override + public boolean isAccountNonLocked() { + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + return true; + } + + @Override + public boolean isEnabled() { + return true; + } +} diff --git a/src/main/java/mx/gob/jumapacelaya/models/RedmineUser_Model.java b/src/main/java/mx/gob/jumapacelaya/models/RedmineUser_Model.java deleted file mode 100644 index ccbc9fa..0000000 --- a/src/main/java/mx/gob/jumapacelaya/models/RedmineUser_Model.java +++ /dev/null @@ -1,2 +0,0 @@ -package mx.gob.jumapacelaya.models;public class RedmineUser_Model { -} diff --git a/src/main/java/mx/gob/jumapacelaya/models/User.java b/src/main/java/mx/gob/jumapacelaya/models/User.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/mx/gob/jumapacelaya/models/UserElement.java b/src/main/java/mx/gob/jumapacelaya/models/UserElement.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/mx/gob/jumapacelaya/services/LdapService.java b/src/main/java/mx/gob/jumapacelaya/services/LdapService.java new file mode 100644 index 0000000..acccaff --- /dev/null +++ b/src/main/java/mx/gob/jumapacelaya/services/LdapService.java @@ -0,0 +1,46 @@ +package mx.gob.jumapacelaya.services; + +import mx.gob.jumapacelaya.models.CustomUserDetails; +import org.springframework.ldap.core.LdapTemplate; +import org.springframework.ldap.filter.EqualsFilter; +import org.springframework.stereotype.Service; + +import javax.naming.NamingException; +import javax.naming.directory.Attributes; +import javax.naming.directory.SearchControls; +import java.util.List; + +@Service +public class LdapService { + + private final LdapTemplate ldapTemplate; + + public LdapService(LdapTemplate ldapTemplate) { + this.ldapTemplate = ldapTemplate; + } + + public CustomUserDetails getUserDetails(String username) { + EqualsFilter filter = new EqualsFilter("sAMAccountName", username); + SearchControls searchControls = new SearchControls(); + searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE); + searchControls.setReturningAttributes(new String[]{"givenName", "sn", "mail"}); + searchControls.setReturningObjFlag(true); + + List result = ldapTemplate.search("", filter.encode(), searchControls, (Attributes attrs) -> { + String firstName = getAttribute(attrs, "givenName"); + String lastName = getAttribute(attrs, "sn"); + String email = getAttribute(attrs, "mail"); + return new CustomUserDetails(username, firstName, lastName, email, null, null); // Ajustar los últimos dos parámetros si es necesario + }); + return result.isEmpty() ? null : result.get(0); + } + + private String getAttribute(Attributes attributes, String attributeName) { + try { + return attributes.get(attributeName).get().toString(); + } catch (NamingException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/mx/gob/jumapacelaya/services/UserService.java b/src/main/java/mx/gob/jumapacelaya/services/UserService.java index 8a6af6c..236b649 100644 --- a/src/main/java/mx/gob/jumapacelaya/services/UserService.java +++ b/src/main/java/mx/gob/jumapacelaya/services/UserService.java @@ -3,6 +3,7 @@ package mx.gob.jumapacelaya.services; import com.vaadin.flow.server.VaadinService; import mx.gob.jumapacelaya.api.RedmineClient; import mx.gob.jumapacelaya.api.SecurityService; +import mx.gob.jumapacelaya.models.CustomUserDetails; import mx.gob.jumapacelaya.models.RedmineUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,11 +15,13 @@ public class UserService { private final SecurityService securityService; private final RedmineClient redmineClient; private static final Logger logger = LoggerFactory.getLogger(UserService.class); + private final LdapService ldapService; - public UserService(SecurityService securityService, RedmineClient redmineClient) { + public UserService(SecurityService securityService, RedmineClient redmineClient, LdapService ldapService) { this.securityService = securityService; this.redmineClient = redmineClient; + this.ldapService = ldapService; } /** @@ -28,11 +31,31 @@ public class UserService { */ public RedmineUser getAuthenticatedRedmineUser() { try { - String usename = securityService.getAuthenticatedUser(); - logger.info("Usuario autenticado: " + usename); - if (usename != null) { - RedmineUser user = redmineClient.getUserByUsername(usename); - logger.info("Usuario autenticado en Redmine: " + user); + String username = securityService.getAuthenticatedUser(); + logger.info("Usuario autenticado: " + username); + if (username != null) { + RedmineUser user = redmineClient.getUserByUsername(username); + if (user == null) { + CustomUserDetails userDetails = ldapService.getUserDetails(username); + if (userDetails != null) { + RedmineUser newUser = RedmineClient.createRedmineUser( + username, + userDetails.getFirstName(), + userDetails.getLastName(), + userDetails.getEmail() + ); + if (newUser != null) { + logger.info("Usuario creado en Redmine: " + newUser); + return newUser; + } else { + logger.error("Error al crear el usuario en Redmine"); + } + } else { + logger.error("No se encontraron detalles del usuario en LDAP"); + } + } else { + logger.info("Usuario autenticado en Redmine: " + user); + } return user; } } catch (Exception e) { @@ -41,6 +64,7 @@ public class UserService { return null; } + public RedmineUser getRedmineUser() { RedmineUser userclient = (RedmineUser) VaadinService.getCurrentRequest().getWrappedSession().getAttribute("myaccount"); @@ -52,10 +76,16 @@ public class UserService { if (myAccount != null && !myAccount.getKey().isEmpty()) { userclient = myAccount; VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount); + } else { + // Crear un nuevo usuario si no existe + myAccount = redmineClient.createRedmineUser(user.getLogin(), user.getFirstname(), user.getLastname(), user.getMail()); + if (myAccount != null && !myAccount.getKey().isEmpty()) { + userclient = myAccount; + VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount); + } } } } - return userclient; } } diff --git a/src/main/java/mx/gob/jumapacelaya/views/crearnuevoticket/CrearnuevoTicketView.java b/src/main/java/mx/gob/jumapacelaya/views/crearnuevoticket/CrearnuevoTicketView.java index 69bca90..820f575 100644 --- a/src/main/java/mx/gob/jumapacelaya/views/crearnuevoticket/CrearnuevoTicketView.java +++ b/src/main/java/mx/gob/jumapacelaya/views/crearnuevoticket/CrearnuevoTicketView.java @@ -118,7 +118,7 @@ public class CrearnuevoTicketView extends VerticalLayout { resetForm(asunto, descripcion, tipoTickets); } else { - Notification.show("Ha ocurrido un error al enviar el ticket: " + response, 5000, Notification.Position.MIDDLE) + Notification.show(response, 5000, Notification.Position.MIDDLE) .addThemeVariants(NotificationVariant.LUMO_ERROR); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2eadab9..87b2af9 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,12 +10,10 @@ vaadin.allowed-packages = com.vaadin,org.vaadin,dev.hilla,com.example.applicatio spring.jpa.defer-datasource-initialization = true # Configuracion de LDAP -spring: -ldap: -urls: ldap://172.16.0.1:389 -base: DC=JUMAPACELAYA, DC=GOB, DC=MX -username: administrator -password: Dr3na%134$4guA +spring.ldap.urls=ldap://172.16.0.1:389 +spring.ldap.base=DC=JUMAPACELAYA,DC=GOB,DC=MX +spring.ldap.username=administrator +spring.ldap.password=Dr3na%134$4guA @@ -26,4 +24,4 @@ password: Dr3na%134$4guA ########LOCAL###################################### redmine.url=http://localhost:3000/ -redmine.api_key=cf3be6168e66c99892c6212ea0bc64e8ab1c6848 \ No newline at end of file +redmine.api_key=66157c80f9efb6456757fa8f10887a2605d24fba \ No newline at end of file