aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/traccar/api/resource/SessionResource.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/traccar/api/resource/SessionResource.java')
-rw-r--r--src/main/java/org/traccar/api/resource/SessionResource.java138
1 files changed, 75 insertions, 63 deletions
diff --git a/src/main/java/org/traccar/api/resource/SessionResource.java b/src/main/java/org/traccar/api/resource/SessionResource.java
index 7025d5fa7..979b62589 100644
--- a/src/main/java/org/traccar/api/resource/SessionResource.java
+++ b/src/main/java/org/traccar/api/resource/SessionResource.java
@@ -16,39 +16,41 @@
package org.traccar.api.resource;
import org.traccar.api.BaseResource;
+import org.traccar.api.security.CodeRequiredException;
+import org.traccar.api.security.LoginResult;
import org.traccar.api.security.LoginService;
import org.traccar.api.signature.TokenManager;
-import org.traccar.helper.DataConverter;
+import org.traccar.database.OpenIdProvider;
import org.traccar.helper.LogAction;
-import org.traccar.helper.ServletHelper;
+import org.traccar.helper.WebHelper;
import org.traccar.model.User;
import org.traccar.storage.StorageException;
import org.traccar.storage.query.Columns;
import org.traccar.storage.query.Condition;
import org.traccar.storage.query.Request;
-import javax.annotation.security.PermitAll;
-import javax.inject.Inject;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.FormParam;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
+import com.nimbusds.oauth2.sdk.ParseException;
+import jakarta.annotation.Nullable;
+import jakarta.annotation.security.PermitAll;
+import jakarta.inject.Inject;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
import java.io.IOException;
-import java.net.URLDecoder;
-import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.Date;
+import java.net.URI;
@Path("session")
@Produces(MediaType.APPLICATION_JSON)
@@ -56,13 +58,16 @@ import java.util.Date;
public class SessionResource extends BaseResource {
public static final String USER_ID_KEY = "userId";
- public static final String USER_COOKIE_KEY = "user";
- public static final String PASS_COOKIE_KEY = "password";
+ public static final String EXPIRATION_KEY = "expiration";
@Inject
private LoginService loginService;
@Inject
+ @Nullable
+ private OpenIdProvider openIdProvider;
+
+ @Inject
private TokenManager tokenManager;
@Context
@@ -73,48 +78,22 @@ public class SessionResource extends BaseResource {
public User get(@QueryParam("token") String token) throws StorageException, IOException, GeneralSecurityException {
if (token != null) {
- User user = loginService.login(token);
- if (user != null) {
+ LoginResult loginResult = loginService.login(token);
+ if (loginResult != null) {
+ User user = loginResult.getUser();
request.getSession().setAttribute(USER_ID_KEY, user.getId());
- LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request));
+ request.getSession().setAttribute(EXPIRATION_KEY, loginResult.getExpiration());
+ LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request));
return user;
}
}
Long userId = (Long) request.getSession().getAttribute(USER_ID_KEY);
- if (userId == null) {
-
- Cookie[] cookies = request.getCookies();
- String email = null, password = null;
- if (cookies != null) {
- for (Cookie cookie : cookies) {
- if (cookie.getName().equals(USER_COOKIE_KEY)) {
- byte[] emailBytes = DataConverter.parseBase64(
- URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII));
- email = new String(emailBytes, StandardCharsets.UTF_8);
- } else if (cookie.getName().equals(PASS_COOKIE_KEY)) {
- byte[] passwordBytes = DataConverter.parseBase64(
- URLDecoder.decode(cookie.getValue(), StandardCharsets.US_ASCII));
- password = new String(passwordBytes, StandardCharsets.UTF_8);
- }
- }
- }
- if (email != null && password != null) {
- User user = loginService.login(email, password);
- if (user != null) {
- request.getSession().setAttribute(USER_ID_KEY, user.getId());
- LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request));
- return user;
- }
- }
-
- } else {
-
+ if (userId != null) {
User user = permissionsService.getUser(userId);
if (user != null) {
return user;
}
-
}
throw new WebApplicationException(Response.status(Response.Status.NOT_FOUND).build());
@@ -123,32 +102,44 @@ public class SessionResource extends BaseResource {
@Path("{id}")
@GET
public User get(@PathParam("id") long userId) throws StorageException {
- permissionsService.checkAdmin(getUserId());
+ permissionsService.checkUser(getUserId(), userId);
User user = storage.getObject(User.class, new Request(
new Columns.All(), new Condition.Equals("id", userId)));
request.getSession().setAttribute(USER_ID_KEY, user.getId());
- LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request));
+ LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request));
return user;
}
@PermitAll
@POST
public User add(
- @FormParam("email") String email, @FormParam("password") String password) throws StorageException {
- User user = loginService.login(email, password);
- if (user != null) {
+ @FormParam("email") String email,
+ @FormParam("password") String password,
+ @FormParam("code") Integer code) throws StorageException {
+ LoginResult loginResult;
+ try {
+ loginResult = loginService.login(email, password, code);
+ } catch (CodeRequiredException e) {
+ Response response = Response
+ .status(Response.Status.UNAUTHORIZED)
+ .header("WWW-Authenticate", "TOTP")
+ .build();
+ throw new WebApplicationException(response);
+ }
+ if (loginResult != null) {
+ User user = loginResult.getUser();
request.getSession().setAttribute(USER_ID_KEY, user.getId());
- LogAction.login(user.getId(), ServletHelper.retrieveRemoteAddress(request));
+ LogAction.login(user.getId(), WebHelper.retrieveRemoteAddress(request));
return user;
} else {
- LogAction.failedLogin(ServletHelper.retrieveRemoteAddress(request));
+ LogAction.failedLogin(WebHelper.retrieveRemoteAddress(request));
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
@DELETE
public Response remove() {
- LogAction.logout(getUserId(), ServletHelper.retrieveRemoteAddress(request));
+ LogAction.logout(getUserId(), WebHelper.retrieveRemoteAddress(request));
request.getSession().removeAttribute(USER_ID_KEY);
return Response.noContent().build();
}
@@ -157,7 +148,28 @@ public class SessionResource extends BaseResource {
@POST
public String requestToken(
@FormParam("expiration") Date expiration) throws StorageException, GeneralSecurityException, IOException {
+ Date currentExpiration = (Date) request.getSession().getAttribute(EXPIRATION_KEY);
+ if (currentExpiration != null && currentExpiration.before(expiration)) {
+ expiration = currentExpiration;
+ }
return tokenManager.generateToken(getUserId(), expiration);
}
+ @PermitAll
+ @Path("openid/auth")
+ @GET
+ public Response openIdAuth() {
+ return Response.seeOther(openIdProvider.createAuthUri()).build();
+ }
+
+ @PermitAll
+ @Path("openid/callback")
+ @GET
+ public Response requestToken() throws IOException, StorageException, ParseException, GeneralSecurityException {
+ StringBuilder requestUrl = new StringBuilder(request.getRequestURL().toString());
+ String queryString = request.getQueryString();
+ String requestUri = requestUrl.append('?').append(queryString).toString();
+
+ return Response.seeOther(openIdProvider.handleCallback(URI.create(requestUri), request)).build();
+ }
}