(
self,
obj: User,
attrs: Mapping[str, Any],
user: User | AnonymousUser | RpcUser,
**kwargs: Any,
)
| 162 | return data |
| 163 | |
| 164 | def serialize( |
| 165 | self, |
| 166 | obj: User, |
| 167 | attrs: Mapping[str, Any], |
| 168 | user: User | AnonymousUser | RpcUser, |
| 169 | **kwargs: Any, |
| 170 | ) -> UserSerializerResponse | UserSerializerResponseSelf: |
| 171 | d: UserSerializerResponse = { |
| 172 | "id": str(obj.id), |
| 173 | "name": obj.get_display_name(), |
| 174 | "username": obj.username, |
| 175 | "email": obj.email, |
| 176 | "avatarUrl": get_gravatar_url(obj.email, size=32), |
| 177 | "isActive": obj.is_active, |
| 178 | "isSuspended": obj.is_suspended, |
| 179 | "hasPasswordAuth": obj.password not in ("!", ""), |
| 180 | "isManaged": obj.is_managed, |
| 181 | "dateJoined": obj.date_joined, |
| 182 | "lastLogin": obj.last_login, |
| 183 | "has2fa": attrs["has2fa"], |
| 184 | "lastActive": obj.last_active, |
| 185 | "isSuperuser": obj.is_superuser, |
| 186 | "isStaff": obj.is_staff, |
| 187 | "emails": [], |
| 188 | # TODO(epurkhiser): This can be removed once we confirm the |
| 189 | # frontend does not use it |
| 190 | "experiments": {}, |
| 191 | } |
| 192 | |
| 193 | if self._user_is_requester(obj, user) or user.is_superuser: |
| 194 | d["emails"] = [ |
| 195 | {"id": str(e.id), "email": e.email, "is_verified": e.is_verified} |
| 196 | for e in attrs["emails"] |
| 197 | ] |
| 198 | |
| 199 | if self._user_is_requester(obj, user): |
| 200 | d = cast(UserSerializerResponseSelf, d) |
| 201 | options = { |
| 202 | o.key: o.value |
| 203 | for o in UserOption.objects.filter(user_id=obj.id, project_id__isnull=True) |
| 204 | if o.value is not None |
| 205 | } |
| 206 | |
| 207 | stacktrace_order = _SerializedStacktraceOrder( |
| 208 | int( |
| 209 | options.get("stacktrace_order", StacktraceOrder.DEFAULT) |
| 210 | # TODO: This second `or` won't be necessary once we remove empty strings from the DB |
| 211 | or StacktraceOrder.DEFAULT |
| 212 | ) |
| 213 | ) |
| 214 | |
| 215 | d["options"] = { |
| 216 | "theme": options.get("theme") or "system", |
| 217 | "language": options.get("language") or settings.SENTRY_DEFAULT_LANGUAGE, |
| 218 | "stacktraceOrder": stacktrace_order, |
| 219 | "defaultIssueEvent": options.get("default_issue_event") or "recommended", |
| 220 | "timezone": options.get("timezone") or settings.SENTRY_DEFAULT_TIME_ZONE, |
| 221 | "clock24Hours": options.get("clock_24_hours") or False, |
no test coverage detected