kinto 23.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kinto/__init__.py +92 -0
- kinto/__main__.py +249 -0
- kinto/authorization.py +134 -0
- kinto/config/__init__.py +94 -0
- kinto/config/kinto.tpl +270 -0
- kinto/contribute.json +27 -0
- kinto/core/__init__.py +246 -0
- kinto/core/authentication.py +48 -0
- kinto/core/authorization.py +311 -0
- kinto/core/cache/__init__.py +131 -0
- kinto/core/cache/memcached.py +112 -0
- kinto/core/cache/memory.py +104 -0
- kinto/core/cache/postgresql/__init__.py +178 -0
- kinto/core/cache/postgresql/schema.sql +23 -0
- kinto/core/cache/testing.py +208 -0
- kinto/core/cornice/__init__.py +93 -0
- kinto/core/cornice/cors.py +144 -0
- kinto/core/cornice/errors.py +40 -0
- kinto/core/cornice/pyramidhook.py +373 -0
- kinto/core/cornice/renderer.py +89 -0
- kinto/core/cornice/resource.py +205 -0
- kinto/core/cornice/service.py +641 -0
- kinto/core/cornice/util.py +138 -0
- kinto/core/cornice/validators/__init__.py +94 -0
- kinto/core/cornice/validators/_colander.py +142 -0
- kinto/core/cornice/validators/_marshmallow.py +182 -0
- kinto/core/cornice_swagger/__init__.py +92 -0
- kinto/core/cornice_swagger/converters/__init__.py +21 -0
- kinto/core/cornice_swagger/converters/exceptions.py +6 -0
- kinto/core/cornice_swagger/converters/parameters.py +90 -0
- kinto/core/cornice_swagger/converters/schema.py +249 -0
- kinto/core/cornice_swagger/swagger.py +725 -0
- kinto/core/cornice_swagger/templates/index.html +73 -0
- kinto/core/cornice_swagger/templates/index_script_template.html +21 -0
- kinto/core/cornice_swagger/util.py +42 -0
- kinto/core/cornice_swagger/views.py +78 -0
- kinto/core/decorators.py +74 -0
- kinto/core/errors.py +216 -0
- kinto/core/events.py +301 -0
- kinto/core/initialization.py +738 -0
- kinto/core/listeners/__init__.py +9 -0
- kinto/core/metrics.py +94 -0
- kinto/core/openapi.py +115 -0
- kinto/core/permission/__init__.py +202 -0
- kinto/core/permission/memory.py +167 -0
- kinto/core/permission/postgresql/__init__.py +489 -0
- kinto/core/permission/postgresql/migrations/migration_001_002.sql +18 -0
- kinto/core/permission/postgresql/schema.sql +41 -0
- kinto/core/permission/testing.py +487 -0
- kinto/core/resource/__init__.py +1311 -0
- kinto/core/resource/model.py +412 -0
- kinto/core/resource/schema.py +502 -0
- kinto/core/resource/viewset.py +230 -0
- kinto/core/schema.py +119 -0
- kinto/core/scripts.py +50 -0
- kinto/core/statsd.py +1 -0
- kinto/core/storage/__init__.py +436 -0
- kinto/core/storage/exceptions.py +53 -0
- kinto/core/storage/generators.py +58 -0
- kinto/core/storage/memory.py +651 -0
- kinto/core/storage/postgresql/__init__.py +1131 -0
- kinto/core/storage/postgresql/client.py +120 -0
- kinto/core/storage/postgresql/migrations/migration_001_002.sql +10 -0
- kinto/core/storage/postgresql/migrations/migration_002_003.sql +33 -0
- kinto/core/storage/postgresql/migrations/migration_003_004.sql +18 -0
- kinto/core/storage/postgresql/migrations/migration_004_005.sql +20 -0
- kinto/core/storage/postgresql/migrations/migration_005_006.sql +11 -0
- kinto/core/storage/postgresql/migrations/migration_006_007.sql +74 -0
- kinto/core/storage/postgresql/migrations/migration_007_008.sql +66 -0
- kinto/core/storage/postgresql/migrations/migration_008_009.sql +41 -0
- kinto/core/storage/postgresql/migrations/migration_009_010.sql +98 -0
- kinto/core/storage/postgresql/migrations/migration_010_011.sql +14 -0
- kinto/core/storage/postgresql/migrations/migration_011_012.sql +9 -0
- kinto/core/storage/postgresql/migrations/migration_012_013.sql +71 -0
- kinto/core/storage/postgresql/migrations/migration_013_014.sql +14 -0
- kinto/core/storage/postgresql/migrations/migration_014_015.sql +95 -0
- kinto/core/storage/postgresql/migrations/migration_015_016.sql +4 -0
- kinto/core/storage/postgresql/migrations/migration_016_017.sql +81 -0
- kinto/core/storage/postgresql/migrations/migration_017_018.sql +25 -0
- kinto/core/storage/postgresql/migrations/migration_018_019.sql +8 -0
- kinto/core/storage/postgresql/migrations/migration_019_020.sql +7 -0
- kinto/core/storage/postgresql/migrations/migration_020_021.sql +68 -0
- kinto/core/storage/postgresql/migrations/migration_021_022.sql +62 -0
- kinto/core/storage/postgresql/migrations/migration_022_023.sql +5 -0
- kinto/core/storage/postgresql/migrations/migration_023_024.sql +6 -0
- kinto/core/storage/postgresql/migrations/migration_024_025.sql +6 -0
- kinto/core/storage/postgresql/migrator.py +98 -0
- kinto/core/storage/postgresql/pool.py +55 -0
- kinto/core/storage/postgresql/schema.sql +143 -0
- kinto/core/storage/testing.py +1857 -0
- kinto/core/storage/utils.py +37 -0
- kinto/core/testing.py +182 -0
- kinto/core/utils.py +553 -0
- kinto/core/views/__init__.py +0 -0
- kinto/core/views/batch.py +163 -0
- kinto/core/views/errors.py +145 -0
- kinto/core/views/heartbeat.py +106 -0
- kinto/core/views/hello.py +69 -0
- kinto/core/views/openapi.py +35 -0
- kinto/core/views/version.py +50 -0
- kinto/events.py +3 -0
- kinto/plugins/__init__.py +0 -0
- kinto/plugins/accounts/__init__.py +94 -0
- kinto/plugins/accounts/authentication.py +63 -0
- kinto/plugins/accounts/scripts.py +61 -0
- kinto/plugins/accounts/utils.py +13 -0
- kinto/plugins/accounts/views.py +136 -0
- kinto/plugins/admin/README.md +3 -0
- kinto/plugins/admin/VERSION +1 -0
- kinto/plugins/admin/__init__.py +40 -0
- kinto/plugins/admin/build/VERSION +1 -0
- kinto/plugins/admin/build/assets/index-CYFwtKtL.css +6 -0
- kinto/plugins/admin/build/assets/index-DJ0m93zA.js +149 -0
- kinto/plugins/admin/build/assets/logo-VBRiKSPX.png +0 -0
- kinto/plugins/admin/build/index.html +18 -0
- kinto/plugins/admin/public/help.html +25 -0
- kinto/plugins/admin/views.py +42 -0
- kinto/plugins/default_bucket/__init__.py +191 -0
- kinto/plugins/flush.py +28 -0
- kinto/plugins/history/__init__.py +65 -0
- kinto/plugins/history/listener.py +181 -0
- kinto/plugins/history/views.py +66 -0
- kinto/plugins/openid/__init__.py +131 -0
- kinto/plugins/openid/utils.py +14 -0
- kinto/plugins/openid/views.py +193 -0
- kinto/plugins/prometheus.py +300 -0
- kinto/plugins/statsd.py +85 -0
- kinto/schema_validation.py +135 -0
- kinto/views/__init__.py +34 -0
- kinto/views/admin.py +195 -0
- kinto/views/buckets.py +45 -0
- kinto/views/collections.py +58 -0
- kinto/views/contribute.py +39 -0
- kinto/views/groups.py +90 -0
- kinto/views/permissions.py +235 -0
- kinto/views/records.py +133 -0
- kinto-23.2.1.dist-info/METADATA +232 -0
- kinto-23.2.1.dist-info/RECORD +142 -0
- kinto-23.2.1.dist-info/WHEEL +5 -0
- kinto-23.2.1.dist-info/entry_points.txt +5 -0
- kinto-23.2.1.dist-info/licenses/LICENSE +13 -0
- kinto-23.2.1.dist-info/top_level.txt +1 -0
kinto/config/kinto.tpl
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Created at {config_file_timestamp}
|
|
2
|
+
# Using Kinto version {kinto_version}
|
|
3
|
+
# Full options list for .ini file
|
|
4
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
[server:main]
|
|
8
|
+
use = egg:waitress#main
|
|
9
|
+
host = {host}
|
|
10
|
+
port = %(http_port)s
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
[app:main]
|
|
14
|
+
use = egg:kinto
|
|
15
|
+
|
|
16
|
+
# Feature settings
|
|
17
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#feature-settings
|
|
18
|
+
#
|
|
19
|
+
# kinto.readonly = false
|
|
20
|
+
# kinto.batch_max_requests = 25
|
|
21
|
+
# kinto.paginate_by =
|
|
22
|
+
# Experimental JSON-schema on collection
|
|
23
|
+
# kinto.experimental_collection_schema_validation = false
|
|
24
|
+
#
|
|
25
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#activating-the-permissions-endpoint
|
|
26
|
+
# kinto.experimental_permissions_endpoint = false
|
|
27
|
+
#
|
|
28
|
+
# kinto.trailing_slash_redirect_enabled = true
|
|
29
|
+
# kinto.trailing_slash_redirect_ttl_seconds = 3600
|
|
30
|
+
# kinto.heartbeat_timeout_seconds = 10
|
|
31
|
+
|
|
32
|
+
# Plugins
|
|
33
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#plugins
|
|
34
|
+
# https://github.com/uralbash/awesome-pyramid
|
|
35
|
+
kinto.includes = kinto.plugins.default_bucket
|
|
36
|
+
kinto.plugins.admin
|
|
37
|
+
kinto.plugins.accounts
|
|
38
|
+
# kinto.plugins.history
|
|
39
|
+
|
|
40
|
+
# Backends
|
|
41
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#storage
|
|
42
|
+
#
|
|
43
|
+
kinto.storage_backend = {storage_backend}
|
|
44
|
+
kinto.storage_url = {storage_url}
|
|
45
|
+
# kinto.storage_max_fetch_size = 10000
|
|
46
|
+
# kinto.storage_pool_size = 25
|
|
47
|
+
# kinto.storage_max_overflow = 5
|
|
48
|
+
# kinto.storage_pool_recycle = -1
|
|
49
|
+
# kinto.storage_pool_timeout = 30
|
|
50
|
+
# kinto.storage_max_backlog = -1
|
|
51
|
+
|
|
52
|
+
# Cache
|
|
53
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#cache
|
|
54
|
+
#
|
|
55
|
+
kinto.cache_backend = {cache_backend}
|
|
56
|
+
kinto.cache_url = {cache_url}
|
|
57
|
+
# kinto.cache_prefix =
|
|
58
|
+
# kinto.cache_max_size_bytes = 524288
|
|
59
|
+
# kinto.cache_pool_size = 25
|
|
60
|
+
# kinto.cache_max_overflow = 5
|
|
61
|
+
# kinto.cache_pool_recycle = -1
|
|
62
|
+
# kinto.cache_pool_timeout = 30
|
|
63
|
+
# kinto.cache_max_backlog = -1
|
|
64
|
+
|
|
65
|
+
# kinto.cache_backend = kinto.core.cache.memcached
|
|
66
|
+
# kinto.cache_hosts = 127.0.0.1:11211
|
|
67
|
+
|
|
68
|
+
# Permissions.
|
|
69
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#permissions
|
|
70
|
+
#
|
|
71
|
+
kinto.permission_backend = {permission_backend}
|
|
72
|
+
kinto.permission_url = {permission_url}
|
|
73
|
+
# kinto.permission_pool_size = 25
|
|
74
|
+
# kinto.permission_max_overflow = 5
|
|
75
|
+
# kinto.permission_pool_recycle = 1
|
|
76
|
+
# kinto.permission_pool_timeout = 30
|
|
77
|
+
# kinto.permission_max_backlog - 1
|
|
78
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#bypass-permissions-with-configuration
|
|
79
|
+
# kinto.bucket_create_principals = system.Authenticated
|
|
80
|
+
|
|
81
|
+
# Authentication
|
|
82
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#authentication
|
|
83
|
+
#
|
|
84
|
+
kinto.userid_hmac_secret = {secret}
|
|
85
|
+
multiauth.policies = account
|
|
86
|
+
|
|
87
|
+
# Bucket ID salt
|
|
88
|
+
kinto.default_bucket_hmac_secret = {bucket_id_salt}
|
|
89
|
+
|
|
90
|
+
# Any pyramid multiauth setting can be specified for custom authentication
|
|
91
|
+
# https://github.com/uralbash/awesome-pyramid#authentication
|
|
92
|
+
#
|
|
93
|
+
# Accounts API configuration
|
|
94
|
+
#
|
|
95
|
+
# Enable built-in plugin.
|
|
96
|
+
# Set `kinto.includes` to `kinto.plugins.accounts`
|
|
97
|
+
# Enable authenticated policy.
|
|
98
|
+
# Set `multiauth.policies` to `account`
|
|
99
|
+
multiauth.policy.account.use = kinto.plugins.accounts.AccountsPolicy
|
|
100
|
+
# Allow anyone to create accounts.
|
|
101
|
+
kinto.account_create_principals = system.Everyone
|
|
102
|
+
# Set user 'account:admin' as the administrator.
|
|
103
|
+
kinto.account_write_principals = account:admin
|
|
104
|
+
# Allow administrators to create buckets
|
|
105
|
+
kinto.bucket_create_principals = account:admin
|
|
106
|
+
|
|
107
|
+
# Notifications
|
|
108
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#notifications
|
|
109
|
+
#
|
|
110
|
+
# Configuration example:
|
|
111
|
+
# kinto.event_listeners = redis
|
|
112
|
+
# kinto.event_listeners.redis.use = kinto_redis.listeners
|
|
113
|
+
# kinto.event_listeners.redis.url = redis://localhost:6379/0
|
|
114
|
+
# kinto.event_listeners.redis.pool_size = 5
|
|
115
|
+
# kinto.event_listeners.redis.listname = queue
|
|
116
|
+
# kinto.event_listeners.redis.actions = create
|
|
117
|
+
# kinto.event_listeners.redis.resources = bucket collection
|
|
118
|
+
|
|
119
|
+
# Production settings
|
|
120
|
+
#
|
|
121
|
+
# https://kinto.readthedocs.io/en/latest/configuration/production.html
|
|
122
|
+
|
|
123
|
+
# kinto.http_scheme = https
|
|
124
|
+
# kinto.http_host = kinto.services.mozilla.com
|
|
125
|
+
|
|
126
|
+
# Cross Origin Requests
|
|
127
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#cross-origin-requests-cors
|
|
128
|
+
#
|
|
129
|
+
# kinto.cors_origins = *
|
|
130
|
+
|
|
131
|
+
# Backoff indicators/end of service
|
|
132
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#backoff-indicators
|
|
133
|
+
# https://kinto.readthedocs.io/en/latest/api/1.x/backoff.html#id1
|
|
134
|
+
#
|
|
135
|
+
# kinto.backoff =
|
|
136
|
+
# kinto.backoff_percentage =
|
|
137
|
+
# kinto.retry_after_seconds = 3
|
|
138
|
+
# kinto.eos =
|
|
139
|
+
# kinto.eos_message =
|
|
140
|
+
# kinto.eos_url =
|
|
141
|
+
|
|
142
|
+
# Project information
|
|
143
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#project-information
|
|
144
|
+
#
|
|
145
|
+
# kinto.version_json_path = ./version.json
|
|
146
|
+
# kinto.error_info_link = https://github.com/kinto/kinto/issues/
|
|
147
|
+
# kinto.project_docs = https://kinto.readthedocs.io
|
|
148
|
+
# kinto.project_name = kinto
|
|
149
|
+
# kinto.project_version =
|
|
150
|
+
# kinto.version_prefix_redirect_enabled = true
|
|
151
|
+
|
|
152
|
+
# Application profilling
|
|
153
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#application-profiling
|
|
154
|
+
# kinto.profiler_enabled = true
|
|
155
|
+
# kinto.profiler_dir = /tmp/profiling
|
|
156
|
+
|
|
157
|
+
# Client cache headers
|
|
158
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#client-caching
|
|
159
|
+
#
|
|
160
|
+
# Root URL
|
|
161
|
+
# kinto.root_cache_expires_seconds = 86400
|
|
162
|
+
#
|
|
163
|
+
# Every bucket objects objects and list
|
|
164
|
+
# kinto.bucket_cache_expires_seconds = 3600
|
|
165
|
+
#
|
|
166
|
+
# Every collection objects and list of every buckets
|
|
167
|
+
# kinto.collection_cache_expires_seconds = 3600
|
|
168
|
+
#
|
|
169
|
+
# Every group objects and list of every buckets
|
|
170
|
+
# kinto.group_cache_expires_seconds = 3600
|
|
171
|
+
#
|
|
172
|
+
# Every records objects and list of every collections
|
|
173
|
+
# kinto.record_cache_expires_seconds = 3600
|
|
174
|
+
#
|
|
175
|
+
# Records in a specific bucket
|
|
176
|
+
# kinto.blog_record_cache_expires_seconds = 3600
|
|
177
|
+
#
|
|
178
|
+
# Records in a specific collection in a specific bucket
|
|
179
|
+
# kinto.blog_article_record_cache_expires_seconds = 3600
|
|
180
|
+
|
|
181
|
+
# Custom ID generator for POST Requests
|
|
182
|
+
# https://kinto.readthedocs.io/en/latest/tutorials/custom-id-generator.html#tutorial-id-generator
|
|
183
|
+
#
|
|
184
|
+
# Default generator
|
|
185
|
+
# kinto.bucket_id_generator=kinto.views.NameGenerator
|
|
186
|
+
# Custom example
|
|
187
|
+
# kinto.collection_id_generator = name_generator.CollectionGenerator
|
|
188
|
+
# kinto.group_id_generator = name_generator.GroupGenerator
|
|
189
|
+
# kinto.record_id_generator = name_generator.RecordGenerator
|
|
190
|
+
|
|
191
|
+
# Kinto admin
|
|
192
|
+
# Absolute path to UI assets
|
|
193
|
+
# kinto.admin_assets_path = /app/kinto/plugins/admin/build/
|
|
194
|
+
|
|
195
|
+
# Enabling or disabling endpoints
|
|
196
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#enabling-or-disabling-endpoints
|
|
197
|
+
#
|
|
198
|
+
# kinto.endpoint_type_resource_name_method_enabled = false
|
|
199
|
+
# Where:
|
|
200
|
+
# endpoint_type: is either ``plural`` (e.g. ``/buckets``) or ``object`` (e.g. ``/buckets/abc``);
|
|
201
|
+
# resource_name: is the name of the resource (e.g. ``bucket``, ``group``, ``collection``, ``record``);
|
|
202
|
+
# method: is the http method (in lower case) (e.g. ``get``, ``post``, ``put``, ``patch``, ``delete``).
|
|
203
|
+
# For example, to disable the POST on the list of buckets and DELETE on single records
|
|
204
|
+
# kinto.plural_bucket_post_enabled = false
|
|
205
|
+
# kinto.object_record_delete_enabled = false
|
|
206
|
+
|
|
207
|
+
# [uwsgi]
|
|
208
|
+
# wsgi-file = app.wsgi
|
|
209
|
+
# enable-threads = true
|
|
210
|
+
# socket = /var/run/uwsgi/kinto.sock
|
|
211
|
+
# chmod-socket = 666
|
|
212
|
+
# processes = 3
|
|
213
|
+
# master = true
|
|
214
|
+
# module = kinto
|
|
215
|
+
# harakiri = 120
|
|
216
|
+
# uid = kinto
|
|
217
|
+
# gid = kinto
|
|
218
|
+
# virtualenv = .venv
|
|
219
|
+
# lazy = true
|
|
220
|
+
# lazy-apps = true
|
|
221
|
+
# single-interpreter = true
|
|
222
|
+
# buffer-size = 65535
|
|
223
|
+
# post-buffering = 65535
|
|
224
|
+
# plugin = python
|
|
225
|
+
|
|
226
|
+
# Logging and Monitoring
|
|
227
|
+
#
|
|
228
|
+
# https://kinto.readthedocs.io/en/latest/configuration/settings.html#logging-and-monitoring
|
|
229
|
+
# kinto.statsd_backend = kinto.core.statsd
|
|
230
|
+
# kinto.statsd_prefix = kinto
|
|
231
|
+
# kinto.statsd_url =
|
|
232
|
+
|
|
233
|
+
# kinto.sentry_dsn =
|
|
234
|
+
# kinto.sentry_env =
|
|
235
|
+
|
|
236
|
+
# kinto.newrelic_config =
|
|
237
|
+
# kinto.newrelic_env = dev
|
|
238
|
+
|
|
239
|
+
# Logging configuration
|
|
240
|
+
|
|
241
|
+
[loggers]
|
|
242
|
+
keys = root, kinto
|
|
243
|
+
|
|
244
|
+
[handlers]
|
|
245
|
+
keys = console
|
|
246
|
+
|
|
247
|
+
[formatters]
|
|
248
|
+
keys = color, json
|
|
249
|
+
|
|
250
|
+
[logger_root]
|
|
251
|
+
level = INFO
|
|
252
|
+
handlers = console
|
|
253
|
+
|
|
254
|
+
[logger_kinto]
|
|
255
|
+
level = DEBUG
|
|
256
|
+
handlers = console
|
|
257
|
+
qualname = kinto
|
|
258
|
+
propagate = 0
|
|
259
|
+
|
|
260
|
+
[handler_console]
|
|
261
|
+
class = kinto.core.StreamHandlerWithRequestID
|
|
262
|
+
args = (sys.stderr,)
|
|
263
|
+
level = NOTSET
|
|
264
|
+
formatter = color
|
|
265
|
+
|
|
266
|
+
[formatter_color]
|
|
267
|
+
class = logging_color_formatter.ColorFormatter
|
|
268
|
+
|
|
269
|
+
[formatter_json]
|
|
270
|
+
class = kinto.core.JsonLogFormatter
|
kinto/contribute.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Kinto",
|
|
3
|
+
"description": "Kinto is a minimalist JSON storage service with synchronisation and sharing abilities.",
|
|
4
|
+
"repository": {
|
|
5
|
+
"url": "https://github.com/Kinto/kinto",
|
|
6
|
+
"license": "Apache License (2.0)",
|
|
7
|
+
"tests": "https://github.com/Kinto/kinto/actions"
|
|
8
|
+
},
|
|
9
|
+
"participate": {
|
|
10
|
+
"home": "https://kinto.readthedocs.io/en/latest/community.html#how-to-contribute",
|
|
11
|
+
"docs": "https://kinto.readthedocs.io/",
|
|
12
|
+
"irc": "irc://irc.freenode.org/#kinto",
|
|
13
|
+
"irc-contacts": ["alexis", "leplatrem", "magopian", "natim", "NiKo`"]
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"list": "https://github.com/Kinto/kinto/issues",
|
|
17
|
+
"report": "https://github.com/Kinto/kinto/issues/new"
|
|
18
|
+
},
|
|
19
|
+
"keywords": [
|
|
20
|
+
"JSON",
|
|
21
|
+
"Python",
|
|
22
|
+
"Pyramid",
|
|
23
|
+
"REST",
|
|
24
|
+
"API",
|
|
25
|
+
"Database"
|
|
26
|
+
]
|
|
27
|
+
}
|
kinto/core/__init__.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"""Main entry point"""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import tempfile
|
|
5
|
+
|
|
6
|
+
import pkg_resources
|
|
7
|
+
from dockerflow import logging as dockerflow_logging
|
|
8
|
+
from pyramid.settings import aslist
|
|
9
|
+
|
|
10
|
+
from kinto.core import errors, events
|
|
11
|
+
from kinto.core.cornice import Service as CorniceService
|
|
12
|
+
from kinto.core.initialization import ( # NOQA
|
|
13
|
+
initialize,
|
|
14
|
+
install_middlewares,
|
|
15
|
+
load_default_settings,
|
|
16
|
+
)
|
|
17
|
+
from kinto.core.utils import (
|
|
18
|
+
current_resource_name,
|
|
19
|
+
current_service,
|
|
20
|
+
follow_subrequest,
|
|
21
|
+
log_context,
|
|
22
|
+
prefixed_principals,
|
|
23
|
+
prefixed_userid,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
__all__ = ["initialize", "load_default_settings", "Service"]
|
|
30
|
+
|
|
31
|
+
# Module version, as defined in PEP-0396.
|
|
32
|
+
__version__ = pkg_resources.get_distribution("kinto").version # FIXME?
|
|
33
|
+
|
|
34
|
+
DEFAULT_SETTINGS = {
|
|
35
|
+
"backoff": None,
|
|
36
|
+
"backoff_percentage": None,
|
|
37
|
+
"batch_max_requests": 25,
|
|
38
|
+
"cache_backend": "",
|
|
39
|
+
"cache_hosts": "",
|
|
40
|
+
"cache_url": "",
|
|
41
|
+
"cache_prefix": "",
|
|
42
|
+
"cache_max_size_bytes": 524288,
|
|
43
|
+
"cors_origins": "*",
|
|
44
|
+
"cors_max_age_seconds": 3600,
|
|
45
|
+
"eos": None,
|
|
46
|
+
"eos_message": None,
|
|
47
|
+
"eos_url": None,
|
|
48
|
+
"explicit_permissions": True,
|
|
49
|
+
"error_info_link": "https://github.com/Kinto/kinto/issues/",
|
|
50
|
+
"http_host": None,
|
|
51
|
+
"http_scheme": None,
|
|
52
|
+
"id_generator": "kinto.core.storage.generators.UUID4",
|
|
53
|
+
"includes": "",
|
|
54
|
+
"initialization_sequence": (
|
|
55
|
+
"kinto.core.initialization.setup_request_bound_data",
|
|
56
|
+
"kinto.core.initialization.setup_json_serializer",
|
|
57
|
+
"kinto.core.initialization.restrict_http_methods_if_readonly",
|
|
58
|
+
"kinto.core.initialization.setup_csp_headers",
|
|
59
|
+
"kinto.core.initialization.setup_logging",
|
|
60
|
+
"kinto.core.initialization.setup_storage",
|
|
61
|
+
"kinto.core.initialization.setup_permission",
|
|
62
|
+
"kinto.core.initialization.setup_cache",
|
|
63
|
+
"kinto.core.initialization.setup_requests_scheme",
|
|
64
|
+
"kinto.core.initialization.setup_version_redirection",
|
|
65
|
+
"kinto.core.initialization.setup_deprecation",
|
|
66
|
+
"kinto.core.initialization.setup_authentication",
|
|
67
|
+
"kinto.core.initialization.setup_backoff",
|
|
68
|
+
"kinto.core.initialization.setup_sentry",
|
|
69
|
+
"kinto.core.initialization.setup_listeners",
|
|
70
|
+
"kinto.core.initialization.setup_metrics",
|
|
71
|
+
"kinto.core.events.setup_transaction_hook",
|
|
72
|
+
),
|
|
73
|
+
"event_listeners": "",
|
|
74
|
+
"json_renderer": "ultrajson",
|
|
75
|
+
"heartbeat_timeout_seconds": 10,
|
|
76
|
+
"newrelic_config": None,
|
|
77
|
+
"newrelic_env": "dev",
|
|
78
|
+
"paginate_by": None,
|
|
79
|
+
"pagination_token_validity_seconds": 10 * 60,
|
|
80
|
+
"permission_backend": "",
|
|
81
|
+
"permission_url": "",
|
|
82
|
+
"profiler_dir": tempfile.gettempdir(),
|
|
83
|
+
"profiler_enabled": False,
|
|
84
|
+
"project_docs": "",
|
|
85
|
+
"project_name": "",
|
|
86
|
+
"project_version": "",
|
|
87
|
+
"readonly": False,
|
|
88
|
+
"root_cache_expires_seconds": 86400,
|
|
89
|
+
"retry_after_seconds": 30,
|
|
90
|
+
"version_prefix_redirect_ttl_seconds": -1,
|
|
91
|
+
"settings_prefix": "",
|
|
92
|
+
"sentry_dsn": None,
|
|
93
|
+
"sentry_env": None,
|
|
94
|
+
"sentry_breadcrumbs_min_level": logging.DEBUG,
|
|
95
|
+
"sentry_events_min_level": logging.WARNING,
|
|
96
|
+
"statsd_backend": "kinto.core.statsd",
|
|
97
|
+
"statsd_prefix": "kinto.core",
|
|
98
|
+
"statsd_url": None,
|
|
99
|
+
"metrics_matchdict_fields": [],
|
|
100
|
+
"storage_backend": "",
|
|
101
|
+
"storage_url": "",
|
|
102
|
+
"storage_max_fetch_size": 10000,
|
|
103
|
+
"tm.annotate_user": False, # Do annotate transactions with the user-id.
|
|
104
|
+
"transaction_per_request": True,
|
|
105
|
+
"userid_hmac_secret": "",
|
|
106
|
+
"default_bucket_hmac_secret": "",
|
|
107
|
+
"version_json_path": "version.json",
|
|
108
|
+
"version_prefix_redirect_enabled": True,
|
|
109
|
+
"trailing_slash_redirect_enabled": True,
|
|
110
|
+
"trailing_slash_redirect_ttl_seconds": 3600,
|
|
111
|
+
"multiauth.groupfinder": "kinto.core.authorization.groupfinder",
|
|
112
|
+
"multiauth.policies": "",
|
|
113
|
+
"multiauth.policy.basicauth.use": "kinto.core.authentication.BasicAuthAuthenticationPolicy",
|
|
114
|
+
"multiauth.authorization_policy": "kinto.core.authorization.AuthorizationPolicy",
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class Service(CorniceService):
|
|
119
|
+
"""Subclass of the default cornice service.
|
|
120
|
+
|
|
121
|
+
This is useful in order to attach specific behaviours without monkey
|
|
122
|
+
patching the default cornice service (which would impact other uses of it)
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
default_cors_headers = ("Backoff", "Retry-After", "Alert", "Content-Length", "Content-Type")
|
|
126
|
+
|
|
127
|
+
def error_handler(self, request):
|
|
128
|
+
return errors.json_error_handler(request)
|
|
129
|
+
|
|
130
|
+
@classmethod
|
|
131
|
+
def init_from_settings(cls, settings):
|
|
132
|
+
cls.renderer = settings["json_renderer"]
|
|
133
|
+
cls.cors_origins = tuple(aslist(settings["cors_origins"]))
|
|
134
|
+
cors_max_age = settings["cors_max_age_seconds"]
|
|
135
|
+
cls.cors_max_age = int(cors_max_age) if cors_max_age else None
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class JsonLogFormatter(dockerflow_logging.JsonLogFormatter):
|
|
139
|
+
logger_name = "kinto"
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
def init_from_settings(cls, settings):
|
|
143
|
+
cls.logger_name = settings["project_name"]
|
|
144
|
+
|
|
145
|
+
def __init__(self, fmt=None, datefmt=None, style="%"):
|
|
146
|
+
# Do not let mozilla-cloud-services-logger constructor to improperly
|
|
147
|
+
# use style as the logger_name.
|
|
148
|
+
# See https://github.com/mozilla/mozilla-cloud-services-logger/issues/3
|
|
149
|
+
logger_name = self.logger_name
|
|
150
|
+
super().__init__(fmt, datefmt, style)
|
|
151
|
+
self.logger_name = logger_name
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class StreamHandlerWithRequestID(logging.StreamHandler):
|
|
155
|
+
"""
|
|
156
|
+
A custom StreamHandler that adds the Dockerflow's `RequestIdLogFilter`.
|
|
157
|
+
|
|
158
|
+
Defining a custom handler seems to be the only way to bypass the fact that
|
|
159
|
+
``logging.config.fileConfig()`` does not load filters from ``.ini`` files.
|
|
160
|
+
"""
|
|
161
|
+
|
|
162
|
+
def __init__(self, *args, **kwargs):
|
|
163
|
+
super().__init__(*args, **kwargs)
|
|
164
|
+
filter_ = dockerflow_logging.RequestIdLogFilter()
|
|
165
|
+
self.addFilter(filter_)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def get_user_info(request):
|
|
169
|
+
# Default user info (shown in hello view for example).
|
|
170
|
+
user_info = {"id": request.prefixed_userid, "principals": request.prefixed_principals}
|
|
171
|
+
if hasattr(request, "get_user_profile"):
|
|
172
|
+
user_info["profile"] = request.get_user_profile()
|
|
173
|
+
return user_info
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def includeme(config):
|
|
177
|
+
settings = config.get_settings()
|
|
178
|
+
|
|
179
|
+
# Heartbeat registry.
|
|
180
|
+
config.registry.heartbeats = {}
|
|
181
|
+
|
|
182
|
+
# Public settings registry.
|
|
183
|
+
config.registry.public_settings = {"batch_max_requests", "readonly", "explicit_permissions"}
|
|
184
|
+
|
|
185
|
+
# Directive to declare arbitrary API capabilities.
|
|
186
|
+
def add_api_capability(config, identifier, description="", url="", **kw):
|
|
187
|
+
existing = config.registry.api_capabilities.get(identifier)
|
|
188
|
+
if existing:
|
|
189
|
+
error_msg = "The '{}' API capability was already registered ({})."
|
|
190
|
+
raise ValueError(error_msg.format(identifier, existing))
|
|
191
|
+
|
|
192
|
+
capability = dict(description=description, url=url, **kw)
|
|
193
|
+
config.registry.api_capabilities[identifier] = capability
|
|
194
|
+
|
|
195
|
+
config.add_directive("add_api_capability", add_api_capability)
|
|
196
|
+
config.registry.api_capabilities = {}
|
|
197
|
+
|
|
198
|
+
# Resource events helpers.
|
|
199
|
+
config.add_request_method(events.get_resource_events, name="get_resource_events")
|
|
200
|
+
config.add_request_method(events.notify_resource_event, name="notify_resource_event")
|
|
201
|
+
|
|
202
|
+
# Setup cornice.
|
|
203
|
+
config.include("kinto.core.cornice")
|
|
204
|
+
|
|
205
|
+
# Setup cornice api documentation
|
|
206
|
+
config.include("kinto.core.cornice_swagger")
|
|
207
|
+
|
|
208
|
+
# Per-request transaction.
|
|
209
|
+
config.include("pyramid_tm")
|
|
210
|
+
|
|
211
|
+
# Add CORS settings to the base kinto.core Service class.
|
|
212
|
+
Service.init_from_settings(settings)
|
|
213
|
+
|
|
214
|
+
# Use the project name as the main logger name (Logger field in MozLog).
|
|
215
|
+
JsonLogFormatter.init_from_settings(settings)
|
|
216
|
+
|
|
217
|
+
# Setup components.
|
|
218
|
+
for step in aslist(settings["initialization_sequence"]):
|
|
219
|
+
step_func = config.maybe_dotted(step)
|
|
220
|
+
step_func(config)
|
|
221
|
+
|
|
222
|
+
# Custom helpers.
|
|
223
|
+
config.add_request_method(log_context)
|
|
224
|
+
config.add_request_method(follow_subrequest)
|
|
225
|
+
config.add_request_method(prefixed_userid, property=True)
|
|
226
|
+
config.add_request_method(prefixed_principals, reify=True)
|
|
227
|
+
config.add_request_method(get_user_info, name="get_user_info")
|
|
228
|
+
config.add_request_method(current_resource_name, reify=True)
|
|
229
|
+
config.add_request_method(current_service, reify=True)
|
|
230
|
+
config.commit()
|
|
231
|
+
|
|
232
|
+
# Include plugins after init, unlike pyramid includes.
|
|
233
|
+
includes = aslist(settings["includes"])
|
|
234
|
+
for app in includes:
|
|
235
|
+
config.include(app)
|
|
236
|
+
|
|
237
|
+
# # Show settings to output.
|
|
238
|
+
# for key, value in settings.items():
|
|
239
|
+
# logger.info('Using {} = {}'.format(key, value))
|
|
240
|
+
|
|
241
|
+
# Scan views.
|
|
242
|
+
config.scan("kinto.core.views")
|
|
243
|
+
|
|
244
|
+
# Give sign of life.
|
|
245
|
+
msg = "Running {project_name} {project_version}."
|
|
246
|
+
logger.info(msg.format_map(settings))
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
from pyramid import authentication as base_auth
|
|
2
|
+
|
|
3
|
+
from kinto.core import utils
|
|
4
|
+
from kinto.core.openapi import OpenAPI
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BasicAuthAuthenticationPolicy(base_auth.BasicAuthAuthenticationPolicy):
|
|
8
|
+
"""Basic auth implementation.
|
|
9
|
+
|
|
10
|
+
Allow any user with any credentials (e.g. there is no need to create an
|
|
11
|
+
account).
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, *args, **kwargs):
|
|
16
|
+
def noop_check(*a):
|
|
17
|
+
return []
|
|
18
|
+
|
|
19
|
+
super().__init__(noop_check, *args, **kwargs)
|
|
20
|
+
|
|
21
|
+
def effective_principals(self, request):
|
|
22
|
+
# Bypass default Pyramid construction of principals because
|
|
23
|
+
# Pyramid multiauth already adds userid, Authenticated and Everyone
|
|
24
|
+
# principals.
|
|
25
|
+
return []
|
|
26
|
+
|
|
27
|
+
def unauthenticated_userid(self, request):
|
|
28
|
+
settings = request.registry.settings
|
|
29
|
+
|
|
30
|
+
credentials = base_auth.extract_http_basic_credentials(request)
|
|
31
|
+
if credentials:
|
|
32
|
+
username, password = credentials
|
|
33
|
+
if not username:
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
hmac_secret = settings["userid_hmac_secret"]
|
|
37
|
+
credentials = f"{credentials[0]}:{credentials[1]}"
|
|
38
|
+
userid = utils.hmac_digest(hmac_secret, credentials)
|
|
39
|
+
return userid
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def includeme(config):
|
|
43
|
+
config.add_api_capability(
|
|
44
|
+
"basicauth",
|
|
45
|
+
description="Very basic authentication sessions. Not for production use.",
|
|
46
|
+
url="http://kinto.readthedocs.io/en/stable/api/1.x/authentication.html",
|
|
47
|
+
)
|
|
48
|
+
OpenAPI.expose_authentication_method("basicauth", {"type": "basic"})
|