Skip to content

Commit

Permalink
Add new SetHmacKeys API method
Browse files Browse the repository at this point in the history
  • Loading branch information
neekolas committed Mar 1, 2024
1 parent 47481e5 commit 62213b2
Show file tree
Hide file tree
Showing 20 changed files with 1,000 additions and 112 deletions.
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;
21 changes: 21 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,21 @@
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

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

0 comments on commit 62213b2

Please sign in to comment.