func (e roomsEndpoint) doWildcardJoin(req *http.Request, params httprouter.Params) interface{} { user, err := readAccessToken(e.userService, e.tokenService, req) if err != nil { return err } roomIdOrAlias := params[0].Value room, parseErr := ct.ParseRoomId(roomIdOrAlias) if parseErr != nil { alias, parseErr := ct.ParseAlias(roomIdOrAlias) if parseErr != nil { return types.BadParamError("invalid room id or alias: " + roomIdOrAlias) } room, err = e.roomService.LookupAlias(alias) if err != nil { return err } } content := types.MembershipEventContent{} content.Membership = types.MembershipMember _, err = e.roomService.SetState(room, user, &content, user.String()) if err != nil { return err } return struct{}{} }
func (e roomsEndpoint) doLeave(req *http.Request, params httprouter.Params) interface{} { room, user, err := e.getRoomAndUser(req, params) if err != nil { return err } content := types.MembershipEventContent{} content.Membership = types.MembershipLeaving state, err := e.roomService.SetState(room, user, &content, user.String()) if err != nil { return err } return eventIdResponse{state.EventId} }
func (s roomService) doMembershipChange( room ct.RoomId, caller ct.UserId, user ct.UserId, membership *types.MembershipEventContent, ) (*types.State, types.Error) { log.Printf("attempting membership change of %s in %s to %s, by %s", user, room, membership.Membership, caller) currentMembership, err := s.userMembership(room, user) if err != nil { return nil, err } if currentMembership == membership.Membership { return nil, types.ForbiddenError("membership change was a no-op") } membership.UserProfile = nil switch membership.Membership { case types.MembershipNone: if currentMembership != types.MembershipBanned { return nil, types.BadJsonError("invalid or missing membership in membership change") } err = s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int { return pl.Ban }) if err != nil { return nil, err } if user == caller { return nil, types.ForbiddenError("cannot remove a ban from self") } case types.MembershipInvited: if currentMembership != types.MembershipNone { return nil, types.ForbiddenError("could not invite user to room, already have membership '" + currentMembership.String() + "'") } ok, err := s.allowsJoinRule(room, types.JoinRuleInvite) if err != nil { return nil, err } if !ok { return nil, types.ForbiddenError("room does not allow join method: " + types.JoinRuleInvite.String()) } err = s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int { return pl.Invite }) if err != nil { return nil, err } case types.MembershipMember: switch currentMembership { case types.MembershipNone: ok, err := s.allowsJoinRule(room, types.JoinRulePublic) if err != nil { return nil, err } if !ok { return nil, types.ForbiddenError("room does not allow join method: " + types.JoinRuleInvite.String()) } case types.MembershipInvited: if user != caller { return nil, types.ForbiddenError("cannot force other users to join the room") } case types.MembershipKnocking: if user == caller { return nil, types.ForbiddenError("cannot let yourself in after knocking") } err = s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int { return pl.Invite }) if err != nil { return nil, err } case types.MembershipBanned: if user == caller { return nil, types.ForbiddenError("you are banned from that room") } else { return nil, types.ForbiddenError("that user is banned from this room") } } profile, err := s.profileProvider.Profile(caller) if err != nil { return nil, err } membership.UserProfile = &profile case types.MembershipKnocking: if user != caller { return nil, types.ForbiddenError("cannot force other users to knock") } if currentMembership != types.MembershipNone { return nil, types.ForbiddenError("could not knock on room, already have membership '" + currentMembership.String() + "'") } ok, err := s.allowsJoinRule(room, types.JoinRuleKnock) if err != nil { return nil, err } if !ok { return nil, types.ForbiddenError("room does not allow join method: " + types.JoinRuleKnock.String()) } case types.MembershipLeaving: if currentMembership == types.MembershipNone { return nil, types.ForbiddenError("tried to leave a room without current membership") } if currentMembership == types.MembershipBanned { return nil, types.ForbiddenError("tried to leave room with current membership '" + types.MembershipBanned.String() + "'") } if user != caller { err = s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int { return pl.Kick }) if err != nil { return nil, err } } case types.MembershipBanned: if user == caller { return nil, types.ForbiddenError("cannot ban self") } err = s.testPowerLevel(room, caller, func(pl *types.PowerLevelsEventContent) int { return pl.Ban }) if err != nil { return nil, err } } if membership.Membership == types.MembershipMember { if err := s.members.AddMember(room, user); err != nil { return nil, err } } else if currentMembership == types.MembershipMember { if err := s.members.RemoveMember(room, user); err != nil { return nil, err } } return s.setState(room, caller, membership, user.String()) }