/graylog2-server/src/main/java/org/graylog2/rest/resources/system/CookieFactory.java

https://github.com/Graylog2/graylog2-server · Java · 109 lines · 72 code · 21 blank · 16 comment · 3 complexity · f6c5defe16729ba106d84e3798e2bdb8 MD5 · raw file

  1. /*
  2. * Copyright (C) 2020 Graylog, Inc.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the Server Side Public License, version 1,
  6. * as published by MongoDB, Inc.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * Server Side Public License for more details.
  12. *
  13. * You should have received a copy of the Server Side Public License
  14. * along with this program. If not, see
  15. * <http://www.mongodb.com/licensing/server-side-public-license>.
  16. */
  17. package org.graylog2.rest.resources.system;
  18. import com.google.common.base.Strings;
  19. import org.graylog2.configuration.HttpConfiguration;
  20. import org.graylog2.rest.models.system.sessions.responses.SessionResponse;
  21. import javax.ws.rs.container.ContainerRequestContext;
  22. import javax.ws.rs.core.Cookie;
  23. import javax.ws.rs.core.NewCookie;
  24. import java.net.URI;
  25. import java.util.Date;
  26. import java.util.Optional;
  27. public class CookieFactory {
  28. private static final String HEADER_ORIGIN = "Origin";
  29. private static final String HEADER_X_FORWARDED_PROTO = "X-Forwarded-Proto";
  30. NewCookie createAuthenticationCookie(SessionResponse token, ContainerRequestContext requestContext) {
  31. return makeCookie(token.getAuthenticationToken(), token.validUntil(), requestContext);
  32. }
  33. NewCookie deleteAuthenticationCookie(ContainerRequestContext requestContext) {
  34. return makeCookie("", new Date(), requestContext);
  35. }
  36. private NewCookie makeCookie(String value, Date validUntil, ContainerRequestContext requestContext) {
  37. final Date now = new Date();
  38. final int maxAge = Long.valueOf((validUntil.getTime() - now.getTime()) / 1000).intValue();
  39. final URI baseUri = baseUriFromRequest(requestContext);
  40. final String basePath = Optional.ofNullable(Strings.emptyToNull(baseUri.getPath())).orElse("/");
  41. final boolean isSecure = schemeFromRequest(requestContext)
  42. .map(scheme -> scheme.equalsIgnoreCase("https"))
  43. .orElse(false);
  44. return new NewCookie("authentication",
  45. value,
  46. basePath,
  47. null,
  48. Cookie.DEFAULT_VERSION,
  49. "Authentication Cookie",
  50. maxAge,
  51. validUntil,
  52. isSecure,
  53. true);
  54. }
  55. private Optional<String> schemeFromRequest(ContainerRequestContext requestContext) {
  56. final Optional<URI> graylogUrlFromHeader = uriFromHeader(requestContext, HttpConfiguration.OVERRIDE_HEADER);
  57. if (graylogUrlFromHeader.isPresent()) {
  58. return graylogUrlFromHeader.map(URI::getScheme);
  59. }
  60. final Optional<String> xForwardedProtoHeader = Optional.ofNullable(requestContext.getHeaderString(HEADER_X_FORWARDED_PROTO))
  61. .filter(header -> !Strings.isNullOrEmpty(header));
  62. if (xForwardedProtoHeader.isPresent()) {
  63. return xForwardedProtoHeader;
  64. }
  65. final Optional<URI> origin = uriFromHeader(requestContext, HEADER_ORIGIN);
  66. return origin.map(URI::getScheme);
  67. }
  68. private Optional<URI> uriFromHeader(ContainerRequestContext requestContext, String headerName) {
  69. return Optional.ofNullable(requestContext.getHeaderString(headerName))
  70. .filter(header -> !Strings.isNullOrEmpty(header))
  71. .flatMap(this::safeCreateUri);
  72. }
  73. private URI baseUriFromRequest(ContainerRequestContext requestContext) {
  74. final Optional<URI> graylogUrlFromHeader = uriFromHeader(requestContext, HttpConfiguration.OVERRIDE_HEADER);
  75. if (graylogUrlFromHeader.isPresent()) {
  76. return graylogUrlFromHeader.get();
  77. }
  78. final Optional<URI> origin = uriFromHeader(requestContext, HEADER_ORIGIN);
  79. return origin.orElseGet(() -> requestContext.getUriInfo().getBaseUri());
  80. }
  81. private Optional<URI> safeCreateUri(String uri) {
  82. try {
  83. return Optional.of(URI.create(uri));
  84. } catch (IllegalArgumentException ignored) {
  85. return Optional.empty();
  86. }
  87. }
  88. }