AuthorisationToken.vala 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using Invercargill;
  2. using Invercargill.Mapping;
  3. using Invercargill.DataStructures;
  4. using InvercargillJson;
  5. namespace Spry.Authorisation {
  6. /**
  7. * Data structure embedded in authorisation tokens.
  8. *
  9. * Token contents (JSON, encrypted and signed):
  10. * - id: Identity unique identifier
  11. * - username: Human-readable name
  12. * - permissions: Array of permission strings
  13. * - data: Additional variant data
  14. * - issued_at: Token issuance timestamp
  15. * - expires_at: Token expiry timestamp
  16. */
  17. public class AuthorisationToken {
  18. // Identity fields
  19. public Element user_identifier { get; private set; }
  20. public string username { get; private set; }
  21. public ImmutableLot<string> permissions { get; private set; }
  22. public DateTime issued_at { get; private set; }
  23. public DateTime expires_at { get; private set; }
  24. public string token_id { get; private set; }
  25. public Properties data { get; private set; }
  26. public ByteBuffer cryptographic_token { get; internal set; }
  27. /**
  28. * Creates a token from an Identity.
  29. *
  30. * @param identity The identity to create a token for
  31. * @param duration Optional token duration (defaults to 24 hours)
  32. */
  33. internal AuthorisationToken(Identity identity, TimeSpan? duration = null) {
  34. this.user_identifier = identity.identifier;
  35. this.username = identity.username;
  36. this.permissions = identity.permissions;
  37. this.data = identity.data;
  38. this.issued_at = new DateTime.now_utc();
  39. this.expires_at = new DateTime.now_utc().add(duration ?? TimeSpan.HOUR * 24);
  40. this.token_id = Uuid.string_random();
  41. }
  42. /**
  43. * Checks if the token has expired.
  44. *
  45. * @return true if the token has expired, false otherwise
  46. */
  47. public bool has_expired() {
  48. return expires_at.compare(new DateTime.now_utc()) <= 0;
  49. }
  50. // Blank constructor for mapper below
  51. private AuthorisationToken.blank() {
  52. }
  53. /**
  54. * Gets the property mapper for AuthorisationToken serialization.
  55. *
  56. * Uses the PropertyMapper system from Invercargill.Mapping for
  57. * consistent serialization with the rest of the framework.
  58. */
  59. public static PropertyMapper<AuthorisationToken> get_mapper() {
  60. return PropertyMapper.build_for<AuthorisationToken>(cfg => {
  61. cfg.map<Element>("uid", o => o.user_identifier, (o, v) => o.user_identifier = v);
  62. cfg.map<string>("unm", o => o.username, (o, v) => o.username = v);
  63. cfg.map_many<string>("prm", o => o.permissions, (o, v) => o.permissions = v.to_immutable_buffer())
  64. .when_null(o => o.permissions = Iterate.nothing<string>().to_immutable_buffer());
  65. cfg.map<Properties>("dat", o => o.data, (o, v) => o.data = v);
  66. cfg.map<string>("iat", o => o.issued_at.format_iso8601(), (o, v) => o.issued_at = new DateTime.from_iso8601(v, new TimeZone.utc()));
  67. cfg.map<string?>("eat",
  68. o => o.expires_at != null ? ((!)o.expires_at).format_iso8601() : null,
  69. (o, v) => o.expires_at = v != null ? new DateTime.from_iso8601((!)v, new TimeZone.utc()) : null);
  70. cfg.set_constructor(() => new AuthorisationToken.blank());
  71. });
  72. }
  73. }
  74. }