Skip to content

Commit 0fd36e7

Browse files
committed
refac: refactering subspace file to the implementation of cip
1 parent 7c78bf0 commit 0fd36e7

File tree

12 files changed

+959
-295
lines changed

12 files changed

+959
-295
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ jobs:
1818
with:
1919
go-version-file: ./go.mod
2020

21-
- run: go test ./... -tags=sonic
21+
- run: go test ./... -tags=sonic

cip/auth.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package cip
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
)
8+
9+
// Action represents the permission action type
10+
type Action uint8
11+
12+
const (
13+
ActionRead Action = 1 << iota // 1
14+
ActionWrite // 2
15+
ActionExecute // 4
16+
)
17+
18+
// AuthTag represents the auth tag structure
19+
type AuthTag struct {
20+
Action Action // Permission mask (1=read, 2=write, 4=execute)
21+
Key uint32 // Causality key ID
22+
Exp uint64 // Expiration clock value
23+
}
24+
25+
// NewAuthTag creates a new auth tag
26+
func NewAuthTag(action Action, key uint32, exp uint64) AuthTag {
27+
return AuthTag{
28+
Action: action,
29+
Key: key,
30+
Exp: exp,
31+
}
32+
}
33+
34+
// ParseAuthTag parses an auth tag string into an AuthTag struct
35+
func ParseAuthTag(authStr string) (AuthTag, error) {
36+
parts := strings.Split(authStr, ",")
37+
if len(parts) != 3 {
38+
return AuthTag{}, fmt.Errorf("invalid auth tag format: %s", authStr)
39+
}
40+
41+
var auth AuthTag
42+
for _, part := range parts {
43+
kv := strings.Split(part, "=")
44+
if len(kv) != 2 {
45+
return AuthTag{}, fmt.Errorf("invalid auth tag part: %s", part)
46+
}
47+
48+
switch kv[0] {
49+
case "action":
50+
action, err := strconv.ParseUint(kv[1], 10, 8)
51+
if err != nil {
52+
return AuthTag{}, fmt.Errorf("invalid action value: %s", kv[1])
53+
}
54+
auth.Action = Action(action)
55+
case "key":
56+
key, err := strconv.ParseUint(kv[1], 10, 32)
57+
if err != nil {
58+
return AuthTag{}, fmt.Errorf("invalid key value: %s", kv[1])
59+
}
60+
auth.Key = uint32(key)
61+
case "exp":
62+
exp, err := strconv.ParseUint(kv[1], 10, 64)
63+
if err != nil {
64+
return AuthTag{}, fmt.Errorf("invalid exp value: %s", kv[1])
65+
}
66+
auth.Exp = exp
67+
default:
68+
return AuthTag{}, fmt.Errorf("unknown auth tag field: %s", kv[0])
69+
}
70+
}
71+
72+
return auth, nil
73+
}
74+
75+
// String returns the string representation of an AuthTag
76+
func (a AuthTag) String() string {
77+
return fmt.Sprintf("action=%d,key=%d,exp=%d", a.Action, a.Key, a.Exp)
78+
}
79+
80+
// HasPermission checks if the auth tag has the specified permission
81+
func (a AuthTag) HasPermission(action Action) bool {
82+
return a.Action&action != 0
83+
}
84+
85+
// IsExpired checks if the auth tag is expired based on the current clock value
86+
func (a AuthTag) IsExpired(currentClock uint64) bool {
87+
return a.Exp <= currentClock
88+
}

cip/auth_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package cip
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestAuthTag(t *testing.T) {
10+
// Test creating a new auth tag
11+
auth := NewAuthTag(ActionRead|ActionWrite, 30300, 1000)
12+
assert.Equal(t, ActionRead|ActionWrite, auth.Action)
13+
assert.Equal(t, uint32(30300), auth.Key)
14+
assert.Equal(t, uint64(1000), auth.Exp)
15+
16+
// Test permission checks
17+
assert.True(t, auth.HasPermission(ActionRead))
18+
assert.True(t, auth.HasPermission(ActionWrite))
19+
assert.False(t, auth.HasPermission(ActionExecute))
20+
21+
// Test expiration
22+
assert.False(t, auth.IsExpired(999))
23+
assert.True(t, auth.IsExpired(1000))
24+
assert.True(t, auth.IsExpired(1001))
25+
26+
// Test string representation
27+
assert.Equal(t, "action=3,key=30300,exp=1000", auth.String())
28+
}
29+
30+
func TestParseAuthTag(t *testing.T) {
31+
// Valid cases
32+
validTags := []string{
33+
"action=1,key=30300,exp=1000",
34+
"action=2,key=30301,exp=2000",
35+
"action=3,key=30302,exp=3000",
36+
"action=4,key=30303,exp=4000",
37+
"action=7,key=30304,exp=5000",
38+
}
39+
for _, tag := range validTags {
40+
auth, err := ParseAuthTag(tag)
41+
assert.NoError(t, err)
42+
assert.NotNil(t, auth)
43+
}
44+
45+
// Invalid cases
46+
invalidTags := []string{
47+
"", // empty
48+
"action=1", // missing fields
49+
"action=1,key=30300", // missing exp
50+
"action=1,key=30300,exp=1000,extra=value", // extra field
51+
"action=invalid,key=30300,exp=1000", // invalid action
52+
"action=1,key=invalid,exp=1000", // invalid key
53+
"action=1,key=30300,exp=invalid", // invalid exp
54+
"action=1,key=30300,exp=1000,", // trailing comma
55+
",action=1,key=30300,exp=1000", // leading comma
56+
}
57+
for _, tag := range invalidTags {
58+
_, err := ParseAuthTag(tag)
59+
assert.Error(t, err)
60+
}
61+
}

0 commit comments

Comments
 (0)