enrollment_key.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package models
  2. import (
  3. "errors"
  4. "fmt"
  5. "time"
  6. "github.com/google/uuid"
  7. )
  8. const (
  9. Undefined KeyType = iota
  10. TimeExpiration
  11. Uses
  12. Unlimited
  13. )
  14. var (
  15. ErrNilEnrollmentKey = errors.New("enrollment key is nil")
  16. ErrNilNetworksEnrollmentKey = errors.New("enrollment key networks is nil")
  17. ErrNilTagsEnrollmentKey = errors.New("enrollment key tags is nil")
  18. ErrInvalidEnrollmentKey = errors.New("enrollment key is not valid")
  19. ErrInvalidEnrollmentKeyValue = errors.New("enrollment key value is not valid")
  20. )
  21. // KeyType - the type of enrollment key
  22. type KeyType int
  23. // String - returns the string representation of a KeyType
  24. func (k KeyType) String() string {
  25. return [...]string{"Undefined", "TimeExpiration", "Uses", "Unlimited"}[k]
  26. }
  27. // EnrollmentToken - the tokenized version of an enrollmentkey;
  28. // to be used for host registration
  29. type EnrollmentToken struct {
  30. Server string `json:"server"`
  31. Value string `json:"value"`
  32. }
  33. // EnrollmentKeyLength - the length of an enrollment key - 62^16 unique possibilities
  34. const EnrollmentKeyLength = 32
  35. // EnrollmentKey - the key used to register hosts and join them to specific networks
  36. type EnrollmentKey struct {
  37. Expiration time.Time `json:"expiration"`
  38. UsesRemaining int `json:"uses_remaining"`
  39. Value string `json:"value"`
  40. Networks []string `json:"networks"`
  41. Unlimited bool `json:"unlimited"`
  42. Tags []string `json:"tags"`
  43. Token string `json:"token,omitempty"` // B64 value of EnrollmentToken
  44. Type KeyType `json:"type"`
  45. Relay uuid.UUID `json:"relay"`
  46. Groups []TagID `json:"groups"`
  47. Default bool `json:"default"`
  48. }
  49. // APIEnrollmentKey - used to create enrollment keys via API
  50. type APIEnrollmentKey struct {
  51. Expiration int64 `json:"expiration" swaggertype:"primitive,integer" format:"int64"`
  52. UsesRemaining int `json:"uses_remaining"`
  53. Networks []string `json:"networks"`
  54. Unlimited bool `json:"unlimited"`
  55. Tags []string `json:"tags" validate:"required,dive,min=3,max=32"`
  56. Type KeyType `json:"type"`
  57. Relay string `json:"relay"`
  58. Groups []TagID `json:"groups"`
  59. }
  60. // RegisterResponse - the response to a successful enrollment register
  61. type RegisterResponse struct {
  62. ServerConf ServerConfig `json:"server_config"`
  63. RequestedHost Host `json:"requested_host"`
  64. }
  65. // EnrollmentKey.IsValid - checks if the key is still valid to use
  66. func (k *EnrollmentKey) IsValid() bool {
  67. if k == nil {
  68. return false
  69. }
  70. if k.UsesRemaining > 0 {
  71. return true
  72. }
  73. if !k.Expiration.IsZero() && time.Now().Before(k.Expiration) {
  74. return true
  75. }
  76. if k.Type == Undefined {
  77. return false
  78. }
  79. return k.Unlimited
  80. }
  81. // EnrollmentKey.Validate - validate's an EnrollmentKey
  82. // should be used during creation
  83. func (k *EnrollmentKey) Validate() error {
  84. if k == nil {
  85. return ErrNilEnrollmentKey
  86. }
  87. if k.Tags == nil {
  88. return ErrNilTagsEnrollmentKey
  89. }
  90. if len(k.Value) != EnrollmentKeyLength {
  91. return fmt.Errorf("%w: length not %d characters", ErrInvalidEnrollmentKeyValue, EnrollmentKeyLength)
  92. }
  93. if !k.IsValid() {
  94. return fmt.Errorf("%w: uses remaining: %d, expiration: %s, unlimited: %t", ErrInvalidEnrollmentKey, k.UsesRemaining, k.Expiration, k.Unlimited)
  95. }
  96. return nil
  97. }