inveniosoftware / invenio-app-rdm

Turn-key research data management platform.
https://inveniordm.docs.cern.ch
MIT License
109 stars 149 forks source link

Duplicate Domain Creation Allowed Without Validation #2796

Open Samk13 opened 3 months ago

Samk13 commented 3 months ago

Package version (if known): 12

Describe the bug

The invenio domains create command allows creating domains with duplicate labels, which should be rejected. This causes multiple entries in the database. When selecting one of the duplicate domain labels in the domain administration UI, it results in a 500 error: sqlalchemy.exc.MultipleResultsFound error due to non-unique entries.

Steps to Reproduce

  1. Run invenio domains create company.
  2. Run invenio domains create company again.
  3. Attempt to select the "company" domain in the domain administration UI.
  4. Observe the error.

Expected behavior

The system should prevent creating domains with duplicate labels, returning an error instead of creating the domain.

Screenshots (if applicable)

Logs 127.0.0.1 - - [20/Aug/2024 13:36:06] "POST /api/domains HTTP/1.1" 500 - Traceback (most recent call last): File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask/app.py", line 2552, in __call__ return self.wsgi_app(environ, start_response) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py", line 187, in __call__ return self.app(environ, start_response) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/werkzeug/middleware/dispatcher.py", line 78, in __call__ return app(environ, start_response) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask/app.py", line 2552, in __call__ return self.wsgi_app(environ, start_response) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py", line 187, in __call__ return self.app(environ, start_response) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask/app.py", line 2532, in wsgi_app response = self.handle_exception(e) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask/app.py", line 2529, in wsgi_app response = self.full_dispatch_request() File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask/app.py", line 1825, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask/app.py", line 1823, in full_dispatch_request rv = self.dispatch_request() File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask/app.py", line 1799, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask_resources/resources.py", line 65, in view return view_meth() File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask_resources/content_negotiation.py", line 116, in inner_content_negotiation return f(*args, **kwargs) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask_resources/parsers/decorators.py", line 51, in inner return f(self, *args, **kwargs) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask_resources/parsers/decorators.py", line 90, in inner return f(self, *args, **kwargs) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/flask_resources/responses.py", line 39, in inner res = f(*args, **kwargs) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_records_resources/resources/records/resource.py", line 93, in create item = self.service.create( File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_records_resources/services/uow.py", line 376, in inner res = f(self, *args, **kwargs) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_records_resources/services/records/service.py", line 327, in create return self._create(self.record_cls, identity, data, uow=uow, expand=expand) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_records_resources/services/uow.py", line 380, in inner return f(self, *args, **kwargs) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_records_resources/services/records/service.py", line 342, in _create data, errors = self.schema.load( File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_records_resources/services/records/schema.py", line 90, in load valid_data = self.schema(context=context, **schema_args).load(data) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/marshmallow/schema.py", line 722, in load return self._do_load( File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/marshmallow/schema.py", line 884, in _do_load self._invoke_schema_validators( File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/marshmallow/schema.py", line 1184, in _invoke_schema_validators self._run_validator( File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/marshmallow/schema.py", line 774, in _run_validator validator_func(output, partial=partial, many=many) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_users_resources/services/schemas.py", line 277, in validate_category category = DomainCategory.get(data["category_name"]) File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/invenio_accounts/models.py", line 541, in get return cls.query.filter_by(label=label).one_or_none() File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 2850, in one_or_none return self._iter().one_or_none() File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/sqlalchemy/engine/result.py", line 1510, in one_or_none return self._only_one_row( File "/home/user/.pyenv/versions/3.9.19/envs/my-site/lib/python3.9/site-packages/sqlalchemy/engine/result.py", line 614, in _only_one_row raise exc.MultipleResultsFound( sqlalchemy.exc.MultipleResultsFound: Multiple rows were found when one or none was required

Additional context

psql --version
psql (PostgreSQL) 14.13 (Debian 14.13-1.pgdg120+1)

Looking here shouldn't the label be unique true?

label = db.Column(db.String(255), unique=True, nullable=False)
github-actions[bot] commented 1 month ago

This issue was automatically marked as stale.