2026-01-27 08:24:22 +00:00
|
|
|
# Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
# See the LICENSE file for details.
|
|
|
|
|
|
2024-05-08 17:31:20 +00:00
|
|
|
AUTHENTICATION_ERROR_CODES = {
|
|
|
|
|
# Global
|
|
|
|
|
"INSTANCE_NOT_CONFIGURED": 5000,
|
2024-05-10 12:00:38 +00:00
|
|
|
"INVALID_EMAIL": 5005,
|
|
|
|
|
"EMAIL_REQUIRED": 5010,
|
|
|
|
|
"SIGNUP_DISABLED": 5015,
|
2024-05-14 15:23:51 +00:00
|
|
|
"MAGIC_LINK_LOGIN_DISABLED": 5016,
|
fix(security): block bot user logins (#9368)
Bot service accounts (User.is_bot=True, e.g. the WORKSPACE_SEED bot) are
internal identities meant to act only through API tokens. Nothing stopped
one from being driven through the interactive login flow if its email was
known, letting a human assume a service identity.
Reject bot accounts at the shared login chokepoint,
Adapter.complete_login_or_signup(), right beside the existing
deactivated-account check. This covers every interactive provider in one
place: email/password, magic code, and all OAuth providers (Google, GitHub,
GitLab, Gitea) across both the app and space surfaces. Bot API-token access
is left untouched, since that is how bots are meant to operate.
Also add a defense-in-depth is_bot guard to InstanceAdminSignInEndpoint,
which mints its own admin session outside the chokepoint (a bot is never an
InstanceAdmin today, so this is not currently reachable, but it closes the
path regardless).
Surface the rejection with a new dedicated error code
BOT_USER_LOGIN_FORBIDDEN (5017), plumbed into the app and space frontend
error helpers as well as the shared @plane/constants and @plane/utils
packages (message map + banner-alert list) so any consumer of the shared
auth-error handler renders it correctly. The admin path reuses the existing
ADMIN_AUTHENTICATION_FAILED code so it discloses no bot-specific error.
Add contract regression tests: a bot blocked via password and via magic
code, a bot blocked at the admin sign-in endpoint, and a non-bot control
that still logs in.
2026-07-07 20:21:37 +00:00
|
|
|
"BOT_USER_LOGIN_FORBIDDEN": 5017,
|
2024-05-14 15:23:51 +00:00
|
|
|
"PASSWORD_LOGIN_DISABLED": 5018,
|
|
|
|
|
"USER_ACCOUNT_DEACTIVATED": 5019,
|
2024-05-08 17:31:20 +00:00
|
|
|
# Password strength
|
2024-05-10 12:00:38 +00:00
|
|
|
"INVALID_PASSWORD": 5020,
|
2026-02-13 13:21:33 +00:00
|
|
|
"PASSWORD_TOO_WEAK": 5021,
|
2024-05-10 12:00:38 +00:00
|
|
|
"SMTP_NOT_CONFIGURED": 5025,
|
2024-05-08 17:31:20 +00:00
|
|
|
# Sign Up
|
2024-05-10 12:00:38 +00:00
|
|
|
"USER_ALREADY_EXIST": 5030,
|
|
|
|
|
"AUTHENTICATION_FAILED_SIGN_UP": 5035,
|
|
|
|
|
"REQUIRED_EMAIL_PASSWORD_SIGN_UP": 5040,
|
|
|
|
|
"INVALID_EMAIL_SIGN_UP": 5045,
|
|
|
|
|
"INVALID_EMAIL_MAGIC_SIGN_UP": 5050,
|
|
|
|
|
"MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED": 5055,
|
2024-05-24 13:13:37 +00:00
|
|
|
"EMAIL_PASSWORD_AUTHENTICATION_DISABLED": 5056,
|
2024-05-08 17:31:20 +00:00
|
|
|
# Sign In
|
2024-05-10 12:00:38 +00:00
|
|
|
"USER_DOES_NOT_EXIST": 5060,
|
|
|
|
|
"AUTHENTICATION_FAILED_SIGN_IN": 5065,
|
|
|
|
|
"REQUIRED_EMAIL_PASSWORD_SIGN_IN": 5070,
|
|
|
|
|
"INVALID_EMAIL_SIGN_IN": 5075,
|
|
|
|
|
"INVALID_EMAIL_MAGIC_SIGN_IN": 5080,
|
|
|
|
|
"MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED": 5085,
|
|
|
|
|
# Both Sign in and Sign up for magic
|
2024-05-20 06:53:48 +00:00
|
|
|
"INVALID_MAGIC_CODE_SIGN_IN": 5090,
|
|
|
|
|
"INVALID_MAGIC_CODE_SIGN_UP": 5092,
|
|
|
|
|
"EXPIRED_MAGIC_CODE_SIGN_IN": 5095,
|
|
|
|
|
"EXPIRED_MAGIC_CODE_SIGN_UP": 5097,
|
|
|
|
|
"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN": 5100,
|
|
|
|
|
"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP": 5102,
|
2024-05-08 17:31:20 +00:00
|
|
|
# Oauth
|
2024-06-14 09:25:59 +00:00
|
|
|
"OAUTH_NOT_CONFIGURED": 5104,
|
2024-05-10 12:00:38 +00:00
|
|
|
"GOOGLE_NOT_CONFIGURED": 5105,
|
|
|
|
|
"GITHUB_NOT_CONFIGURED": 5110,
|
2025-03-24 07:25:20 +00:00
|
|
|
"GITHUB_USER_NOT_IN_ORG": 5122,
|
2024-06-14 09:25:59 +00:00
|
|
|
"GITLAB_NOT_CONFIGURED": 5111,
|
2025-10-28 13:23:54 +00:00
|
|
|
"GITEA_NOT_CONFIGURED": 5112,
|
2024-05-10 12:00:38 +00:00
|
|
|
"GOOGLE_OAUTH_PROVIDER_ERROR": 5115,
|
|
|
|
|
"GITHUB_OAUTH_PROVIDER_ERROR": 5120,
|
2024-06-14 09:25:59 +00:00
|
|
|
"GITLAB_OAUTH_PROVIDER_ERROR": 5121,
|
2025-10-28 13:23:54 +00:00
|
|
|
"GITEA_OAUTH_PROVIDER_ERROR": 5123,
|
2026-07-09 11:01:33 +00:00
|
|
|
"OAUTH_PROVIDER_UNVERIFIED_EMAIL": 5124,
|
2024-05-08 17:31:20 +00:00
|
|
|
# Reset Password
|
2024-05-10 12:00:38 +00:00
|
|
|
"INVALID_PASSWORD_TOKEN": 5125,
|
|
|
|
|
"EXPIRED_PASSWORD_TOKEN": 5130,
|
2024-05-08 17:31:20 +00:00
|
|
|
# Change password
|
2024-05-10 12:00:38 +00:00
|
|
|
"INCORRECT_OLD_PASSWORD": 5135,
|
2024-05-14 15:23:51 +00:00
|
|
|
"MISSING_PASSWORD": 5138,
|
2024-05-10 12:00:38 +00:00
|
|
|
"INVALID_NEW_PASSWORD": 5140,
|
Add codespell support (config, workflow to detect/not fix) and make it fix some typos (#7864)
* Add github action to codespell preview on push and PRs
* Add rudimentary codespell config
* [DATALAD RUNCMD] chore: run codespell throughout fixing a few typos interactively
=== Do not change lines below ===
{
"chain": [],
"cmd": "codespell -w -i 3 -C 4 ./apps/web/core/components/workspace/delete-workspace-form.tsx ./deployments/cli/community/README.md",
"exit": 0,
"extra_inputs": [],
"inputs": [],
"outputs": [],
"pwd": "."
}
^^^ Do not change lines above ^^^
* Adjust coespell regex to ignore all camelCased words
* [DATALAD RUNCMD] chore: run codespell throughout fixing a few new typos automagically
=== Do not change lines below ===
{
"chain": [],
"cmd": "codespell -w",
"exit": 0,
"extra_inputs": [],
"inputs": [],
"outputs": [],
"pwd": "."
}
^^^ Do not change lines above ^^^
2025-10-07 12:12:49 +00:00
|
|
|
# set password
|
2024-05-10 12:00:38 +00:00
|
|
|
"PASSWORD_ALREADY_SET": 5145,
|
2024-05-08 17:31:20 +00:00
|
|
|
# Admin
|
2024-05-10 12:00:38 +00:00
|
|
|
"ADMIN_ALREADY_EXIST": 5150,
|
|
|
|
|
"REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME": 5155,
|
|
|
|
|
"INVALID_ADMIN_EMAIL": 5160,
|
|
|
|
|
"INVALID_ADMIN_PASSWORD": 5165,
|
|
|
|
|
"REQUIRED_ADMIN_EMAIL_PASSWORD": 5170,
|
|
|
|
|
"ADMIN_AUTHENTICATION_FAILED": 5175,
|
|
|
|
|
"ADMIN_USER_ALREADY_EXIST": 5180,
|
|
|
|
|
"ADMIN_USER_DOES_NOT_EXIST": 5185,
|
2024-05-14 15:23:51 +00:00
|
|
|
"ADMIN_USER_DEACTIVATED": 5190,
|
2024-05-21 09:33:01 +00:00
|
|
|
# Rate limit
|
|
|
|
|
"RATE_LIMIT_EXCEEDED": 5900,
|
2024-06-05 08:50:57 +00:00
|
|
|
# Unknown
|
|
|
|
|
"AUTHENTICATION_FAILED": 5999,
|
2024-05-08 17:31:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AuthenticationException(Exception):
|
|
|
|
|
error_code = None
|
|
|
|
|
error_message = None
|
|
|
|
|
payload = {}
|
|
|
|
|
|
|
|
|
|
def __init__(self, error_code, error_message, payload={}):
|
|
|
|
|
self.error_code = error_code
|
|
|
|
|
self.error_message = error_message
|
|
|
|
|
self.payload = payload
|
|
|
|
|
|
|
|
|
|
def get_error_dict(self):
|
2024-11-21 12:12:44 +00:00
|
|
|
error = {"error_code": self.error_code, "error_message": self.error_message}
|
2024-05-08 17:31:20 +00:00
|
|
|
for key in self.payload:
|
|
|
|
|
error[key] = self.payload[key]
|
|
|
|
|
|
|
|
|
|
return error
|