Skip to content

Commit

Permalink
Fix presence authorization + fix receiving presence events with an ex…
Browse files Browse the repository at this point in the history
…tension key.
  • Loading branch information
Florimond committed May 1, 2020
1 parent f0e507e commit cc90508
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 31 deletions.
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"appveyor.yml": true,
"Dockerfile": true
},
"editor.fontFamily": "Fira Code",
"editor.fontLigatures": true,
"go.formatTool": "gofmt",
"go.formatFlags": [
Expand Down
34 changes: 11 additions & 23 deletions internal/broker/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,38 +406,28 @@ func (c *Conn) onPresence(payload []byte) (response, bool) {
if err := json.Unmarshal(payload, &msg); err != nil {
return errors.ErrBadRequest, false
}

// Attempt to parse the key, this should be a master key
key, err := c.keys.DecryptKey(msg.Key)
if err != nil || !key.HasPermission(security.AllowPresence) || key.IsExpired() {
return errors.ErrUnauthorized, false
}

// Attempt to fetch the contract using the key. Underneath, it's cached.
contract, contractFound := c.service.contracts.Get(key.Contract())
if !contractFound {
return errors.ErrNotFound, false
}

// Validate the contract
if !contract.Validate(key) {
return errors.ErrUnauthorized, false
}

// Ensure we have trailing slash
if !strings.HasSuffix(msg.Channel, "/") {
msg.Channel = msg.Channel + "/"
}

// Parse the channel
channel := security.ParseChannel([]byte("emitter/" + msg.Channel))
channel := security.ParseChannel([]byte(msg.Key + "/" + msg.Channel))
if channel.ChannelType == security.ChannelInvalid {
return errors.ErrBadRequest, false
}
// Check the authorization and permissions
_, key, allowed := c.service.authorize(channel, security.AllowPresence)
if !allowed {
return errors.ErrUnauthorized, false
}

// Keys which are supposed to be extended should not be used for presence
if key.HasPermission(security.AllowExtend) {
return errors.ErrUnauthorizedExt, false
}

// Create the ssid for the presence
ssid := message.NewSsid(key.Contract(), channel.Query)

// Check if the client is interested in subscribing/unsubscribing from changes.
if msg.Changes != nil {
if *msg.Changes {
Expand All @@ -446,12 +436,10 @@ func (c *Conn) onPresence(payload []byte) (response, bool) {
c.Unsubscribe(message.NewSsidForPresence(ssid), nil)
}
}

// If we requested a status, populate the slice via scatter/gather.
now := time.Now().UTC().Unix()
who := make([]presenceInfo, 0, 4)
if msg.Status {

// Gather local & cluster presence
who = append(who, getAllPresence(c.service, ssid)...)
return &presenceResponse{
Expand Down
22 changes: 15 additions & 7 deletions internal/broker/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ func TestHandlers_onPresence(t *testing.T) {
// TODO :
// - valid key for the right channel, but no presence right.
// - test Who
license, _ := license.Parse(testLicense)
license, _ := license.Parse(testLicenseV2)
tests := []struct {
channel string
payload string
Expand All @@ -371,7 +371,7 @@ func TestHandlers_onPresence(t *testing.T) {
}{
{
channel: "emitter/presence/",
payload: "{\"key\":\"VfW_Cv5wWVZPHgCvLwJAuU2bgRFKXQEY\",\"channel\":\"a\",\"status\":true}",
payload: "{\"key\":\"hw7Jv3TMhYTg6lLk2fQoSvs2EP3gjFPk\",\"channel\":\"a\",\"status\":true}",
contractValid: true,
contractFound: true,
success: true,
Expand All @@ -390,7 +390,7 @@ func TestHandlers_onPresence(t *testing.T) {
},
{
channel: "emitter/presence/",
payload: "{\"key\":\"VfW_Cv5wWVZPHgCvLwJAuU2bgRFKXQEY\",\"channel\":\"a+b\",\"status\":true}",
payload: "{\"key\":\"hw7Jv3TMhYTg6lLk2fQoSvs2EP3gjFPk\",\"channel\":\"a+b\",\"status\":true}",
contractValid: true,
contractFound: true,
success: false,
Expand All @@ -399,7 +399,7 @@ func TestHandlers_onPresence(t *testing.T) {
},
{
channel: "emitter/presence/",
payload: "{\"key\":\"0Nq8SWbL8qoOKEDqh_ebBZRqJDby30m\",\"channel\":\"a\",\"status\":true}",
payload: "{\"key\":\"07XJv3TMhYTg6lLk2fQoSift1AbgjFPk\",\"channel\":\"a\",\"status\":true}",
contractValid: true,
contractFound: true,
success: false,
Expand All @@ -408,20 +408,28 @@ func TestHandlers_onPresence(t *testing.T) {
},
{
channel: "emitter/presence/",
payload: "{\"key\":\"VfW_Cv5wWVZPHgCvLwJAuU2bgRFKXQEY\",\"channel\":\"a+b\",\"status\":true}",
err: errors.ErrNotFound,
payload: "{\"key\":\"hw7Jv3TMhYTg6lLk2fQoSvs2EP3gjFPk\",\"channel\":\"a\",\"status\":true}",
err: errors.ErrUnauthorized,
contractValid: true,
contractFound: false,
msg: "Contract not found case",
},
{
channel: "emitter/presence/",
payload: "{\"key\":\"VfW_Cv5wWVZPHgCvLwJAuU2bgRFKXQEY\",\"channel\":\"a+b\",\"status\":true}",
payload: "{\"key\":\"hw7Jv3TMhYTg6lLk2fQoSvs2EP3gjFPk\",\"channel\":\"a\",\"status\":true}",
err: errors.ErrUnauthorized,
contractValid: false,
contractFound: true,
msg: "Contract is invalid case",
},
{
channel: "emitter/presence/",
payload: "{\"key\":\"sVTJv3TMhYTg6lLk2fQoCvs2EP3gjFPk\",\"channel\":\"a\",\"status\":true}",
err: errors.ErrUnauthorizedExt,
contractValid: true,
contractFound: true,
msg: "Extended key is unauthorized case",
},
}

for _, tc := range tests {
Expand Down

0 comments on commit cc90508

Please sign in to comment.