Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add devices validation #144

Merged
merged 1 commit into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: "1.18"
go-version: "1.19"

- uses: actions/checkout@v2

Expand All @@ -27,4 +27,4 @@ jobs:
STREAM_SECRET: ${{ secrets.STREAM_SECRET }}
run: |
go test -coverprofile cover.out -v -race ./...
go tool cover -func=cover.out
go tool cover -func=cover.out
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: '1.18'
go-version: '1.19'

- name: Tidy
run: go mod tidy -v && git diff --no-patch --exit-code || { git status; echo 'Unchecked diff, did you forget go mod tidy again?' ; false ; };
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: '1.18'
go-version: '1.19'

- run: |
git tag "${{ env.VERSION }}"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/reviewdog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: "1.18"
go-version: "1.19"

- name: Install golangci-lint
run:
Expand All @@ -30,4 +30,4 @@ jobs:
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run:
$(go env GOPATH)/bin/golangci-lint run --out-format line-number | reviewdog -f=golangci-lint -name=golangci-lint -reporter=github-pr-review
$(go env GOPATH)/bin/golangci-lint run --out-format line-number | reviewdog -f=golangci-lint -name=golangci-lint -reporter=github-pr-review
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
run:
go: '1.18'
go: '1.19'
yaziine marked this conversation as resolved.
Show resolved Hide resolved
deadline: 210s
timeout: 10m
skip-dirs:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NAME = stream-cli

GOLANGCI_VERSION = 1.45.0
GOLANGCI_VERSION = 1.49.0
GOLANGCI = .bin/golangci/$(GOLANGCI_VERSION)/golangci-lint
$(GOLANGCI):
@curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(dir $(GOLANGCI)) v$(GOLANGCI_VERSION)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/GetStream/stream-cli

go 1.18
go 1.19

require (
github.com/AlecAivazis/survey/v2 v2.3.4
Expand Down
25 changes: 25 additions & 0 deletions pkg/cmd/chat/imports/validator/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ type index struct {

// reactions
reactionPKs map[Bits256]struct{}

// devices
devicePKs map[Bits256]struct{}
}

func newIndex(roles map[string]*streamchat.Role, channelTypes map[string]*streamchat.ChannelType) *index {
Expand All @@ -84,6 +87,7 @@ func newIndex(roles map[string]*streamchat.Role, channelTypes map[string]*stream
messagePKsWithReaction: make(map[Bits256]struct{}),
messagePKsReplies: make(map[Bits256]struct{}),
reactionPKs: make(map[Bits256]struct{}),
devicePKs: make(map[Bits256]struct{}),
}
}

Expand All @@ -94,6 +98,7 @@ func (i *index) stats() map[string]int {
"members": len(i.memberPKs),
"messages": len(i.messagePKs),
"reactions": len(i.reactionPKs),
"devices": len(i.devicePKs),
}
}

Expand Down Expand Up @@ -302,3 +307,23 @@ func (i *index) addReaction(messageID, reactionType, userID string) error {

return nil
}

func getDevicePK(deviceID string) Bits256 {
return hashValues(deviceID)
}

func (i *index) deviceExist(deviceID string) bool {
pk := getDevicePK(deviceID)
_, ok := i.devicePKs[pk]
return ok
}

func (i *index) addDevice(deviceID string) error {
if i.deviceExist(deviceID) {
return fmt.Errorf("duplicate device id:%s", deviceID)
}

pk := getDevicePK(deviceID)
i.devicePKs[pk] = struct{}{}
return nil
}
98 changes: 90 additions & 8 deletions pkg/cmd/chat/imports/validator/items.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"strings"
"time"
"unicode/utf8"

streamchat "github.com/GetStream/stream-chat-go/v5"
)

