mealie-recipes / mealie

Mealie is a self hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in Vue for a pleasant user experience for the whole family. Easily add recipes into your database by providing the url and mealie will automatically import the relevant data or add a family recipe with the UI editor
https://docs.mealie.io
GNU Affero General Public License v3.0
5.57k stars 608 forks source link

[BUG] - Two users cannot have the same email address #2866

Open azerial opened 6 months ago

azerial commented 6 months ago

First Check

What is the issue you are experiencing?

Impact: User cannot be created

Experienced: I tried to create a user with the same email addresses and got the error in the UI of " An unexpected error occurred" In the logs the error is "sqlite3.IntegrityError: UNIQUE constraint failed: users.email"

Expected: The error should be handled and if the no two users can have the same email address, the UI should display the error correctly.

Steps to Reproduce

  1. Log in to Mealie as a user with admin access
  2. Click on Settings
  3. Click on Users
  4. Copy an email address of an existing user
  5. Click on the Create button to create a new user
  6. Configure the user with the same email address of an existing user
  7. Observe error

Please provide relevant logs

mealie | ERROR: 19-Dec-23 20:09:30 (sqlite3.IntegrityError) UNIQUE constraint failed: users.email mealie | [SQL: INSERT INTO users (id, full_name, username, email, password, auth_method, admin, advanced, group_id, cache_key, login_attemps, locked_at, can_manage, can_invite, can_organize, owned_recipes_id, created_at, update_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)] mealie | [parameters: ('7471e2108c4247aabe1bf7a18d30a5dd', 'Dee', 'admin', 'email@whateverAddress.com', '$2b$12$EFvpHB4KV233p./wnKHhA..yhkH9Zyc/h0nEG4QO8ucFlvCoIyAi2', 'MEALIE', 1, 1, 'bd3b0e735fdd4633a482e9efd2e415a7', '1234', 0, None, 1, 1, 1, None, '2023-12-19 20:09:30.443978', '2023-12-19 20:09:30.443983')] mealie | (Background on this error at: https://sqlalche.me/e/20/gkpj) mealie | Traceback (most recent call last): mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1965, in _exec_single_context mealie | self.dialect.do_execute( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 921, in do_execute mealie | cursor.execute(statement, parameters) mealie | sqlite3.IntegrityError: UNIQUE constraint failed: users.email mealie | mealie | The above exception was the direct cause of the following exception: mealie | mealie | Traceback (most recent call last): mealie | File "/app/mealie/routes/_base/mixins.py", line 68, in create_one mealie | item = self.repo.create(data) mealie | File "/app/mealie/repos/repository_users.py", line 32, in create mealie | new_user = super().create(user) mealie | File "/app/mealie/repos/repository_generic.py", line 171, in create mealie | self.session.commit() mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1920, in commit mealie | trans.commit(_to_root=True) mealie | File "<string>", line 2, in commit mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go mealie | ret_value = fn(self, *arg, **kw) mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1236, in commit mealie | self._prepare_impl() mealie | File "<string>", line 2, in _prepare_impl mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go mealie | ret_value = fn(self, *arg, **kw) mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 1211, in _prepare_impl mealie | self.session.flush() mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 4163, in flush mealie | self._flush(objects) mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 4298, in _flush mealie | with util.safe_reraise(): mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py", line 147, in __exit__ mealie | raise exc_value.with_traceback(exc_tb) mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/session.py", line 4259, in _flush mealie | flush_context.execute() mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/unitofwork.py", line 466, in execute mealie | rec.execute(self) mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/unitofwork.py", line 642, in execute mealie | util.preloaded.orm_persistence.save_obj( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/persistence.py", line 93, in save_obj mealie | _emit_insert_statements( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/orm/persistence.py", line 1226, in _emit_insert_statements mealie | result = connection.execute( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1412, in execute mealie | return meth( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/sql/elements.py", line 483, in _execute_on_connection mealie | return connection._execute_clauseelement( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1635, in _execute_clauseelement mealie | ret = self._execute_context( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1844, in _execute_context mealie | return self._exec_single_context( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1984, in _exec_single_context mealie | self._handle_dbapi_exception( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 2339, in _handle_dbapi_exception mealie | raise sqlalchemy_exception.with_traceback(exc_info[2]) from e mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1965, in _exec_single_context mealie | self.dialect.do_execute( mealie | File "/opt/pysetup/.venv/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 921, in do_execute mealie | cursor.execute(statement, parameters) mealie | sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: users.email mealie | [SQL: INSERT INTO users (id, full_name, username, email, password, auth_method, admin, advanced, group_id, cache_key, login_attemps, locked_at, can_manage, can_invite, can_organize, owned_recipes_id, created_at, update_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)] mealie | [parameters: ('7471e2108c4247aabe1bf7a18d30a5dd', 'Dee', 'admin', 'email@whateverAddress.com', '$2b$12$EFvpHB4KV233p./wnKHhA..yhkH9Zyc/h0nEG4QO8ucFlvCoIyAi2', 'MEALIE', 1, 1, 'bd3b0e735fdd4633a482e9efd2e415a7', '1234', 0, None, 1, 1, 1, None, '2023-12-19 20:09:30.443978', '2023-12-19 20:09:30.443983')] mealie | (Background on this error at: https://sqlalche.me/e/20/gkpj)

Mealie Version

Nightly Build version fae8484f8425199a87ce8e7c694ef8a53c34b8b2

Deployment

Docker (Linux)

Additional Deployment Details

No response

hay-kot commented 3 weeks ago

@boc-the-git - idk if this is actually a bug, returning a generic error is a recommendation for OWASP. I think it just depends on if we want to follow OWASP guidelines or add more friendly error messages.

https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#authentication-responses

boc-the-git commented 3 weeks ago

@hay-kot I certainly have no strong feelings here, obviously it's been around for a while.

On the registration page we pop up a message saying Email is taken: https://github.com/mealie-recipes/mealie/blob/94e91d36024ece2071eb0362e7d7f395837238ea/frontend/composables/use-users/user-registration-form.ts#L39

I haven't read OWASP in a long time, but I expect that's against it.

The issue here however is that when creating a user as an admin, via https://demo.mealie.io/admin/manage/users/create, you don't get a nice error message like that and instead get a foreign key issue on the database. So it still gives you the same bad experience that I assume is against OWASP guidelines, and it doesn't give you the user friendliness that we already have on the registration page.