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 new SubscribeWithMetadata API method #30

Merged
merged 1 commit into from
Mar 12, 2024
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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"go.lintTool": "golangci-lint",
"go.lintFlags": ["--config=./dev/.golangci.yaml"]
"go.lintFlags": ["--fast", "--config=./dev/.golangci.yaml"]
}
19 changes: 19 additions & 0 deletions fixtures/envelopes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[
{
"kind": "v2-conversation",
"envelope": "0a502f786d74702f302f6d2d376433323232323932356239366361343339613862376230663933663231623661316563306665373966653432636136643534636164653135653263323765302f70726f746f10c0efebc8c295a3dc171af80412f5040a5c08c0efebc8c295a3dc1712502f786d74702f302f6d2d376433323232323932356239366361343339613862376230663933663231623661316563306665373966653432636136643534636164653135653263323765302f70726f746f12f0030aed030a201dee97828dbfed4768970bbd58b8445386994dcb5f9e4884f561aeca8fb37257120ca6c63e244cb94ec5522e4ca51aba032a46ba2cde18362bdd6e71b7bb3cae54d1a83a112d8087e804f0f23a392c81767def67a6bd96bf1869f71849cdc0f6a7c2ec76c411e6a0d097995feb834a258b1b0eafa873cdd81e722fd36c5ebfdc0c75eda606773db9d562eb1816123966d0d730947ff5003bce19ccc6c890254c7bd7afe7d2f3ebcb2561fc940dc99da9227d2372ac77030001fa12e303549f8bae0610fc8d133179adbce181dfb1fff630e9a9d8982d79323a688dac3ebd60f899b2a0a8614ce0e3a3feee81293638033b85f0495d84a3bd10e06c315c7016b662fe4bf277a9111adcda074a5f6a92f2108913be78d17ef982de8f8f6a261ec237e8c4e44964e297c79c8f3521d04436eafc46ed4f224156b152cff79787d1bb8b25c8b6d5cbee9262f8234067d4b7cea88b6c1b7caf23f8de9c7a6329449b19b45ed220d005fbc58cf76d6588b0ea352b257eba36e579b123c1c48b7e26846fad5e66b4059a18cecdab3d86eef0cd4a8f3343663aa0a924c1104ea78999a13b0f6ee6ede91dcdc94473f238d7e3dd6bd3e40fdab2f0dfb1d0b29d4a6ac1bbaaba14598f17aa40a7f8a1931ce79c481add157c73a9345986934868f9a3305171870780de1271b0a896e8a71a208acd62dae9ed5c2f7ecdbd9fbd1c14ccf0228af94cb8386f4dcd9ebace43ba952001",
"hmacKey": "ce3baf2fa9ce4ca617e30fa17f109f95ffd285101845d4f15b2a7b48b85e3779"
},
{
"kind": "v1-conversation",
"envelope": "0a662f786d74702f302f646d2d3078354437653035304635386336413235326534624443456635313637383465614262363536313231332d3078383135324632313466363138316666316230343862664246303333314165393930354436646231332f70726f746f10c0ccb1fbc295a3dc171adc050ad9050ae5040aaa020a9201089983e6c3df3112440a420a4041237f75422fe52a5599edc50c1123167d814f5f6fa969bf7b486d07371101ef54dfec71ddef639be5cafb9717357a7e588a705e62eab8043ea9ae77e96bf08d1a430a4104365cf010eaa7f63338f2252595007ea69489b9cbf736526dd7b1fbbfccd9aa28dbc5e5569ac78f9be005aa002c6e81b40d68b1f93decc418342902e025c35134129201089b83e6c3df3112440a420a403a46f3fd19ef7b04babb050675595a1da83ae39126d0d5cdc220c07b0df942df602ddd730cdbacccc390d42e924a8e0360a07cabe3ba285af783f148cc7ab7d11a430a4104208becd14fe7226c47bb3c1bfac605e087a5eac5af1fd346c07f65c887df6dc90e1a377aecb95017461c14ff939a3af68cce7773b598257deba5d8045374795812ae020a940108c4ffe5c3df3112460a440a40501acd07ae8bf4068aa5f9144c8ba6b0fbfeea8cdb46b2ed13f435a03d1cced576d6afe6505b1697b2d8f97ee1643c0e913307d00ccf39f7be55cb6aa25fb42d10011a430a410428a877eb7c8257359f8a4b1ac10927fa2cb10b342cdae46147b0f60fe22c3daa7b2554a57f7fefeb5a8815560db9b36815cbfbc08826f1c60a12d90c0e189cc212940108e1ffe5c3df3112460a440a403734434965ed7cdb60a1d0a89454a39dbc44ac8c3396193e3cd2b1b2e04eb20360d0c9a7fced46ca9160b230f09e3571663540decea8d9495512629eb5123b5710011a430a4104a6651d9765917f7e28eb113ed9e3408cd1101702feb26df9d95a7bea9bb930ec44f86acf92e545e43f007e0e063356fa19f626e38b4ad7f86522206b24a11b7a189188e6c3df31126f0a6d0a20c0672d1e14e88770d4a61614ee9f2a797c3b9ee53bcd3ef521981999378c7120120c07621fdab3ac2cbc3e6f78231a3b46ce78ff9878222e08426000ccb37fdcd5507bf995148308e4f375167ecb2bb738997664a3957304bcc14848828c46b1d6be7b5de3beb8b4ebb955"
},
{
"kind": "v2-invite",
"envelope": "0a3f2f786d74702f302f696e766974652d3078354437653035304635386336413235326534624443456635313637383465614262363536313231332f70726f746f10c0cca881c295a3dc171ab5060ab2060af0040ab2020a96010a4c08c4ffe5c3df311a430a410428a877eb7c8257359f8a4b1ac10927fa2cb10b342cdae46147b0f60fe22c3daa7b2554a57f7fefeb5a8815560db9b36815cbfbc08826f1c60a12d90c0e189cc2124612440a40501acd07ae8bf4068aa5f9144c8ba6b0fbfeea8cdb46b2ed13f435a03d1cced576d6afe6505b1697b2d8f97ee1643c0e913307d00ccf39f7be55cb6aa25fb42d10011296010a4c08e1ffe5c3df311a430a4104a6651d9765917f7e28eb113ed9e3408cd1101702feb26df9d95a7bea9bb930ec44f86acf92e545e43f007e0e063356fa19f626e38b4ad7f86522206b24a11b7a12460a440a403734434965ed7cdb60a1d0a89454a39dbc44ac8c3396193e3cd2b1b2e04eb20360d0c9a7fced46ca9160b230f09e3571663540decea8d9495512629eb5123b57100112ae020a94010a4c089983e6c3df311a430a4104365cf010eaa7f63338f2252595007ea69489b9cbf736526dd7b1fbbfccd9aa28dbc5e5569ac78f9be005aa002c6e81b40d68b1f93decc418342902e025c35134124412420a4041237f75422fe52a5599edc50c1123167d814f5f6fa969bf7b486d07371101ef54dfec71ddef639be5cafb9717357a7e588a705e62eab8043ea9ae77e96bf08d1294010a4c089b83e6c3df311a430a4104208becd14fe7226c47bb3c1bfac605e087a5eac5af1fd346c07f65c887df6dc90e1a377aecb95017461c14ff939a3af68cce7773b598257deba5d8045374795812440a420a403a46f3fd19ef7b04babb050675595a1da83ae39126d0d5cdc220c07b0df942df602ddd730cdbacccc390d42e924a8e0360a07cabe3ba285af783f148cc7ab7d118c0cca881c295a3dc1712bc010ab9010a200eea5c8214689486c512d4a6e1df7880ee6d670affb0e1a8ffe7c40f92078109120c350a743d91befd7da46255e01a8601fc82e6b54fcb1c55ebd59fb1abfc080427730b5e094bd0279948e50ed2de30beae92ecd58561686bb0d537d785881d393c9a5e8e9c2eba997f5181cee95551dc46893bcdfdfca2b71f2a3772607ffdc77e666154e43bfc59f8b8ed6704e7c7983ede18cf22f5fba59e67df11ec52ec33f8a076db9b11e610f2abf6977d7eb0af1bf58be53e2a"
},
{
"kind": "v1-intro",
"envelope": "0a3e2f786d74702f302f696e74726f2d3078354437653035304635386336413235326534624443456635313637383465614262363536313231332f70726f746f10c0ccb1fbc295a3dc171adc050ad9050ae5040aaa020a9201089983e6c3df3112440a420a4041237f75422fe52a5599edc50c1123167d814f5f6fa969bf7b486d07371101ef54dfec71ddef639be5cafb9717357a7e588a705e62eab8043ea9ae77e96bf08d1a430a4104365cf010eaa7f63338f2252595007ea69489b9cbf736526dd7b1fbbfccd9aa28dbc5e5569ac78f9be005aa002c6e81b40d68b1f93decc418342902e025c35134129201089b83e6c3df3112440a420a403a46f3fd19ef7b04babb050675595a1da83ae39126d0d5cdc220c07b0df942df602ddd730cdbacccc390d42e924a8e0360a07cabe3ba285af783f148cc7ab7d11a430a4104208becd14fe7226c47bb3c1bfac605e087a5eac5af1fd346c07f65c887df6dc90e1a377aecb95017461c14ff939a3af68cce7773b598257deba5d8045374795812ae020a940108c4ffe5c3df3112460a440a40501acd07ae8bf4068aa5f9144c8ba6b0fbfeea8cdb46b2ed13f435a03d1cced576d6afe6505b1697b2d8f97ee1643c0e913307d00ccf39f7be55cb6aa25fb42d10011a430a410428a877eb7c8257359f8a4b1ac10927fa2cb10b342cdae46147b0f60fe22c3daa7b2554a57f7fefeb5a8815560db9b36815cbfbc08826f1c60a12d90c0e189cc212940108e1ffe5c3df3112460a440a403734434965ed7cdb60a1d0a89454a39dbc44ac8c3396193e3cd2b1b2e04eb20360d0c9a7fced46ca9160b230f09e3571663540decea8d9495512629eb5123b5710011a430a4104a6651d9765917f7e28eb113ed9e3408cd1101702feb26df9d95a7bea9bb930ec44f86acf92e545e43f007e0e063356fa19f626e38b4ad7f86522206b24a11b7a189188e6c3df31126f0a6d0a20c0672d1e14e88770d4a61614ee9f2a797c3b9ee53bcd3ef521981999378c7120120c07621fdab3ac2cbc3e6f78231a3b46ce78ff9878222e08426000ccb37fdcd5507bf995148308e4f375167ecb2bb738997664a3957304bcc14848828c46b1d6be7b5de3beb8b4ebb955"
}
]
33 changes: 25 additions & 8 deletions mocks/Installations.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 64 additions & 14 deletions mocks/Subscriptions.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ func (s *ApiServer) Unsubscribe(
return connect.NewResponse(&emptypb.Empty{}), nil
}