var (
Expand All @@ -35,6 +37,8 @@ func newItem(rawItem *rawItem) (Item, error) {
return newMessageItem(rawItem.Item)
case "reaction":
return newReactionItem(rawItem.Item)
case "device":
return newDeviceItem(rawItem.Item)
default:
return nil, fmt.Errorf("invalid item type %q", rawItem.Type)
}
Expand Down Expand Up @@ -88,14 +92,20 @@ func newUserItem(itemBody json.RawMessage) (*userItem, error) {
}

type userItem struct {
ID string `json:"id"`
Role string `json:"role"`
Invisible bool `json:"invisible"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt time.Time `json:"deleted_at"`
Teams []string `json:"teams"`
Custom extraFields
ID string `json:"id"`
Role string `json:"role"`
Invisible bool `json:"invisible"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt time.Time `json:"deleted_at"`
Teams []string `json:"teams"`
PushNotifications pushNotification `json:"push_notifications"`
Custom extraFields
}

type pushNotification struct {
Disabled bool `json:"disabled"`
DisabledUntil *time.Time `json:"disabled_until"`
}

func (u *userItem) validateFields() error {
Expand Down Expand Up @@ -130,6 +140,78 @@ func (u *userItem) validateReferences(idx *index) error {
return nil
}

type deviceItem struct {
ID string `json:"id"`
UserID string `json:"user_id"`
CreatedAt time.Time `json:"created_at"`
Disabled bool `json:"disabled"`
DisabledReason string `json:"disabled_reason"`
PushProviderType string `json:"push_provider_type"`
PushProviderName string `json:"push_provider_name"`
}

func newDeviceItem(itemBody json.RawMessage) (*deviceItem, error) {
var device deviceItem
if err := unmarshalItem(itemBody, &device); err != nil {
return nil, err
}
return &device, nil
}

var pushProviders = []string{
streamchat.PushProviderFirebase,
streamchat.PushProviderHuawei,
streamchat.PushProviderAPNS,
streamchat.PushProviderXiaomi,
}

func (d *deviceItem) validateFields() error {
if d.ID == "" {
return errors.New("device.id required")
}
if len(d.ID) > 255 {
return errors.New("device.id max length exceeded (255)")
}

if d.UserID == "" {
return errors.New("device.user_id required")
}
if len(d.UserID) > 255 {
return errors.New("device.user_id max length exceeded (255)")
}

if d.CreatedAt.IsZero() {
return errors.New("device.created_at required")
}

if d.PushProviderType == "" {
return errors.New("device.push_provider_type required")
}
var found bool
for _, p := range pushProviders {
if d.PushProviderType == p {
found = true
break
}
}
if !found {
return fmt.Errorf("device.push_provider_type invalid, available options are: %s", strings.Join(pushProviders, ","))
}

return nil
}

func (d *deviceItem) index(i *index) error {
return i.addDevice(d.ID)
}

func (d *deviceItem) validateReferences(i *index) error {
if d.UserID != "" && !i.userExist(d.UserID) {
return fmt.Errorf("device.user_id %q doesn't exist", d.UserID)
}
return nil
}

var channelReservedFields = []string{
"last_message_at", "cid", "created_by_pk", "members", "config", "app_pk", "pk",
}
Expand Down
86 changes: 86 additions & 0 deletions pkg/cmd/chat/imports/validator/testdata/invalid-devices.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
[
{
"type": "user",
"item": {
"id": "userA",
"role": "user"
}
},
{
"type": "device",
"item": {
"id": "id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long-id-too-long",
"user_id": "userA",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "firebase"
}
},
{
"type": "device",
"item": {
"id": "123",
"user_id": "userB",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "firebase"
}
},
{
"type": "device",
"item": {
"user_id": "userA",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "firebase"
}
},
{
"type": "device",
"item": {
"id": "no user ID",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "firebase"
}
},
{
"type": "device",
"item": {
"id": "123",
"user_id": "userA",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "unknown_provider"
}
},
{
"type": "device",
"item": {
"id": "123",
"user_id": "userA",
"disabled": false,
"push_provider_type": "unknown_provider"
}
},
{
"type": "device",
"item": {
"id": "duplicate",
"user_id": "userA",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "apn"
}
},
{
"type": "device",
"item": {
"id": "duplicate",
"user_id": "userA",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "xiaomi"
}
}
]
32 changes: 30 additions & 2 deletions pkg/cmd/chat/imports/validator/testdata/valid-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
"teams": [
"teamA"
],
"foo": "bar"
"foo": "bar",
"push_notifications": {
"disabled": true,
"disabled_until": "2022-12-31T23:59:59Z"
}
}
},
{
Expand All @@ -17,7 +21,10 @@
"role": "user",
"teams": [
"teamB"
]
],
"push_notifications": {
"disabled": false
}
}
},
{
Expand Down Expand Up @@ -160,5 +167,26 @@
"user_id": "user3",
"created_at": "2022-01-01T01:01:01Z"
}
},
{
"type": "device",
"item": {
"id": "123",
"user_id": "user1",
"created_at": "2022-01-01T01:01:01Z",
"disabled": true,
"disabled_reason": "provider creds are not valid",
"push_provider_type": "xiaomi"
}
},
{
"type": "device",
"item": {
"id": "456",
"user_id": "user2",
"created_at": "2022-01-01T01:01:01Z",
"disabled": false,
"push_provider_type": "firebase"
}
}
]
Loading