HttpSession.java

  1. /*
  2.  * The coLAB project
  3.  * Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
  4.  *
  5.  * Licensed under the MIT License
  6.  */
  7. package ch.colabproject.colab.api.model.user;

  8. import static ch.colabproject.colab.api.model.user.User.USER_SEQUENCE_NAME;
  9. import ch.colabproject.colab.api.model.WithPermission;
  10. import ch.colabproject.colab.api.model.WithWebsocketChannels;
  11. import ch.colabproject.colab.api.model.tools.EntityHelper;
  12. import ch.colabproject.colab.api.security.permissions.Conditions;
  13. import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.AboutAccountChannelsBuilder;
  14. import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.ChannelsBuilder;
  15. import ch.colabproject.colab.api.ws.channel.tool.ChannelsBuilders.ForAdminChannelsBuilder;
  16. import ch.colabproject.colab.generator.model.interfaces.WithId;
  17. import ch.colabproject.colab.generator.model.interfaces.WithJsonDiscriminator;
  18. import java.time.OffsetDateTime;
  19. import javax.json.bind.annotation.JsonbTransient;
  20. import javax.persistence.Entity;
  21. import javax.persistence.FetchType;
  22. import javax.persistence.GeneratedValue;
  23. import javax.persistence.GenerationType;
  24. import javax.persistence.Id;
  25. import javax.persistence.Index;
  26. import javax.persistence.ManyToOne;
  27. import javax.persistence.NamedQuery;
  28. import javax.persistence.Table;
  29. import javax.persistence.Transient;
  30. import javax.validation.constraints.NotEmpty;
  31. import javax.validation.constraints.Size;

  32. /**
  33.  * store session related information
  34.  *
  35.  * @author maxence
  36.  */
  37. @Entity
  38. @Table(
  39.     indexes = {
  40.         @Index(columnList = "account_id"),
  41.     }
  42. )
  43. @NamedQuery(
  44.     name = "HttpSession.getOlderThan",
  45.     query = "SELECT session FROM HttpSession session WHERE session.lastSeen < :time"
  46. )
  47. public class HttpSession
  48.     implements WithId, WithJsonDiscriminator, WithPermission, WithWebsocketChannels {

  49.     private static final long serialVersionUID = 1L;

  50.     // ---------------------------------------------------------------------------------------------
  51.     // fields
  52.     // ---------------------------------------------------------------------------------------------

  53.     /**
  54.      * Not so secret id
  55.      */
  56.     @Id
  57.     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = USER_SEQUENCE_NAME)
  58.     private Long id;

  59.     /**
  60.      * raw secret, never persisted, never serialized to client. This is just a temporary field to
  61.      * store the raw value to put in SET-COOKIE
  62.      */
  63.     @Size(max = 255)
  64.     @JsonbTransient
  65.     @Transient
  66.     private String rawSessionSecret;

  67.     /**
  68.      * Session secret id. This value is hashed and is persisted in db.
  69.      * <p>
  70.      * DO NOT SERIALIZE IN JSON EVER
  71.      */
  72.     @JsonbTransient
  73.     @NotEmpty
  74.     private byte[] sessionSecret;

  75.     /**
  76.      * Last activity date
  77.      */
  78.     private OffsetDateTime lastSeen;

  79.     /**
  80.      * User Agent who create the session
  81.      */
  82.     @Size(max = 255)
  83.     private String userAgent;

  84.     /**
  85.      * A HttpSession belongs to an account
  86.      */
  87.     @ManyToOne(optional = false, fetch = FetchType.LAZY)
  88.     @JsonbTransient
  89.     private Account account;

  90.     /**
  91.      * id of the account used for authentication
  92.      */
  93.     @Transient
  94.     private Long accountId;

  95.     // ---------------------------------------------------------------------------------------------
  96.     // getters and setters
  97.     // ---------------------------------------------------------------------------------------------

  98.     /**
  99.      * @return account id
  100.      */
  101.     @Override
  102.     public Long getId() {
  103.         return id;
  104.     }

  105.     /**
  106.      * set id
  107.      *
  108.      * @param id id
  109.      */
  110.     public void setId(Long id) {
  111.         this.id = id;
  112.     }

  113.     /**
  114.      * Get the raw secret. This will almost always return null
  115.      *
  116.      * @return the raw secret or null
  117.      */
  118.     public String getRawSessionSecret() {
  119.         return rawSessionSecret;
  120.     }

  121.     /**
  122.      * Set raw secret value
  123.      *
  124.      * @param rawSessionSecret the raw secret
  125.      */
  126.     public void setRawSessionSecret(String rawSessionSecret) {
  127.         this.rawSessionSecret = rawSessionSecret;
  128.     }

  129.     /**
  130.      * @return Get the session id
  131.      */
  132.     public byte[] getSessionSecret() {
  133.         return sessionSecret;
  134.     }

  135.     /**
  136.      * Set session id
  137.      *
  138.      * @param sessionSecret id of the session
  139.      */
  140.     public void setSessionSecret(byte[] sessionSecret) {
  141.         this.sessionSecret = sessionSecret;
  142.     }

  143.     /**
  144.      * @return Get last activity date
  145.      */
  146.     public OffsetDateTime getLastSeen() {
  147.         return lastSeen;
  148.     }

  149.     /**
  150.      * Set last activity date
  151.      *
  152.      * @param lastSeen lastSeen
  153.      */
  154.     public void setLastSeen(OffsetDateTime lastSeen) {
  155.         this.lastSeen = lastSeen;
  156.     }

  157.     /**
  158.      * Get the value of userAgent
  159.      *
  160.      * @return the value of userAgent
  161.      */
  162.     public String getUserAgent() {
  163.         return userAgent;
  164.     }

  165.     /**
  166.      * Set the value of userAgent
  167.      *
  168.      * @param userAgent new value of userAgent
  169.      */
  170.     public void setUserAgent(String userAgent) {
  171.         this.userAgent = userAgent;
  172.     }

  173.     /**
  174.      * Get the account linked to this session. The only case the account may be null is on logout or
  175.      * when the session is going to be deleted
  176.      *
  177.      * @return authenticated account
  178.      */
  179.     public Account getAccount() {
  180.         return account;
  181.     }

  182.     /**
  183.      * Set the account linked to this HttpSession
  184.      *
  185.      * @param account authenticated account
  186.      */
  187.     public void setAccount(Account account) {
  188.         this.account = account;
  189.     }

  190.     /**
  191.      * @return authenticated account, null if not authenticated
  192.      */
  193.     public Long getAccountId() {
  194.         if (account != null) {
  195.             return account.getId();
  196.         } else {
  197.             return accountId;
  198.         }
  199.     }

  200.     /**
  201.      * Set authenticated account id
  202.      *
  203.      * @param accountId id of the account account
  204.      */
  205.     public void setAccountId(Long accountId) {
  206.         this.accountId = accountId;
  207.     }

  208.     // ---------------------------------------------------------------------------------------------
  209.     // concerning the whole class
  210.     // ---------------------------------------------------------------------------------------------

  211.     @Override
  212.     public ChannelsBuilder getChannelsBuilder() {
  213.         if (this.account != null) {
  214.             return new AboutAccountChannelsBuilder(this.account);
  215.         } else {
  216.             return new ForAdminChannelsBuilder();
  217.         }
  218.     }

  219.     @Override
  220.     @JsonbTransient
  221.     public Conditions.Condition getReadCondition() {
  222.         if (this.account != null) {
  223.             // same
  224.             return this.account.getReadCondition();
  225.         } else {
  226.             // not linked to any account, nothing to hide
  227.             // This case may only exist when the session is about to be destroyed
  228.             return Conditions.alwaysTrue;
  229.         }
  230.     }

  231.     @Override
  232.     @JsonbTransient
  233.     public Conditions.Condition getUpdateCondition() {
  234.         if (this.account != null) {
  235.             // same
  236.             return this.account.getUpdateCondition();
  237.         } else {
  238.             // not linked to any account, nothing to hide
  239.             // This case may only exist when the session is about to be destroyed
  240.             return Conditions.alwaysTrue;
  241.         }
  242.     }

  243.     @Override
  244.     @JsonbTransient
  245.     public Conditions.Condition getCreateCondition() {
  246.         // anyone can create a session
  247.         return Conditions.alwaysTrue;
  248.     }

  249.     @Override
  250.     public int hashCode() {
  251.         return EntityHelper.hashCode(this);
  252.     }

  253.     @Override
  254.     @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
  255.     public boolean equals(Object obj) {
  256.         return EntityHelper.equals(this, obj);
  257.     }

  258.     @Override
  259.     public String toString() {
  260.         return "HttpSession{" + "id=" + id + ", account=" + account + ", lastSeen=" + lastSeen
  261.             + '}';
  262.     }

  263. }