func (s *ApiServer) SubscribeWithMetadata(ctx context.Context, req *connect.Request[proto.SubscribeWithMetadataRequest]) (*connect.Response[emptypb.Empty], error) {
return nil, nil
}

func convertDeliveryMechanism(mechanism *proto.DeliveryMechanism) *interfaces.DeliveryMechanism {
if mechanism == nil {
return nil
Expand All @@ -152,3 +156,23 @@ func convertDeliveryMechanism(mechanism *proto.DeliveryMechanism) *interfaces.De
return &interfaces.DeliveryMechanism{Kind: interfaces.FCM, Token: fcmToken}
}
}

// func convertHmacUpdates(protoUpdates []*proto.Subscription_HmacKey) (interfaces.HmacUpdates, error) {
// out := make(interfaces.HmacUpdates)
// for _, update := range protoUpdates {
// if update == nil {
// continue
// }
// if _, exists := out[update.Topic]; exists {
// return nil, fmt.Errorf("duplicate topic: %s", update.Topic)
// }
// for _, key := range update.HmacKey {
// out[update.Topic] = append(out[update.Topic], interfaces.HmacKey{
// ThirtyDayPeriodsSinceEpoch: int(key.ThirtyDayPeriodsSinceEpoch),
// Key: key.Key,
// })
// }
// }

