|
@@ -16,7 +16,7 @@
|
|
|
import logging
|
|
|
import random
|
|
|
import re
|
|
|
-from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Tuple, Union, cast
|
|
|
+from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union, cast
|
|
|
|
|
|
import attr
|
|
|
|
|
@@ -192,8 +192,8 @@ class RegistrationWorkerStore(CacheInvalidationWorkerStore):
|
|
|
)
|
|
|
|
|
|
@cached()
|
|
|
- async def get_user_by_id(self, user_id: str) -> Optional[Mapping[str, Any]]:
|
|
|
- """Deprecated: use get_userinfo_by_id instead"""
|
|
|
+ async def get_user_by_id(self, user_id: str) -> Optional[UserInfo]:
|
|
|
+ """Returns info about the user account, if it exists."""
|
|
|
|
|
|
def get_user_by_id_txn(txn: LoggingTransaction) -> Optional[Dict[str, Any]]:
|
|
|
# We could technically use simple_select_one here, but it would not perform
|
|
@@ -202,16 +202,12 @@ class RegistrationWorkerStore(CacheInvalidationWorkerStore):
|
|
|
txn.execute(
|
|
|
"""
|
|
|
SELECT
|
|
|
- name, password_hash, is_guest, admin, consent_version, consent_ts,
|
|
|
+ name, is_guest, admin, consent_version, consent_ts,
|
|
|
consent_server_notice_sent, appservice_id, creation_ts, user_type,
|
|
|
deactivated, COALESCE(shadow_banned, FALSE) AS shadow_banned,
|
|
|
COALESCE(approved, TRUE) AS approved,
|
|
|
- COALESCE(locked, FALSE) AS locked, last_seen_ts
|
|
|
+ COALESCE(locked, FALSE) AS locked
|
|
|
FROM users
|
|
|
- LEFT JOIN (
|
|
|
- SELECT user_id, MAX(last_seen) AS last_seen_ts
|
|
|
- FROM user_ips GROUP BY user_id
|
|
|
- ) ls ON users.name = ls.user_id
|
|
|
WHERE name = ?
|
|
|
""",
|
|
|
(user_id,),
|
|
@@ -228,51 +224,23 @@ class RegistrationWorkerStore(CacheInvalidationWorkerStore):
|
|
|
desc="get_user_by_id",
|
|
|
func=get_user_by_id_txn,
|
|
|
)
|
|
|
-
|
|
|
- if row is not None:
|
|
|
- # If we're using SQLite our boolean values will be integers. Because we
|
|
|
- # present some of this data as is to e.g. server admins via REST APIs, we
|
|
|
- # want to make sure we're returning the right type of data.
|
|
|
- # Note: when adding a column name to this list, be wary of NULLable columns,
|
|
|
- # since NULL values will be turned into False.
|
|
|
- boolean_columns = [
|
|
|
- "admin",
|
|
|
- "deactivated",
|
|
|
- "shadow_banned",
|
|
|
- "approved",
|
|
|
- "locked",
|
|
|
- ]
|
|
|
- for column in boolean_columns:
|
|
|
- row[column] = bool(row[column])
|
|
|
-
|
|
|
- return row
|
|
|
-
|
|
|
- async def get_userinfo_by_id(self, user_id: str) -> Optional[UserInfo]:
|
|
|
- """Get a UserInfo object for a user by user ID.
|
|
|
-
|
|
|
- Note! Currently uses the cache of `get_user_by_id`. Once that deprecated method is removed,
|
|
|
- this method should be cached.
|
|
|
-
|
|
|
- Args:
|
|
|
- user_id: The user to fetch user info for.
|
|
|
- Returns:
|
|
|
- `UserInfo` object if user found, otherwise `None`.
|
|
|
- """
|
|
|
- user_data = await self.get_user_by_id(user_id)
|
|
|
- if not user_data:
|
|
|
+ if row is None:
|
|
|
return None
|
|
|
+
|
|
|
return UserInfo(
|
|
|
- appservice_id=user_data["appservice_id"],
|
|
|
- consent_server_notice_sent=user_data["consent_server_notice_sent"],
|
|
|
- consent_version=user_data["consent_version"],
|
|
|
- creation_ts=user_data["creation_ts"],
|
|
|
- is_admin=bool(user_data["admin"]),
|
|
|
- is_deactivated=bool(user_data["deactivated"]),
|
|
|
- is_guest=bool(user_data["is_guest"]),
|
|
|
- is_shadow_banned=bool(user_data["shadow_banned"]),
|
|
|
- user_id=UserID.from_string(user_data["name"]),
|
|
|
- user_type=user_data["user_type"],
|
|
|
- last_seen_ts=user_data["last_seen_ts"],
|
|
|
+ appservice_id=row["appservice_id"],
|
|
|
+ consent_server_notice_sent=row["consent_server_notice_sent"],
|
|
|
+ consent_version=row["consent_version"],
|
|
|
+ consent_ts=row["consent_ts"],
|
|
|
+ creation_ts=row["creation_ts"],
|
|
|
+ is_admin=bool(row["admin"]),
|
|
|
+ is_deactivated=bool(row["deactivated"]),
|
|
|
+ is_guest=bool(row["is_guest"]),
|
|
|
+ is_shadow_banned=bool(row["shadow_banned"]),
|
|
|
+ user_id=UserID.from_string(row["name"]),
|
|
|
+ user_type=row["user_type"],
|
|
|
+ approved=bool(row["approved"]),
|
|
|
+ locked=bool(row["locked"]),
|
|
|
)
|
|
|
|
|
|
async def is_trial_user(self, user_id: str) -> bool:
|
|
@@ -290,10 +258,10 @@ class RegistrationWorkerStore(CacheInvalidationWorkerStore):
|
|
|
|
|
|
now = self._clock.time_msec()
|
|
|
days = self.config.server.mau_appservice_trial_days.get(
|
|
|
- info["appservice_id"], self.config.server.mau_trial_days
|
|
|
+ info.appservice_id, self.config.server.mau_trial_days
|
|
|
)
|
|
|
trial_duration_ms = days * 24 * 60 * 60 * 1000
|
|
|
- is_trial = (now - info["creation_ts"] * 1000) < trial_duration_ms
|
|
|
+ is_trial = (now - info.creation_ts * 1000) < trial_duration_ms
|
|
|
return is_trial
|
|
|
|
|
|
@cached()
|