From 414ea314a6068a2444eefc689ac4ae0c7150f4d4 Mon Sep 17 00:00:00 2001 From: Kegsay Date: Fri, 10 Mar 2017 17:54:17 +0000 Subject: [PATCH] Update gomatrixserverlib and use AuthEventProvider (#35) --- .../dendrite/clientapi/writers/createroom.go | 27 +----- .../dendrite/roomserver/input/authevents.go | 10 +-- vendor/manifest | 2 +- .../matrix-org/gomatrixserverlib/eventauth.go | 85 +++++++++++++++---- .../gomatrixserverlib/eventauth_test.go | 43 ++++++++++ .../gomatrixserverlib/eventcontent.go | 8 +- 6 files changed, 125 insertions(+), 50 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go b/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go index 77c112c28..790fd5989 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/createroom.go @@ -151,7 +151,7 @@ func createRoom(req *http.Request, cfg config.ClientAPI, roomID string, producer // TODO m.room.aliases } - authEvents := authEventProvider{builtEventMap} + authEvents := gomatrixserverlib.NewAuthEvents(nil) for i, e := range eventsToMake { depth := i + 1 // depth starts at 1 @@ -178,6 +178,7 @@ func createRoom(req *http.Request, cfg config.ClientAPI, roomID string, producer // Add the event to the list of auth events builtEventMap[common.StateKeyTuple{e.Type, e.StateKey}] = ev builtEvents = append(builtEvents, ev) + authEvents.AddEvent(ev) } // send events to the room server @@ -280,27 +281,3 @@ func eventsToMessages(events []*gomatrixserverlib.Event, topic string) ([]*saram } return msgs, nil } - -type authEventProvider struct { - events map[common.StateKeyTuple]*gomatrixserverlib.Event -} - -func (a *authEventProvider) Create() (ev *gomatrixserverlib.Event, err error) { - return a.events[common.StateKeyTuple{"m.room.create", ""}], nil -} - -func (a *authEventProvider) JoinRules() (ev *gomatrixserverlib.Event, err error) { - return a.events[common.StateKeyTuple{"m.room.join_rules", ""}], nil -} - -func (a *authEventProvider) PowerLevels() (ev *gomatrixserverlib.Event, err error) { - return a.events[common.StateKeyTuple{"m.room.power_levels", ""}], nil -} - -func (a *authEventProvider) Member(stateKey string) (ev *gomatrixserverlib.Event, err error) { - return a.events[common.StateKeyTuple{"m.room.member", stateKey}], nil -} - -func (a *authEventProvider) ThirdPartyInvite(stateKey string) (ev *gomatrixserverlib.Event, err error) { - return a.events[common.StateKeyTuple{"m.room.third_party_invite", stateKey}], nil -} diff --git a/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go b/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go index 7dcaca915..f2c7dc0fb 100644 --- a/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go +++ b/src/github.com/matrix-org/dendrite/roomserver/input/authevents.go @@ -44,27 +44,27 @@ type authEvents struct { events eventMap } -// Create implements gomatrixserverlib.AuthEvents +// Create implements gomatrixserverlib.AuthEventProvider func (ae *authEvents) Create() (*gomatrixserverlib.Event, error) { return ae.lookupEventWithEmptyStateKey(types.MRoomCreateNID), nil } -// PowerLevels implements gomatrixserverlib.AuthEvents +// PowerLevels implements gomatrixserverlib.AuthEventProvider func (ae *authEvents) PowerLevels() (*gomatrixserverlib.Event, error) { return ae.lookupEventWithEmptyStateKey(types.MRoomPowerLevelsNID), nil } -// JoinRules implements gomatrixserverlib.AuthEvents +// JoinRules implements gomatrixserverlib.AuthEventProvider func (ae *authEvents) JoinRules() (*gomatrixserverlib.Event, error) { return ae.lookupEventWithEmptyStateKey(types.MRoomJoinRulesNID), nil } -// Memmber implements gomatrixserverlib.AuthEvents +// Memmber implements gomatrixserverlib.AuthEventProvider func (ae *authEvents) Member(stateKey string) (*gomatrixserverlib.Event, error) { return ae.lookupEvent(types.MRoomMemberNID, stateKey), nil } -// ThirdPartyInvite implements gomatrixserverlib.AuthEvents +// ThirdPartyInvite implements gomatrixserverlib.AuthEventProvider func (ae *authEvents) ThirdPartyInvite(stateKey string) (*gomatrixserverlib.Event, error) { return ae.lookupEvent(types.MRoomThirdPartyInviteNID, stateKey), nil } diff --git a/vendor/manifest b/vendor/manifest index 5435122fa..f252c6a3b 100644 --- a/vendor/manifest +++ b/vendor/manifest @@ -92,7 +92,7 @@ { "importpath": "github.com/matrix-org/gomatrixserverlib", "repository": "https://github.com/matrix-org/gomatrixserverlib", - "revision": "4218890fdd60e73cc5539ec40b86fd51568f4a19", + "revision": "131b3e83fe053bc40f6909226b8c3c1d186799c1", "branch": "master" }, { diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth.go index 913e652a9..523c0c939 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth.go @@ -160,21 +160,76 @@ func thirdPartyInviteToken(thirdPartyInviteData rawJSON) (string, error) { return thirdPartyInvite.Signed.Token, nil } -// AuthEvents are the state events needed to authenticate an event. -type AuthEvents interface { - // Create returns the m.room.create event for the room. +// AuthEventProvider provides auth_events for the authentication checks. +type AuthEventProvider interface { + // Create returns the m.room.create event for the room or nil if there isn't a m.room.create event. Create() (*Event, error) - // JoinRules returns the m.room.join_rules event for the room. + // JoinRules returns the m.room.join_rules event for the room or nil if there isn't a m.room.join_rules event. JoinRules() (*Event, error) - // PowerLevels returns the m.room.power_levels event for the room. + // PowerLevels returns the m.room.power_levels event for the room or nil if there isn't a m.room.power_levels event. PowerLevels() (*Event, error) - // Member returns the m.room.member event for the given user_id state_key. + // Member returns the m.room.member event for the given user_id state_key or nil if there isn't a m.room.member event. Member(stateKey string) (*Event, error) // ThirdPartyInvite returns the m.room.third_party_invite event for the - // given state_key + // given state_key or nil if there isn't a m.room.third_party_invite event ThirdPartyInvite(stateKey string) (*Event, error) } +type stateKeyTuple struct { + Type string + StateKey string +} + +// AuthEvents is an implementation of AuthEventProvider backed by a map. +type AuthEvents struct { + events map[stateKeyTuple]*Event +} + +// AddEvent adds an event to the provider. If an event already existed for the (type, state_key) then +// the event is replaced with the new event. Only returns an error if the event is not a state event. +func (a *AuthEvents) AddEvent(event *Event) error { + if event.StateKey() == nil { + return fmt.Errorf("AddEvent: event %s does not have a state key", event.Type()) + } + a.events[stateKeyTuple{event.Type(), *event.StateKey()}] = event + return nil +} + +// Create implements AuthEventProvider +func (a *AuthEvents) Create() (*Event, error) { + return a.events[stateKeyTuple{"m.room.create", ""}], nil +} + +// JoinRules implements AuthEventProvider +func (a *AuthEvents) JoinRules() (*Event, error) { + return a.events[stateKeyTuple{"m.room.join_rules", ""}], nil +} + +// PowerLevels implements AuthEventProvider +func (a *AuthEvents) PowerLevels() (*Event, error) { + return a.events[stateKeyTuple{"m.room.power_levels", ""}], nil +} + +// Member implements AuthEventProvider +func (a *AuthEvents) Member(stateKey string) (*Event, error) { + return a.events[stateKeyTuple{"m.room.member", stateKey}], nil +} + +// ThirdPartyInvite implements AuthEventProvider +func (a *AuthEvents) ThirdPartyInvite(stateKey string) (*Event, error) { + return a.events[stateKeyTuple{"m.room.third_party_invite", stateKey}], nil +} + +// NewAuthEvents returns an AuthEventProvider backed by the given events. New events can be added by +// calling AddEvent(). +func NewAuthEvents(events []*Event) AuthEvents { + a := AuthEvents{make(map[stateKeyTuple]*Event)} + for _, e := range events { + a.AddEvent(e) + } + return a +} + // A NotAllowed error is returned if an event does not pass the auth checks. type NotAllowed struct { Message string @@ -191,7 +246,7 @@ func errorf(message string, args ...interface{}) error { // Allowed checks whether an event is allowed by the auth events. // It returns a NotAllowed error if the event is not allowed. // If there was an error loading the auth events then it returns that error. -func Allowed(event Event, authEvents AuthEvents) error { +func Allowed(event Event, authEvents AuthEventProvider) error { switch event.Type() { case "m.room.create": return createEventAllowed(event) @@ -233,7 +288,7 @@ func createEventAllowed(event Event) error { // memberEventAllowed checks whether the m.room.member event is allowed. // Membership events have different authentication rules to ordinary events. -func memberEventAllowed(event Event, authEvents AuthEvents) error { +func memberEventAllowed(event Event, authEvents AuthEventProvider) error { allower, err := newMembershipAllower(authEvents, event) if err != nil { return err @@ -243,7 +298,7 @@ func memberEventAllowed(event Event, authEvents AuthEvents) error { // aliasEventAllowed checks whether the m.room.aliases event is allowed. // Alias events have different authentication rules to ordinary events. -func aliasEventAllowed(event Event, authEvents AuthEvents) error { +func aliasEventAllowed(event Event, authEvents AuthEventProvider) error { // The alias events have different auth rules to ordinary events. // In particular we allow any server to send a m.room.aliases event without checking if the sender is in the room. // This allows server admins to update the m.room.aliases event for their server when they change the aliases on their server. @@ -278,7 +333,7 @@ func aliasEventAllowed(event Event, authEvents AuthEvents) error { // powerLevelsEventAllowed checks whether the m.room.power_levels event is allowed. // It returns an error if the event is not allowed or if there was a problem // loading the auth events needed. -func powerLevelsEventAllowed(event Event, authEvents AuthEvents) error { +func powerLevelsEventAllowed(event Event, authEvents AuthEventProvider) error { allower, err := newEventAllower(authEvents, event.Sender()) if err != nil { return err @@ -492,7 +547,7 @@ func checkUserLevels(senderLevel int64, senderID string, oldPowerLevels, newPowe // redactEventAllowed checks whether the m.room.redaction event is allowed. // It returns an error if the event is not allowed or if there was a problem // loading the auth events needed. -func redactEventAllowed(event Event, authEvents AuthEvents) error { +func redactEventAllowed(event Event, authEvents AuthEventProvider) error { allower, err := newEventAllower(authEvents, event.Sender()) if err != nil { return err @@ -542,7 +597,7 @@ func redactEventAllowed(event Event, authEvents AuthEvents) error { // checks for events. // It returns an error if the event is not allowed or if there was a // problem loading the auth events needed. -func defaultEventAllowed(event Event, authEvents AuthEvents) error { +func defaultEventAllowed(event Event, authEvents AuthEventProvider) error { allower, err := newEventAllower(authEvents, event.Sender()) if err != nil { return err @@ -564,7 +619,7 @@ type eventAllower struct { // newEventAllower loads the information needed to authorise an event sent // by a given user ID from the auth events. -func newEventAllower(authEvents AuthEvents, senderID string) (e eventAllower, err error) { +func newEventAllower(authEvents AuthEventProvider, senderID string) (e eventAllower, err error) { if e.create, err = newCreateContentFromAuthEvents(authEvents); err != nil { return } @@ -646,7 +701,7 @@ type membershipAllower struct { // newMembershipAllower loads the information needed to authenticate the m.room.member event // from the auth events. -func newMembershipAllower(authEvents AuthEvents, event Event) (m membershipAllower, err error) { +func newMembershipAllower(authEvents AuthEventProvider, event Event) (m membershipAllower, err error) { stateKey := event.StateKey() if stateKey == nil { err = errorf("m.room.member must be a state event") diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth_test.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth_test.go index 71822e6d9..ca11c42e7 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth_test.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/eventauth_test.go @@ -844,3 +844,46 @@ func TestRedactAllowed(t *testing.T) { }] }`) } + +func TestAuthEvents(t *testing.T) { + power, err := NewEventFromTrustedJSON(rawJSON(`{ + "type": "m.room.power_levels", + "state_key": "", + "sender": "@u1:a", + "room_id": "!r1:a", + "event_id": "$e5:a", + "content": { + "users": { + "@u1:a": 100 + }, + "redact": 100 + } + }`), false) + if err != nil { + t.Fatalf("TestAuthEvents: failed to create power_levels event: %s", err) + } + a := NewAuthEvents([]*Event{&power}) + var e *Event + if e, err = a.PowerLevels(); err != nil || e != &power { + t.Errorf("TestAuthEvents: failed to get same power_levels event") + } + create, err := NewEventFromTrustedJSON(rawJSON(`{ + "type": "m.room.create", + "state_key": "", + "sender": "@u1:a", + "room_id": "!r1:a", + "event_id": "$e1:a", + "content": { + "creator": "@u1:a" + } + }`), false) + if err != nil { + t.Fatalf("TestAuthEvents: failed to create create event: %s", err) + } + if err = a.AddEvent(&create); err != nil { + t.Errorf("TestAuthEvents: Failed to AddEvent: %s", err) + } + if e, err = a.Create(); err != nil || e != &create { + t.Errorf("TestAuthEvents: failed to get same create event") + } +} diff --git a/vendor/src/github.com/matrix-org/gomatrixserverlib/eventcontent.go b/vendor/src/github.com/matrix-org/gomatrixserverlib/eventcontent.go index c355f8b7a..97f9316b2 100644 --- a/vendor/src/github.com/matrix-org/gomatrixserverlib/eventcontent.go +++ b/vendor/src/github.com/matrix-org/gomatrixserverlib/eventcontent.go @@ -39,7 +39,7 @@ type createContent struct { // newCreateContentFromAuthEvents loads the create event content from the create event in the // auth events. -func newCreateContentFromAuthEvents(authEvents AuthEvents) (c createContent, err error) { +func newCreateContentFromAuthEvents(authEvents AuthEventProvider) (c createContent, err error) { var createEvent *Event if createEvent, err = authEvents.Create(); err != nil { return @@ -113,7 +113,7 @@ type memberContent struct { // newMemberContentFromAuthEvents loads the member content from the member event for the user ID in the auth events. // Returns an error if there was an error loading the member event or parsing the event content. -func newMemberContentFromAuthEvents(authEvents AuthEvents, userID string) (c memberContent, err error) { +func newMemberContentFromAuthEvents(authEvents AuthEventProvider, userID string) (c memberContent, err error) { var memberEvent *Event if memberEvent, err = authEvents.Member(userID); err != nil { return @@ -146,7 +146,7 @@ type joinRuleContent struct { // newJoinRuleContentFromAuthEvents loads the join rule content from the join rules event in the auth event. // Returns an error if there was an error loading the join rule event or parsing the content. -func newJoinRuleContentFromAuthEvents(authEvents AuthEvents) (c joinRuleContent, err error) { +func newJoinRuleContentFromAuthEvents(authEvents AuthEventProvider) (c joinRuleContent, err error) { var joinRulesEvent *Event if joinRulesEvent, err = authEvents.JoinRules(); err != nil { return @@ -210,7 +210,7 @@ func (c *powerLevelContent) eventLevel(eventType string, isState bool) int64 { // newPowerLevelContentFromAuthEvents loads the power level content from the // power level event in the auth events or returns the default values if there // is no power level event. -func newPowerLevelContentFromAuthEvents(authEvents AuthEvents, creatorUserID string) (c powerLevelContent, err error) { +func newPowerLevelContentFromAuthEvents(authEvents AuthEventProvider, creatorUserID string) (c powerLevelContent, err error) { powerLevelsEvent, err := authEvents.PowerLevels() if err != nil { return