// return out, nil
// }
13 changes: 13 additions & 0 deletions pkg/db/migrations/20240229061721_add-hmac-keys.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
SET statement_timeout = 0;

--bun:split

DROP TABLE subscription_hmac_keys;

--bun:split

ALTER TABLE subscriptions DROP COLUMN is_silent;

--bun:split

DROP INDEX CONCURRENTLY IF EXISTS subscriptions_installation_id_topic_idx;
30 changes: 30 additions & 0 deletions pkg/db/migrations/20240229061721_add-hmac-keys.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
SET statement_timeout = 0;

--bun:split

CREATE TABLE subscription_hmac_keys (
subscription_id INTEGER NOT NULL,
thirty_day_periods_since_epoch INTEGER NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
key BYTEA NOT NULL,
PRIMARY KEY (subscription_id, thirty_day_periods_since_epoch),
FOREIGN KEY (subscription_id) REFERENCES subscriptions(id) ON DELETE CASCADE
);

--bun:split

ALTER TABLE subscriptions ADD COLUMN is_silent BOOLEAN DEFAULT FALSE;

--bun:split
-- Ensure that no duplicate subscription rows exist before adding unique index
DELETE FROM subscriptions
WHERE id NOT IN (
SELECT MAX(id)
FROM subscriptions
GROUP BY installation_id, topic
);

