Allow server admin to get admin bit in room
parent
34226ec761
commit
ae67ff7a37
|
@ -14,9 +14,9 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
import logging
|
import logging
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import List, Optional
|
from typing import TYPE_CHECKING, List, Optional
|
||||||
|
|
||||||
from synapse.api.constants import EventTypes, JoinRules
|
from synapse.api.constants import EventTypes, JoinRules, Membership
|
||||||
from synapse.api.errors import Codes, NotFoundError, SynapseError
|
from synapse.api.errors import Codes, NotFoundError, SynapseError
|
||||||
from synapse.http.servlet import (
|
from synapse.http.servlet import (
|
||||||
RestServlet,
|
RestServlet,
|
||||||
|
@ -34,6 +34,9 @@ from synapse.rest.admin._base import (
|
||||||
from synapse.storage.databases.main.room import RoomSortOrder
|
from synapse.storage.databases.main.room import RoomSortOrder
|
||||||
from synapse.types import RoomAlias, RoomID, UserID, create_requester
|
from synapse.types import RoomAlias, RoomID, UserID, create_requester
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from synapse.server import HomeServer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,3 +341,97 @@ class JoinRoomAliasServlet(RestServlet):
|
||||||
)
|
)
|
||||||
|
|
||||||
return 200, {"room_id": room_id}
|
return 200, {"room_id": room_id}
|
||||||
|
|
||||||
|
|
||||||
|
class MakeRoomAdminRoomServlet(RestServlet):
|
||||||
|
PATTERNS = admin_patterns("/make_room_admin/(?P<room_identifier>[^/]*)")
|
||||||
|
|
||||||
|
def __init__(self, hs: "HomeServer"):
|
||||||
|
self.hs = hs
|
||||||
|
self.auth = hs.get_auth()
|
||||||
|
self.room_member_handler = hs.get_room_member_handler()
|
||||||
|
self.event_creation_handler = hs.get_event_creation_handler()
|
||||||
|
self.state_handler = hs.get_state_handler()
|
||||||
|
self.is_mine_id = hs.is_mine_id
|
||||||
|
|
||||||
|
async def on_POST(self, request, room_identifier):
|
||||||
|
requester = await self.auth.get_user_by_req(request)
|
||||||
|
await assert_user_is_admin(self.auth, requester.user)
|
||||||
|
content = parse_json_object_from_request(request, allow_empty_body=True)
|
||||||
|
|
||||||
|
if RoomID.is_valid(room_identifier):
|
||||||
|
room_id = room_identifier
|
||||||
|
elif RoomAlias.is_valid(room_identifier):
|
||||||
|
room_alias = RoomAlias.from_string(room_identifier)
|
||||||
|
room_id, _ = await self.room_member_handler.lookup_room_alias(room_alias)
|
||||||
|
room_id = room_id.to_string()
|
||||||
|
else:
|
||||||
|
raise SynapseError(
|
||||||
|
400, "%s was not legal room ID or room alias" % (room_identifier,)
|
||||||
|
)
|
||||||
|
|
||||||
|
user_to_add = content.get("user_id", requester.user.to_string())
|
||||||
|
|
||||||
|
room_state = await self.state_handler.get_current_state(room_id)
|
||||||
|
|
||||||
|
if not room_state:
|
||||||
|
raise SynapseError(400, "Server not in room")
|
||||||
|
|
||||||
|
create_event = room_state[(EventTypes.Create, "")]
|
||||||
|
power_levels = room_state.get((EventTypes.PowerLevels, ""))
|
||||||
|
|
||||||
|
if power_levels is not None:
|
||||||
|
admin_users = [
|
||||||
|
user_id
|
||||||
|
for user_id, power in power_levels.content.get("users")
|
||||||
|
if self.is_mine_id(user_id)
|
||||||
|
]
|
||||||
|
admin_users.sort(key=lambda user: power_levels.content.get("users")[user])
|
||||||
|
|
||||||
|
admin_user_id = admin_users[-1]
|
||||||
|
|
||||||
|
pl_content = power_levels.content
|
||||||
|
else:
|
||||||
|
admin_user_id = create_event.sender
|
||||||
|
if not self.is_mine_id(admin_user_id):
|
||||||
|
raise SynapseError(400, "No local admin user in room")
|
||||||
|
|
||||||
|
fake_requester = create_requester(
|
||||||
|
admin_user_id, authenticated_entity=requester.authenticated_entity,
|
||||||
|
)
|
||||||
|
|
||||||
|
new_pl_content = dict(pl_content)
|
||||||
|
new_pl_content["users"] = dict(pl_content.get("users", {}))
|
||||||
|
new_pl_content["users"][user_to_add] = new_pl_content["users"][admin_user_id]
|
||||||
|
|
||||||
|
await self.event_creation_handler.create_and_send_nonmember_event(
|
||||||
|
fake_requester, event_dict=new_pl_content,
|
||||||
|
)
|
||||||
|
|
||||||
|
member_event = room_state.get((EventTypes.Member, user_to_add))
|
||||||
|
is_joined = False
|
||||||
|
if member_event:
|
||||||
|
is_joined = member_event.content["membership"] in (
|
||||||
|
Membership.JOIN,
|
||||||
|
Membership.INVITE,
|
||||||
|
)
|
||||||
|
|
||||||
|
if is_joined:
|
||||||
|
return 200, {}
|
||||||
|
|
||||||
|
join_rules = room_state.get((EventTypes.JoinRules, ""))
|
||||||
|
is_public = False
|
||||||
|
if join_rules:
|
||||||
|
is_public = join_rules.content.get("join_rule") == JoinRules.PUBLIC
|
||||||
|
|
||||||
|
if is_public:
|
||||||
|
return 200, {}
|
||||||
|
|
||||||
|
await self.room_member_handler.update_membership(
|
||||||
|
fake_requester,
|
||||||
|
target=UserID.from_string(user_to_add),
|
||||||
|
room_id=room_id,
|
||||||
|
action=Membership.INVITE,
|
||||||
|
)
|
||||||
|
|
||||||
|
return 200, {}
|
||||||
|
|
Loading…
Reference in New Issue