@ -1,121 +0,0 @@ | |||
package com.example.application.api; | |||
import com.nimbusds.jose.shaded.gson.Gson; | |||
import com.nimbusds.jose.shaded.gson.JsonObject; | |||
import com.nimbusds.jose.shaded.gson.JsonParser; | |||
import java.net.URI; | |||
import java.net.http.HttpClient; | |||
import java.net.http.HttpRequest; | |||
import java.net.http.HttpResponse; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
public class ApiRedmine { | |||
public static final Gson GSON = new Gson(); | |||
static String REDMINE_URL; | |||
static String API_KEY; | |||
public ApiRedmine(String redmineurl, String apikey) { | |||
REDMINE_URL = redmineurl; | |||
API_KEY = apikey; | |||
} | |||
public static String createIssue(Map<String, String> issueDetails) { | |||
return createIssue(issueDetails, null); | |||
} | |||
public static String createIssue(Map<String, String> issueDetails, String fileUploadToken) { | |||
Map<String, Object> payload = new HashMap<>(); | |||
payload.put("issue", issueDetails); | |||
if (fileUploadToken != null) { | |||
List<Map<String, String>> uploads = new ArrayList<>(); | |||
Map<String, String> fileTokenMap = new HashMap<>(); | |||
fileTokenMap.put("token", fileUploadToken); | |||
uploads.add(fileTokenMap); | |||
payload.put("uploads", uploads); | |||
} | |||
String jsonPayload = GSON.toJson(payload); | |||
try { | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/issues.json")) | |||
.header("Content-Type", "application/json") | |||
.header("X-Redmine-API-Key", API_KEY) | |||
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) | |||
.build(); | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
return response.body(); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return "Error: " + e.getMessage(); | |||
} | |||
} | |||
public List<String> getTicketTypes() { | |||
List<String> ticketTypes = new ArrayList<>(); | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/trackers.json")) | |||
.header("Content-Type", "application/json") | |||
.header("X-Redmine-API-Key", API_KEY) | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 200) { | |||
String responseBody = response.body(); | |||
ticketTypes = parseTicketTypes(responseBody); | |||
} else { | |||
System.err.println("Error en la respuesta: " + response.statusCode()); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
return ticketTypes; | |||
} | |||
private List<String> parseTicketTypes(String json) { | |||
List<String> names = new ArrayList<>(); | |||
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); | |||
jsonObject.getAsJsonArray("trackers").forEach(trackerElement -> { | |||
JsonObject tracker = trackerElement.getAsJsonObject(); | |||
names.add(tracker.get("name").getAsString()); | |||
}); | |||
return names; | |||
} | |||
public static String uploadFile(byte[] fileContent, String fileName) { | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/uploads.json")) | |||
.header("Content-Type", "application/octet-stream") | |||
.header("X-Redmine-API-Key", API_KEY) | |||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"") | |||
.POST(HttpRequest.BodyPublishers.ofByteArray(fileContent)) | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 201) { | |||
JsonObject jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject(); | |||
return jsonResponse.get("upload").getAsJsonObject().get("token").getAsString(); | |||
} else { | |||
System.err.println("Error en la subida del archivo: " + response.statusCode()); | |||
System.err.println("Response body: " + response.body()); | |||
return null; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
} |
@ -1,127 +0,0 @@ | |||
package com.example.application.api; | |||
import com.example.application.models.Ticket; | |||
import com.nimbusds.jose.shaded.gson.JsonArray; | |||
import com.nimbusds.jose.shaded.gson.JsonElement; | |||
import com.nimbusds.jose.shaded.gson.JsonObject; | |||
import com.nimbusds.jose.shaded.gson.JsonParser; | |||
import java.net.URI; | |||
import java.net.http.HttpClient; | |||
import java.net.http.HttpRequest; | |||
import java.net.http.HttpResponse; | |||
import java.time.LocalDate; | |||
import java.time.format.DateTimeFormatter; | |||
import java.time.format.DateTimeParseException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
public class RedmineClient { | |||
private static final int PAGE_SIZE = 25; | |||
static String REDMINE_URL; | |||
static String API_KEY; | |||
public RedmineClient(String redmineUrl, String apiKey) { | |||
REDMINE_URL = redmineUrl; | |||
API_KEY = apiKey; | |||
} | |||
public List<Ticket> getTickets() { | |||
List<Ticket> tickets = new ArrayList<>(); | |||
HttpClient client = HttpClient.newHttpClient(); | |||
int offset = 0; | |||
while (true) { | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + API_KEY + "&offset=" + offset)) | |||
.header("Content-Type", "application/json") | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 200) { | |||
String responseBody = response.body(); | |||
List<Ticket> pageTickets = parseTickets(responseBody); | |||
tickets.addAll(pageTickets); | |||
if (pageTickets.size() < PAGE_SIZE) { | |||
break; | |||
} | |||
offset += PAGE_SIZE; | |||
} else { | |||
System.err.println("Error en la respuesta: " + response.statusCode()); | |||
break; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
break; | |||
} | |||
} | |||
System.out.println("Total tickets obtenidos: " + tickets.size()); | |||
return tickets; | |||
} | |||
private List<Ticket> parseTickets(String json) { | |||
List<Ticket> tickets = new ArrayList<>(); | |||
try { | |||
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); | |||
JsonArray issues = jsonObject.getAsJsonArray("issues"); | |||
if (issues != null) { | |||
for (JsonElement issueElement : issues) { | |||
JsonObject issue = issueElement.getAsJsonObject(); | |||
int id = issue.has("id") ? issue.get("id").getAsInt() : 0; | |||
String subject = issue.has("subject") ? issue.get("subject").getAsString() : ""; | |||
String description = issue.has("description") ? issue.get("description").getAsString() : ""; | |||
String status = issue.has("status") ? issue.getAsJsonObject("status").get("name").getAsString() : "Unknown"; | |||
String dateString = issue.has("created_on") ? issue.get("created_on").getAsString() : ""; | |||
LocalDate date = null; | |||
if (!dateString.isEmpty()) { | |||
try { | |||
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; | |||
date = LocalDate.parse(dateString, formatter); | |||
} catch (DateTimeParseException e) { | |||
System.err.println("Error al parsear la fecha: " + dateString); | |||
e.printStackTrace(); | |||
} | |||
} | |||
JsonObject authorJson = issue.has("author") ? issue.getAsJsonObject("author") : null; | |||
Ticket.User author = null; | |||
if (authorJson != null) { | |||
String username = authorJson.has("name") ? authorJson.get("name").getAsString() : "Unknown"; | |||
author = new Ticket.User(username); | |||
} | |||
tickets.add(new Ticket(id, subject, description, status, date != null ? date.toString() : "", author)); | |||
} | |||
} else { | |||
System.out.println("La respuesta JSON no contiene la clave 'issues'"); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
System.out.println("Ocurrió un error al parsear los tickets: " + e.getMessage()); | |||
} | |||
return tickets; | |||
} | |||
public List<Ticket> getTicketsCreatedBy(String username) { | |||
List<Ticket> allTickets = getTickets(); | |||
return allTickets.stream() | |||
.filter(ticket -> ticket.getAuthor() != null && username.equals(ticket.getAuthor().getUsername())) | |||
.collect(Collectors.toList()); | |||
} | |||
private static class TicketResponse { | |||
private List<Ticket> issues; | |||
public List<Ticket> getIssues() { | |||
return issues; | |||
} | |||
public void setIssues(List<Ticket> issues) { | |||
this.issues = issues; | |||
} | |||
} | |||
} |
@ -1,58 +0,0 @@ | |||
package com.example.application.views.login; | |||
import com.vaadin.flow.component.html.Image; | |||
import com.vaadin.flow.component.login.LoginForm; | |||
import com.vaadin.flow.component.login.LoginI18n; | |||
import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||
import com.vaadin.flow.router.BeforeEnterEvent; | |||
import com.vaadin.flow.router.BeforeEnterObserver; | |||
import com.vaadin.flow.router.PageTitle; | |||
import com.vaadin.flow.router.Route; | |||
import com.vaadin.flow.server.auth.AnonymousAllowed; | |||
@Route("login") | |||
@PageTitle("Login") | |||
@AnonymousAllowed | |||
public class LoginView extends VerticalLayout implements BeforeEnterObserver { | |||
private final LoginForm formularioLogin; | |||
public LoginView() { | |||
addClassName("vista-login"); | |||
setSizeFull(); | |||
setAlignItems(Alignment.CENTER); | |||
setJustifyContentMode(JustifyContentMode.CENTER); | |||
Image logo = new Image("images/NVO_JUMAPA.png", "Logo JUMAPA"); | |||
logo.setWidth("300px"); | |||
LoginI18n i18n = LoginI18n.createDefault(); | |||
LoginI18n.Form i18nFormulario = i18n.getForm(); | |||
i18nFormulario.setTitle("Sistema de Soporte Técnico Gcia. de T.I"); | |||
i18nFormulario.setUsername("Usuario"); | |||
i18nFormulario.setPassword("Contraseña"); | |||
i18nFormulario.setSubmit("Iniciar sesión"); | |||
i18n.setForm(i18nFormulario); | |||
i18n.getErrorMessage().setTitle("Credenciales incorrectas"); | |||
i18n.getErrorMessage().setMessage("El usuario o la contraseña son incorrectos, verifica tus credenciales."); | |||
formularioLogin = new LoginForm(); | |||
formularioLogin.setAction("login"); | |||
formularioLogin.setForgotPasswordButtonVisible(false); | |||
formularioLogin.setI18n(i18n); | |||
add(logo, formularioLogin); | |||
} | |||
@Override | |||
public void beforeEnter(BeforeEnterEvent beforeEnterEvent) { | |||
if (beforeEnterEvent.getLocation() | |||
.getQueryParameters() | |||
.getParameters() | |||
.containsKey("error")) { | |||
formularioLogin.setError(true); | |||
} | |||
} | |||
} | |||
@ -0,0 +1 @@ | |||
@ -0,0 +1,349 @@ | |||
package mx.gob.jumapacelaya.api; | |||
import com.nimbusds.jose.shaded.gson.*; | |||
import com.vaadin.flow.server.VaadinService; | |||
import mx.gob.jumapacelaya.models.RedmineUser; | |||
import mx.gob.jumapacelaya.models.Ticket; | |||
import org.springframework.beans.factory.annotation.Value; | |||
import org.springframework.stereotype.Component; | |||
import java.io.IOException; | |||
import java.net.URI; | |||
import java.net.http.HttpClient; | |||
import java.net.http.HttpRequest; | |||
import java.net.http.HttpResponse; | |||
import java.time.LocalDate; | |||
import java.time.format.DateTimeFormatter; | |||
import java.time.format.DateTimeParseException; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
@Component | |||
public class RedmineClient { | |||
private static final int PAGE_SIZE = 25; | |||
static String REDMINE_URL; | |||
static String API_KEY; | |||
public static final Gson GSON = new Gson(); | |||
public RedmineClient(@Value("${redmine.url}") String redmineUrl, @Value("${redmine.api_key}") String apiKey) { | |||
REDMINE_URL = redmineUrl; | |||
API_KEY = apiKey; | |||
} | |||
//AQUI OBTENGO LOS TICKETS DESDE REDMINE | |||
public List<Ticket> getTickets(RedmineUser user) { | |||
List<Ticket> tickets = new ArrayList<>(); | |||
HttpClient client = HttpClient.newHttpClient(); | |||
int offset = 0; | |||
while (true) { | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + "&offset=" + offset)) | |||
.header("Content-Type", "application/json") | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 200) { | |||
String responseBody = response.body(); | |||
List<Ticket> pageTickets = parseTickets(responseBody); | |||
tickets.addAll(pageTickets); | |||
if (pageTickets.size() < PAGE_SIZE) { | |||
break; | |||
} | |||
offset += PAGE_SIZE; | |||
} else { | |||
System.err.println("Error en la respuesta: " + response.statusCode()); | |||
break; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
break; | |||
} | |||
} | |||
System.out.println("Total tickets obtenidos: " + tickets.size()); | |||
return tickets; | |||
} | |||
//AQUI OBTENGO LOS TICKETS DESDE REDMINE | |||
public List<Ticket> getTicketsAuthor(RedmineUser user) { | |||
List<Ticket> tickets = new ArrayList<>(); | |||
HttpClient client = HttpClient.newHttpClient(); | |||
int offset = 0; | |||
while (true) { | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + "&author_id=" + user.getId() + "&offset=" + offset)) | |||
.header("Content-Type", "application/json") | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 200) { | |||
String responseBody = response.body(); | |||
List<Ticket> pageTickets = parseTickets(responseBody); | |||
tickets.addAll(pageTickets); | |||
if (pageTickets.size() < PAGE_SIZE) { | |||
break; | |||
} | |||
offset += PAGE_SIZE; | |||
} else { | |||
System.err.println("Error en la respuesta: " + response.statusCode()); | |||
break; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
break; | |||
} | |||
} | |||
System.out.println("Total tickets obtenidos: " + tickets.size()); | |||
return tickets; | |||
} | |||
//Aqui se parsean todos los tickets que existen y se les da un formato con los campos a mostrarse | |||
private List<Ticket> parseTickets(String json) { | |||
List<Ticket> tickets = new ArrayList<>(); | |||
try { | |||
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); | |||
JsonArray issues = jsonObject.getAsJsonArray("issues"); | |||
if (issues != null) { | |||
for (JsonElement issueElement : issues) { | |||
JsonObject issue = issueElement.getAsJsonObject(); | |||
int id = issue.has("id") ? issue.get("id").getAsInt() : 0; | |||
String subject = issue.has("subject") ? issue.get("subject").getAsString() : ""; | |||
String description = issue.has("description") ? issue.get("description").getAsString() : ""; | |||
String status = issue.has("status") ? issue.getAsJsonObject("status").get("name").getAsString() : "Unknown"; | |||
String dateString = issue.has("created_on") ? issue.get("created_on").getAsString() : ""; | |||
LocalDate date = null; | |||
if (!dateString.isEmpty()) { | |||
try { | |||
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME; | |||
date = LocalDate.parse(dateString, formatter); | |||
} catch (DateTimeParseException e) { | |||
System.err.println("Error al parsear la fecha: " + dateString); | |||
e.printStackTrace(); | |||
} | |||
} | |||
JsonObject authorJson = issue.has("author") ? issue.getAsJsonObject("author") : null; | |||
Ticket.User author = null; | |||
if (authorJson != null) { | |||
String username = authorJson.has("name") ? authorJson.get("name").getAsString() : "Unknown"; | |||
author = new Ticket.User(username); | |||
} | |||
tickets.add(new Ticket(id, subject, description, status, date != null ? date.toString() : "", author)); | |||
} | |||
} else { | |||
System.out.println("La respuesta JSON no contiene la clave 'issues'"); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
System.out.println("Ocurrió un error al parsear los tickets: " + e.getMessage()); | |||
} | |||
return tickets; | |||
} | |||
private static class TicketResponse { | |||
private List<Ticket> issues; | |||
public List<Ticket> getIssues() { | |||
return issues; | |||
} | |||
public void setIssues(List<Ticket> issues) { | |||
this.issues = issues; | |||
} | |||
} | |||
//AQUI OBTENGO A LOS USUARIOS | |||
//Se devuelven en formato Json | |||
public RedmineUser getUserByUsername(String username) { | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/users.json?name=" + username )) | |||
.header("Content-Type", "application/json") | |||
.header("X-Redmine-API-Key", API_KEY) | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 200) { | |||
String responseBody = response.body(); | |||
System.out.println("Datos del usuario " + responseBody); | |||
return parseUser(responseBody); | |||
} else { | |||
System.err.println("Error en la respuesta: " + response.statusCode()); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
return null; | |||
} | |||
//Aqui se parsean a los usuarios y se les da un formato con los campos a mostrarse | |||
private RedmineUser parseUser(String json) { | |||
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); | |||
JsonObject userJson = jsonObject.getAsJsonArray("users").get(0).getAsJsonObject(); | |||
RedmineUser user = new RedmineUser(); | |||
user.setId(userJson.get("id").getAsInt()); | |||
user.setLogin(userJson.get("login").getAsString()); | |||
user.setFirstname(userJson.get("firstname").getAsString()); | |||
user.setLastname(userJson.get("lastname").getAsString()); | |||
user.setMail(userJson.get("mail").getAsString()); | |||
//user.setKey(userJson.get("key").getAsString()); | |||
return user; | |||
} | |||
public RedmineUser getMyAccount(String username) { | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/my/account.json")) | |||
.header("Content-Type", "application/json") | |||
.header("X-Redmine-Switch-User", username) | |||
.header("X-Redmine-API-Key", API_KEY) | |||
.GET() | |||
.build(); | |||
try { | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject(); | |||
JsonObject userJson = jsonObject.get("user").getAsJsonObject(); | |||
RedmineUser user = new RedmineUser(); | |||
user.setId(userJson.get("id").getAsInt()); | |||
user.setLogin(userJson.get("login").getAsString()); | |||
user.setFirstname(userJson.get("firstname").getAsString()); | |||
user.setLastname(userJson.get("lastname").getAsString()); | |||
user.setMail(userJson.get("mail").getAsString()); | |||
user.setKey(userJson.get("api_key").getAsString()); | |||
return user; | |||
//return response.body(); | |||
} catch (IOException | InterruptedException e) { | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
public String uploadFile(byte[] fileContent, String fileName) { | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/uploads.json")) | |||
.header("Content-Type", "application/octet-stream") | |||
.header("X-Redmine-API-Key", API_KEY) | |||
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"") | |||
.POST(HttpRequest.BodyPublishers.ofByteArray(fileContent)) | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 201) { | |||
JsonObject jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject(); | |||
return jsonResponse.get("upload").getAsJsonObject().get("token").getAsString(); | |||
} else { | |||
System.err.println("Error en la subida del archivo: " + response.statusCode()); | |||
System.err.println("Response body: " + response.body()); | |||
return null; | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
} | |||
public String createIssue(Map<String, String> issueDetails, String apiKey) { | |||
return createIssue(issueDetails, null, apiKey); | |||
} | |||
public String createIssue(Map<String, String> issueDetails, String fileUploadToken, String apiKey) { | |||
Map<String, Object> payload = new HashMap<>(); | |||
payload.put("issue", issueDetails); | |||
RedmineUser user = (RedmineUser) VaadinService.getCurrentRequest().getWrappedSession().getAttribute("myaccount"); | |||
if (fileUploadToken != null) { | |||
List<Map<String, String>> uploads = new ArrayList<>(); | |||
Map<String, String> fileTokenMap = new HashMap<>(); | |||
fileTokenMap.put("token", fileUploadToken); | |||
uploads.add(fileTokenMap); | |||
payload.put("uploads", uploads); | |||
} | |||
String jsonPayload = GSON.toJson(payload); | |||
try { | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/issues.json")) | |||
.header("Content-Type", "application/json") | |||
.header("X-Redmine-API-Key", user.getKey()) | |||
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload)) | |||
.build(); | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
return response.body(); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
return "Error: " + e.getMessage(); | |||
} | |||
} | |||
public List<String> getTicketTypes() { | |||
List<String> ticketTypes = new ArrayList<>(); | |||
HttpClient client = HttpClient.newHttpClient(); | |||
HttpRequest request = HttpRequest.newBuilder() | |||
.uri(URI.create(REDMINE_URL + "/trackers.json")) | |||
.header("Content-Type", "application/json") | |||
.header("X-Redmine-API-Key", API_KEY) | |||
.build(); | |||
try { | |||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | |||
if (response.statusCode() == 200) { | |||
String responseBody = response.body(); | |||
ticketTypes = parseTicketTypes(responseBody); | |||
} else { | |||
System.err.println("Error en la respuesta: " + response.statusCode()); | |||
} | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
} | |||
return ticketTypes; | |||
} | |||
private List<String> parseTicketTypes(String json) { | |||
List<String> names = new ArrayList<>(); | |||
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject(); | |||
jsonObject.getAsJsonArray("trackers").forEach(trackerElement -> { | |||
JsonObject tracker = trackerElement.getAsJsonObject(); | |||
names.add(tracker.get("name").getAsString()); | |||
}); | |||
return names; | |||
} | |||
} |
@ -0,0 +1,23 @@ | |||
package mx.gob.jumapacelaya.controllers; | |||
import mx.gob.jumapacelaya.models.RedmineUser; | |||
import mx.gob.jumapacelaya.services.UserService; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.web.bind.annotation.GetMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
@RestController | |||
public class UserController { | |||
private final UserService userService; | |||
@Autowired | |||
public UserController(UserService userService) { | |||
this.userService = userService; | |||
} | |||
@GetMapping("/current-user") | |||
public RedmineUser getCurrentUser() { | |||
return userService.getAuthenticatedRedmineUser(); | |||
} | |||
} |
@ -0,0 +1,73 @@ | |||
package mx.gob.jumapacelaya.models; | |||
public class RedmineUser { | |||
private int id; | |||
private String login; | |||
private String firstname; | |||
private String lastname; | |||
private String mail; | |||
private String key; | |||
public int getId() { | |||
return id; | |||
} | |||
public void setId(int id) { | |||
this.id = id; | |||
} | |||
public String getLogin() { | |||
return login; | |||
} | |||
public void setLogin(String login) { | |||
this.login = login; | |||
} | |||
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 getMail() { | |||
return mail; | |||
} | |||
public void setMail(String mail) { | |||
this.mail = mail; | |||
} | |||
public String getKey() { | |||
return key; | |||
} | |||
public void setKey(String key) { | |||
this.key = key; | |||
} | |||
@Override | |||
public String toString() { | |||
return "RedmineUser{" + | |||
"id=" + id + | |||
", login='" + login + '\'' + | |||
", firstname='" + firstname + '\'' + | |||
", lastname='" + lastname + '\'' + | |||
", mail='" + mail + '\'' + | |||
", key='" + key + '\'' + | |||
'}'; | |||
} | |||
} |
@ -0,0 +1,2 @@ | |||
package mx.gob.jumapacelaya.models;public class RedmineUser_Model { | |||
} |
@ -0,0 +1,61 @@ | |||
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.RedmineUser; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.springframework.stereotype.Service; | |||
@Service | |||
public class UserService { | |||
private final SecurityService securityService; | |||
private final RedmineClient redmineClient; | |||
private static final Logger logger = LoggerFactory.getLogger(UserService.class); | |||
public UserService(SecurityService securityService, RedmineClient redmineClient) { | |||
this.securityService = securityService; | |||
this.redmineClient = redmineClient; | |||
} | |||
/** | |||
* Obtiene el usuario autenticado de Redmine. | |||
* | |||
* @return el usuario autenticado de Redmine, o null si no hay un usuario autenticado. | |||
*/ | |||
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); | |||
return user; | |||
} | |||
} catch (Exception e) { | |||
logger.error("Error al obtener al usuario autenticado en Redmine", e); | |||
} | |||
return null; | |||
} | |||
public RedmineUser getRedmineUser() { | |||
RedmineUser userclient = (RedmineUser) VaadinService.getCurrentRequest().getWrappedSession().getAttribute("myaccount"); | |||
if (userclient == null) { | |||
RedmineUser user = getAuthenticatedRedmineUser(); | |||
if (user != null) { | |||
RedmineUser myAccount = redmineClient.getMyAccount(user.getLogin()); | |||
if (myAccount != null && !myAccount.getKey().isEmpty()) { | |||
userclient = myAccount; | |||
VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount); | |||
} | |||
} | |||
} | |||
return userclient; | |||
} | |||
} |
@ -0,0 +1,92 @@ | |||
package mx.gob.jumapacelaya.views.login; | |||
import com.vaadin.flow.component.html.Image; | |||
import com.vaadin.flow.component.login.LoginForm; | |||
import com.vaadin.flow.component.login.LoginI18n; | |||
import com.vaadin.flow.component.orderedlayout.VerticalLayout; | |||
import com.vaadin.flow.router.BeforeEnterEvent; | |||
import com.vaadin.flow.router.BeforeEnterObserver; | |||
import com.vaadin.flow.router.PageTitle; | |||
import com.vaadin.flow.router.Route; | |||
import com.vaadin.flow.server.auth.AnonymousAllowed; | |||
import mx.gob.jumapacelaya.api.RedmineClient; | |||
import mx.gob.jumapacelaya.services.UserService; | |||
@Route("login") | |||
@PageTitle("Login") | |||
@AnonymousAllowed | |||
public class LoginView extends VerticalLayout implements BeforeEnterObserver { //}, ComponentEventListener<AbstractLogin.LoginEvent> { | |||
private final LoginForm formularioLogin; | |||
private static final String LOGIN_SUCCESS_URL = ""; // URL de redirección después del login exitoso | |||
private final UserService userService; | |||
private final RedmineClient redmineClient; | |||
public LoginView(UserService userService, RedmineClient redmineClient) { | |||
addClassName("vista-login"); | |||
setSizeFull(); | |||
setAlignItems(Alignment.CENTER); | |||
setJustifyContentMode(JustifyContentMode.CENTER); | |||
// Imagen del logo | |||
Image logo = new Image("images/NVO_JUMAPA.png", "Logo JUMAPA"); | |||
logo.setWidth("300px"); | |||
// Configuración de i18n para el formulario de login | |||
LoginI18n i18n = LoginI18n.createDefault(); | |||
LoginI18n.Form i18nFormulario = i18n.getForm(); | |||
i18nFormulario.setTitle("Sistema de Soporte Técnico Gcia. de T.I"); | |||
i18nFormulario.setUsername("Usuario"); | |||
i18nFormulario.setPassword("Contraseña"); | |||
i18nFormulario.setSubmit("Iniciar sesión"); | |||
i18n.setForm(i18nFormulario); | |||
i18n.getErrorMessage().setTitle("Credenciales incorrectas"); | |||
i18n.getErrorMessage().setMessage("El usuario o la contraseña son incorrectos, verifica tus credenciales."); | |||
// Configuración del formulario de login | |||
formularioLogin = new LoginForm(); | |||
formularioLogin.setAction("login"); | |||
formularioLogin.setForgotPasswordButtonVisible(false); | |||
formularioLogin.setI18n(i18n); | |||
// Añadir el listener del evento de login | |||
//formularioLogin.addLoginListener(this); | |||
// Añadir componentes a la vista | |||
add(logo, formularioLogin); | |||
this.userService = userService; | |||
this.redmineClient = redmineClient; | |||
} | |||
@Override | |||
public void beforeEnter(BeforeEnterEvent beforeEnterEvent) { | |||
// Mostrar el mensaje de error si hay un parámetro de error en la URL | |||
if (beforeEnterEvent.getLocation().getQueryParameters().getParameters().containsKey("error")) { | |||
formularioLogin.setError(true); | |||
} | |||
} | |||
// Manejar el evento de login | |||
/*@Override | |||
public void onComponentEvent(AbstractLogin.LoginEvent event) { | |||
boolean authenticated = mx.gob.jumapacelaya.views.login.SecurityUtils.authenticate( | |||
event.getUsername(), event.getPassword()); | |||
if (authenticated) { | |||
RedmineUser user = userService.getAuthenticatedRedmineUser(); | |||
if (user != null) { | |||
RedmineUser myAccount = redmineClient.getMyAccount(user.getLogin()); | |||
if (myAccount != null && !myAccount.getKey().isEmpty()) { | |||
VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount); | |||
//UI.getCurrent().getPage().setLocation(LOGIN_SUCCESS_URL); | |||
} //else { | |||
// formularioLogin.setError(true); | |||
//} | |||
//} else { | |||
// formularioLogin.setError(true); | |||
} | |||
} //else { | |||
//formularioLogin.setError(true); | |||
// } | |||
}*/ | |||
} |
@ -0,0 +1,39 @@ | |||
package mx.gob.jumapacelaya.views.login; | |||
import com.vaadin.flow.component.UI; | |||
import com.vaadin.flow.server.VaadinServletRequest; | |||
import com.vaadin.flow.server.VaadinSession; | |||
import jakarta.servlet.ServletException; | |||
public class SecurityUtils { | |||
private static final String LOGOUT_SUCCESS_URL = "login"; | |||
public static boolean isAuthenticated() { | |||
VaadinServletRequest request = VaadinServletRequest.getCurrent(); | |||
return request != null && request.getUserPrincipal() != null; | |||
} | |||
public static boolean authenticate(String username, String password) { | |||
VaadinServletRequest request = VaadinServletRequest.getCurrent(); | |||
if (request == null) { | |||
// This is in a background thread and we can't access the request to | |||
// log in the user | |||
return false; | |||
} | |||
try { | |||
request.login(username, password); | |||
// change session ID to protect against session fixation | |||
request.getHttpServletRequest().changeSessionId(); | |||
return true; | |||
} catch (ServletException e) { | |||
// login exception handle code omitted | |||
return false; | |||
} | |||
} | |||
public static void logout() { | |||
UI.getCurrent().getPage().setLocation(LOGOUT_SUCCESS_URL); | |||
VaadinSession.getCurrent().getSession().invalidate(); | |||
} | |||
} |