--bun:split

CREATE UNIQUE INDEX CONCURRENTLY subscriptions_installation_id_topic_idx ON subscriptions (installation_id, topic);
21 changes: 16 additions & 5 deletions pkg/db/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,20 @@ type DeviceDeliveryMechanism struct {
type Subscription struct {
bun.BaseModel `bun:"table:subscriptions"`

Id int64 `bun:",pk,autoincrement"`
CreatedAt time.Time `bun:"created_at,notnull,default:current_timestamp"`
InstallationId string `bun:"installation_id,notnull"`
Topic string `bun:"topic,notnull"`
IsActive bool `bun:"is_active,notnull"`
Id int64 `bun:",pk,autoincrement"`
CreatedAt time.Time `bun:"created_at,notnull"`
InstallationId string `bun:"installation_id,notnull"`
Topic string `bun:"topic,notnull"`
IsActive bool `bun:"is_active,notnull"`
IsSilent bool `bun:"is_silent,notnull"`
HmacKeys []*SubscriptionHmacKeys `bun:"rel:has-many,join:id=subscription_id"`
}

type SubscriptionHmacKeys struct {
bun.BaseModel `bun:"table:subscription_hmac_keys"`
SubscriptionId int64 `bun:"subscription_id,notnull,pk"`
ThirtyDayPeriodsSinceEpoch int32 `bun:"thirty_day_periods_since_epoch,notnull,pk"`
Key []byte `bun:"key,notnull,type:bytea"`
CreatedAt time.Time `bun:"created_at,notnull"`
UpdatedAt time.Time `bun:"updated_at,notnull,default:current_timestamp"`
}
22 changes: 21 additions & 1 deletion pkg/interfaces/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ type Subscription struct {
InstallationId string
Topic string
IsActive bool
IsSilent bool
HmacKey *HmacKey
}

type SendRequest struct {
Expand All @@ -49,18 +51,36 @@ type SendRequest struct {
Message *v1.Envelope
}

type HmacKey struct {
ThirtyDayPeriodsSinceEpoch int
Key []byte
}

type SubscriptionInput struct {
Topic string
IsSilent bool
HmacKeys []HmacKey
}

type HmacUpdates map[string][]HmacKey

// Pluggable Installation Service interface
//
//go:generate mockery --dir ../interfaces --name Installations --output ../../mocks --outpkg mocks
type Installations interface {
Register(ctx context.Context, installation Installation) (*RegisterResponse, error)
Delete(ctx context.Context, installationId string) error
GetInstallations(ctx context.Context, installationIds []string) ([]Installation, error)
}

// This interface is not expected to be pluggable
//
//go:generate mockery --dir ../interfaces --name Subscriptions --output ../../mocks --outpkg mocks
type Subscriptions interface {
Subscribe(ctx context.Context, installationId string, topics []string) error
Unsubscribe(ctx context.Context, installationId string, topics []string) error
GetSubscriptions(ctx context.Context, topic string) ([]Subscription, error)
GetSubscriptions(ctx context.Context, topic string, thirtyDayPeriod int) ([]Subscription, error)
SubscribeWithMetadata(ctx context.Context, installationId string, subscriptions []SubscriptionInput) error
}

// Pluggable interface for sending push notifications
Expand Down
Loading
Loading