Skip to content

Commit 8807345

Browse files
committed
Added ExpiresAt helper to certitifcate. Moved Subscription to SubscriptionInfo to match API. Applied feedback from the pull request.
1 parent ade7164 commit 8807345

File tree

4 files changed

+46
-20
lines changed

4 files changed

+46
-20
lines changed

pkg/registration/offline_certificate.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"io"
1010
"strings"
11+
"time"
1112
)
1213

1314
// The information extracted from an offline registration certificate
@@ -29,19 +30,19 @@ type OfflineCertificate struct {
2930
// not have the relevant information. Make sure to check if the key exists and prepare for
3031
// type casting if necessary.
3132
type OfflinePayload struct {
32-
Login string `json:"login"`
33-
Password string `json:"password"`
34-
Subscription Subscription `json:"subscription"`
35-
HashedRegcode string `json:"hashed_regcode"`
36-
HashedUUID string `json:"hashed_uuid"`
37-
Information map[string]any `json:"information"`
33+
Login string `json:"login"`
34+
Password string `json:"password"`
35+
SubscriptionInfo SubscriptionInfo `json:"subscription"`
36+
HashedRegcode string `json:"hashed_regcode"`
37+
HashedUUID string `json:"hashed_uuid"`
38+
Information map[string]any `json:"information"`
3839
}
3940

4041
// Reads an offline registration certificate from a read object
4142
//
4243
// An error indicates the certificate was probably malformed
4344
func OfflineCertificateFrom(reader io.Reader) (*OfflineCertificate, error) {
44-
certificate := OfflineCertificate{}
45+
certificate := &OfflineCertificate{}
4546

4647
raw, readErr := io.ReadAll(reader)
4748

@@ -55,17 +56,17 @@ func OfflineCertificateFrom(reader io.Reader) (*OfflineCertificate, error) {
5556
return nil, decodeErr
5657
}
5758

58-
if err := json.Unmarshal(decoded, &certificate); err != nil {
59+
if err := json.Unmarshal(decoded, certificate); err != nil {
5960
return nil, fmt.Errorf("json error: %s", err)
6061
}
6162

62-
return &certificate, nil
63+
return certificate, nil
6364
}
6465

6566
// Checks if the provided offline registration certificate is valid using
6667
// the public RSA key to validate the included signature
6768
func (cert *OfflineCertificate) IsValid() (bool, error) {
68-
key, keyErr := sCCPublicKey()
69+
key, keyErr := sccPublicKey()
6970

7071
if keyErr != nil {
7172
return false, keyErr
@@ -94,19 +95,19 @@ func (cert *OfflineCertificate) ExtractPayload() (*OfflinePayload, error) {
9495
return cert.OfflinePayload, nil
9596
}
9697

97-
payload := OfflinePayload{}
98+
payload := &OfflinePayload{}
9899
raw, decodeErr := decodeBase64([]byte(cert.EncodedPayload))
99100

100101
if decodeErr != nil {
101102
return nil, decodeErr
102103
}
103104

104-
if jsonErr := json.Unmarshal(raw, &payload); jsonErr != nil {
105+
if jsonErr := json.Unmarshal(raw, payload); jsonErr != nil {
105106
return nil, fmt.Errorf("json: %s", jsonErr)
106107
}
107108

108-
cert.OfflinePayload = &payload
109-
return &payload, nil
109+
cert.OfflinePayload = payload
110+
return payload, nil
110111
}
111112

112113
// Provides the signature encoded in the offline registration certificate which
@@ -150,10 +151,20 @@ func (cert *OfflineCertificate) ProductClassIncluded(name string) (bool, error)
150151
return false, extractErr
151152
}
152153

153-
for _, class := range payload.Subscription.ProductClasses {
154+
for _, class := range payload.SubscriptionInfo.ProductClasses {
154155
if class.Name == name {
155156
return true, nil
156157
}
157158
}
158159
return false, nil
159160
}
161+
162+
func (cert *OfflineCertificate) ExpiresAt() (time.Time, error) {
163+
payload, extractErr := cert.ExtractPayload()
164+
165+
if extractErr != nil {
166+
return time.Now(), extractErr
167+
}
168+
169+
return payload.SubscriptionInfo.ExpiresAt, nil
170+
}

pkg/registration/offline_certificate_test.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ func TestOfflineCertificateExtractPayloadSuccess(t *testing.T) {
8383

8484
rawCert := fixture(t, "pkg/registration/offline_certificate/valid.cert")
8585
reader := bytes.NewReader(rawCert)
86-
expectedExpirationDate := time.Date(2026, time.January, 27, 11, 53, 51, 223000000, time.UTC)
8786

8887
cert, err := registration.OfflineCertificateFrom(reader)
8988
assert.NoError(err)
@@ -93,8 +92,7 @@ func TestOfflineCertificateExtractPayloadSuccess(t *testing.T) {
9392

9493
assert.Equal("SCC_384deae18e324233b20de20c87b89df7", payload.Login)
9594
assert.Equal("https://rnch1.dev.company.net/index", payload.Information["server_url"].(string))
96-
assert.Equal("RANCHER-X86-ALPHA", payload.Subscription.ProductClasses[0].Name)
97-
assert.Equal(expectedExpirationDate, payload.Subscription.ExpiresAt)
95+
assert.Equal("RANCHER-X86-ALPHA", payload.SubscriptionInfo.ProductClasses[0].Name)
9896
}
9997

10098
func TestOfflineCertificateExtractPayloadInvalidJSON(t *testing.T) {
@@ -166,3 +164,20 @@ func TestOfflineCertificateProductClassIncluded(t *testing.T) {
166164
assert.True(shouldBeIncluded)
167165
assert.False(shouldNotBeIncluded)
168166
}
167+
168+
func TestOfflineCertificateExpireDate(t *testing.T) {
169+
assert := assert.New(t)
170+
171+
rawCert := fixture(t, "pkg/registration/offline_certificate/valid.cert")
172+
reader := bytes.NewReader(rawCert)
173+
174+
cert, readErr := registration.OfflineCertificateFrom(reader)
175+
assert.NoError(readErr)
176+
177+
expectedExpirationDate := time.Date(2026, time.January, 27, 11, 53, 51, 223000000, time.UTC)
178+
179+
expireDate, err := cert.ExpiresAt()
180+
assert.NoError(err)
181+
182+
assert.Equal(expectedExpirationDate, expireDate)
183+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package registration
33
import "time"
44

55
// A subscription used in the offline registration workflow
6-
type Subscription struct {
6+
type SubscriptionInfo struct {
77
Kind string `json:"kind"`
88
Name string `json:"name"`
99
StartsAt time.Time `json:"starts_at"`

pkg/registration/utilities.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func decodeBase64(input []byte) ([]byte, error) {
2929
return decoded[:size], nil
3030
}
3131

32-
func sCCPublicKey() (*rsa.PublicKey, error) {
32+
func sccPublicKey() (*rsa.PublicKey, error) {
3333
block, _ := pem.Decode(publicKey)
3434

3535
// PKCS#8 compatible

0 commit comments

Comments
 (0)