Skip to content

Commit

Permalink
Merge pull request #8069 from ckan/shashigharti-7604/tighten-validati…
Browse files Browse the repository at this point in the history
…on-for-id-fields

Tighten validation for id fields (followup)
  • Loading branch information
amercader committed May 23, 2024
2 parents 5334bab + dbbf0fa commit 73dfa66
Show file tree
Hide file tree
Showing 17 changed files with 531 additions and 113 deletions.
3 changes: 3 additions & 0 deletions changes/8069.migration
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* Only sysadmins can now set the ``id`` field of Datasets, Groups, Organizations, Users, Resource Views and Extras
* If provided, the value of the ``id`` field needs to be a valid UUID v4 string. Sites using custom ids that are not UUIDs can extend the relevant schema or validate methods to override the validation on the ``id`` field, but are strongly encouraged to use a separate custom field to store the custom id instead.
* The ``form_to_db_*`` and ``db_to_form_*`` methods of the ``IGroupForm`` interface are now deprecated, and have been replaced by``create_group_schema()``, ``update_group_schema()`` and ``show_group_schema()``.
41 changes: 32 additions & 9 deletions ckan/lib/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from flask import Blueprint

import ckan.logic.schema as schema
from ckan.lib.maintain import deprecated
from ckan.common import g
from ckan import logic, model, plugins
import ckan.authz
Expand Down Expand Up @@ -490,10 +491,25 @@ def bulk_process_template(self) -> str:
def group_form(self) -> str:
return 'group/new_group_form.html'

def create_group_schema(self) -> Schema:
return schema.default_create_group_schema()

def update_group_schema(self) -> Schema:
return schema.default_update_group_schema()

def show_group_schema(self) -> Schema:
return schema.default_show_group_schema()

# Deprecated schema methods, to be removed in CKAN 2.12

@deprecated(
"Use either `create_group_schema()` or `update_group_schema()`",
since="2.11.0"
)
def form_to_db_schema_options(self,
options: dict[str, Any]) -> dict[str, Any]:
''' This allows us to select different schemas for different
purpose eg via the web interface or via the api or creation vs
''' [Deprecated] This allows us to select different schemas for
different purpose eg via the web interface or via the api or creation vs
updating. It is optional and if not available form_to_db_schema
should be used.
If a context is provided, and it contains a schema, it will be
Expand All @@ -511,25 +527,32 @@ def form_to_db_schema_options(self,
else:
return self.form_to_db_schema()

@deprecated("Use `create_group_schema()`", since="2.11.0")
def form_to_db_schema_api_create(self) -> dict[str, Any]:
return schema.default_group_schema()
""" Deprecated """
return schema.default_create_group_schema()

@deprecated("Use `update_group_schema()`", since="2.11.0")
def form_to_db_schema_api_update(self) -> dict[str, Any]:
""" Deprecated """
return schema.default_update_group_schema()

@deprecated("Use `create_group_schema()`", since="2.11.0")
def form_to_db_schema(self) -> dict[str, Any]:
return schema.group_form_schema()
""" Deprecated """
return schema.default_create_group_schema()

@deprecated("Use `show_group_schema()`", since="2.11.0")
def db_to_form_schema(self) -> dict[str, Any]:
'''This is an interface to manipulate data from the database
into a format suitable for the form (optional)'''
""" Deprecated """
return {}

@deprecated("Use `show_group_schema()`", since="2.11.0")
def db_to_form_schema_options(self,
options: dict[str, Any]) -> dict[str, Any]:
'''This allows the selection of different schemas for different
purposes. It is optional and if not available, ``db_to_form_schema``
should be used.
''' [Deprecated] This allows the selection of different schemas
for different purposes. It is optional and if not available,
``db_to_form_schema`` should be used.
If a context is provided, and it contains a schema, it will be
returned.
'''
Expand Down
12 changes: 9 additions & 3 deletions ckan/logic/action/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,12 +723,18 @@ def _group_or_org_create(context: Context,
# get the schema
group_type = data_dict.get('type', 'organization' if is_org else 'group')
group_plugin = lib_plugins.lookup_group_plugin(group_type)
try:

if context.get("schema"):
schema: Schema = context["schema"]
elif hasattr(group_plugin, "create_group_schema"):
schema: Schema = group_plugin.create_group_schema()
# TODO: remove these fallback deprecated methods in the next release
elif hasattr(group_plugin, "form_to_db_schema_options"):
schema: Schema = getattr(group_plugin, "form_to_db_schema_options")({
'type': 'create', 'api': 'api_version' in context,
'context': context})
except AttributeError:
schema = group_plugin.form_to_db_schema()
else:
schema: Schema = group_plugin.form_to_db_schema()

data, errors = lib_plugins.plugin_validate(
group_plugin, context, data_dict, schema,
Expand Down
17 changes: 10 additions & 7 deletions ckan/logic/action/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -1215,13 +1215,18 @@ def _group_or_org_show(
item.read(group)

group_plugin = lib_plugins.lookup_group_plugin(group_dict['type'])
try:

if context.get("schema"):
schema: Schema = context["schema"]
elif hasattr(group_plugin, "show_group_schema"):
schema: Schema = group_plugin.show_group_schema()
# TODO: remove these fallback deprecated methods in the next release
elif hasattr(group_plugin, "db_to_form_schema_options"):
schema: Schema = getattr(group_plugin, "db_to_form_schema_options")({
'type': 'show',
'api': 'api_version' in context,
'type': 'show', 'api': 'api_version' in context,
'context': context})
except AttributeError:
schema = group_plugin.db_to_form_schema()
else:
schema: Schema = group_plugin.db_to_form_schema()

if include_followers:
context = plugins.toolkit.fresh_context(context)
Expand All @@ -1231,8 +1236,6 @@ def _group_or_org_show(
else:
group_dict['num_followers'] = 0

if not schema:
schema = ckan.logic.schema.default_show_group_schema()
group_dict, _errors = lib_plugins.plugin_validate(
group_plugin, context, group_dict, schema,
'organization_show' if is_org else 'group_show')
Expand Down
22 changes: 13 additions & 9 deletions ckan/logic/action/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import ckan.lib.app_globals as app_globals

from ckan.common import _, config
from ckan.types import Context, DataDict, ErrorDict
from ckan.types import Context, DataDict, ErrorDict, Schema

if TYPE_CHECKING:
import ckan.model as model_
Expand Down Expand Up @@ -662,14 +662,18 @@ def _group_or_org_update(

# get the schema
group_plugin = lib_plugins.lookup_group_plugin(group.type)
try:
schema = getattr(group_plugin, "form_to_db_schema_options")({
'type': 'update',
'api': 'api_version' in context,
'context': context
})
except AttributeError:
schema = group_plugin.form_to_db_schema()

if context.get("schema"):
schema: Schema = context["schema"]
elif hasattr(group_plugin, "update_group_schema"):
schema: Schema = group_plugin.update_group_schema()
# TODO: remove these fallback deprecated methods in the next release
elif hasattr(group_plugin, "form_to_db_schema_options"):
schema: Schema = getattr(group_plugin, "form_to_db_schema_options")({
'type': 'update', 'api': 'api_version' in context,
'context': context})
else:
schema: Schema = group_plugin.form_to_db_schema()

upload = uploader.get_uploader('group')
upload.update_data_dict(data_dict, 'image_url',
Expand Down
Loading

0 comments on commit 73dfa66

Please sign in to comment.