mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
API access with authorization #475
This commit is contained in:
parent
b874550a64
commit
fb34d4323c
@ -29,3 +29,4 @@ JWT_PRIVATE_KEY=""
|
||||
JWT_PUBLIC_JWKS=''
|
||||
DOCS_URL=''
|
||||
ADMIN_UNIT_CREATE_REQUIRES_ADMIN=False
|
||||
API_READ_ANONYM=False
|
||||
@ -26,6 +26,7 @@ x-web-env:
|
||||
DOCS_URL: ${DOCS_URL}
|
||||
SITE_NAME: ${SITE_NAME}
|
||||
ADMIN_UNIT_CREATE_REQUIRES_ADMIN: ${ADMIN_UNIT_CREATE_REQUIRES_ADMIN:-False}
|
||||
API_READ_ANONYM: ${API_READ_ANONYM:-False}
|
||||
|
||||
x-web:
|
||||
&default-web
|
||||
|
||||
@ -52,6 +52,7 @@ app.config["SEO_SITEMAP_PING_GOOGLE"] = getenv_bool("SEO_SITEMAP_PING_GOOGLE", "
|
||||
app.config["GOOGLE_MAPS_API_KEY"] = os.getenv("GOOGLE_MAPS_API_KEY")
|
||||
set_env_to_app(app, "SITE_NAME", "EventCally")
|
||||
app.config["FLASK_DEBUG"] = getenv_bool("FLASK_DEBUG", "False")
|
||||
app.config["API_READ_ANONYM"] = getenv_bool("API_READ_ANONYM", "False")
|
||||
|
||||
# if app.config["FLASK_DEBUG"]:
|
||||
# logging.basicConfig(level=logging.DEBUG)
|
||||
@ -268,6 +269,7 @@ from project.views import (
|
||||
admin_unit,
|
||||
admin_unit_member,
|
||||
admin_unit_member_invitation,
|
||||
custom_widget,
|
||||
dump,
|
||||
event,
|
||||
event_date,
|
||||
|
||||
@ -34,6 +34,7 @@ def owner_access_or_401(user_id):
|
||||
def login_api_user() -> bool:
|
||||
return (
|
||||
current_token
|
||||
and current_token.user
|
||||
and login_user(current_token.user)
|
||||
or current_user
|
||||
and current_user.is_authenticated
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from apispec import APISpec
|
||||
from apispec import APISpec, BasePlugin
|
||||
from apispec.exceptions import DuplicateComponentNameError
|
||||
from apispec.ext.marshmallow import MarshmallowPlugin
|
||||
from flask import url_for
|
||||
@ -115,6 +115,11 @@ class RestApi(Api):
|
||||
data["errors"] = errors
|
||||
|
||||
|
||||
class DocSecurityPlugin(BasePlugin):
|
||||
def operation_helper(self, path=None, operations=None, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
scope_list = [
|
||||
"openid",
|
||||
"profile",
|
||||
@ -138,7 +143,7 @@ app.config.update(
|
||||
"APISPEC_SPEC": APISpec(
|
||||
title="Event calendar API",
|
||||
version="0.1.0",
|
||||
plugins=[marshmallow_plugin],
|
||||
plugins=[marshmallow_plugin, DocSecurityPlugin()],
|
||||
openapi_version="2.0",
|
||||
info=dict(
|
||||
description="This API provides endpoints to interact with the event calendar data."
|
||||
@ -174,16 +179,33 @@ def add_oauth2_scheme_with_transport(insecure: bool):
|
||||
authorizationUrl = url_for("authorize", _external=True, _scheme="https")
|
||||
tokenUrl = url_for("issue_token", _external=True, _scheme="https")
|
||||
|
||||
oauth2_scheme = {
|
||||
scopes = {k: k for _, k in enumerate(scope_list)}
|
||||
oauth2_authorization_code_scheme = {
|
||||
"type": "oauth2",
|
||||
"authorizationUrl": authorizationUrl,
|
||||
"tokenUrl": tokenUrl,
|
||||
"flow": "accessCode",
|
||||
"scopes": {k: k for _, k in enumerate(scope_list)},
|
||||
"scopes": scopes,
|
||||
}
|
||||
|
||||
try:
|
||||
api_docs.spec.components.security_scheme("oauth2", oauth2_scheme)
|
||||
api_docs.spec.components.security_scheme(
|
||||
"oauth2AuthCode", oauth2_authorization_code_scheme
|
||||
)
|
||||
except DuplicateComponentNameError: # pragma: no cover
|
||||
pass
|
||||
|
||||
oauth2_client_credentials_scheme = {
|
||||
"type": "oauth2",
|
||||
"tokenUrl": tokenUrl,
|
||||
"flow": "application",
|
||||
"scopes": scopes,
|
||||
}
|
||||
|
||||
try:
|
||||
api_docs.spec.components.security_scheme(
|
||||
"oauth2ClientCredentials", oauth2_client_credentials_scheme
|
||||
)
|
||||
except DuplicateComponentNameError: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
@ -16,13 +16,13 @@ from project.models import CustomWidget
|
||||
class CustomWidgetResource(BaseResource):
|
||||
@doc(summary="Get custom widget", tags=["Custom Widgets"])
|
||||
@marshal_with(CustomWidgetSchema)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
return CustomWidget.query.get_or_404(id)
|
||||
|
||||
@doc(
|
||||
summary="Update custom widget",
|
||||
tags=["Custom Widgets"],
|
||||
security=[{"oauth2": ["customwidget:write"]}],
|
||||
)
|
||||
@use_kwargs(CustomWidgetPostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -42,7 +42,6 @@ class CustomWidgetResource(BaseResource):
|
||||
@doc(
|
||||
summary="Patch custom widget",
|
||||
tags=["Custom Widgets"],
|
||||
security=[{"oauth2": ["customwidget:write"]}],
|
||||
)
|
||||
@use_kwargs(CustomWidgetPatchRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -62,7 +61,6 @@ class CustomWidgetResource(BaseResource):
|
||||
@doc(
|
||||
summary="Delete custom widget",
|
||||
tags=["Custom Widgets"],
|
||||
security=[{"oauth2": ["customwidget:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("customwidget:write")
|
||||
|
||||
@ -2,7 +2,7 @@ from flask_apispec import doc, marshal_with
|
||||
|
||||
from project.api import add_api_resource
|
||||
from project.api.dump.schemas import DumpResponseSchema
|
||||
from project.api.resources import BaseResource
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.api.schemas import NoneSchema
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ class DumpResource(BaseResource):
|
||||
)
|
||||
@marshal_with(NoneSchema, 404)
|
||||
@marshal_with(DumpResponseSchema, 200)
|
||||
@require_api_access()
|
||||
def get(self, **kwargs):
|
||||
return None, 404
|
||||
|
||||
|
||||
@ -26,10 +26,9 @@ from project.api.event_date.schemas import (
|
||||
EventDateListRequestSchema,
|
||||
EventDateListResponseSchema,
|
||||
)
|
||||
from project.api.resources import BaseResource
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.api.schemas import NoneSchema
|
||||
from project.models import AdminUnit, Event, EventDate, PublicStatus
|
||||
from project.oauth2 import require_oauth
|
||||
from project.services.event import (
|
||||
get_event_with_details_or_404,
|
||||
get_events_query,
|
||||
@ -61,6 +60,7 @@ class EventListResource(BaseResource):
|
||||
@doc(summary="List events", tags=["Events"])
|
||||
@use_kwargs(EventListRequestSchema, location=("query"))
|
||||
@marshal_with(EventListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, **kwargs):
|
||||
pagination = (
|
||||
Event.query.join(Event.admin_unit)
|
||||
@ -78,7 +78,7 @@ class EventListResource(BaseResource):
|
||||
class EventResource(BaseResource):
|
||||
@doc(summary="Get event", tags=["Events"])
|
||||
@marshal_with(EventSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
login_api_user()
|
||||
event = get_event_with_details_or_404(id)
|
||||
@ -86,11 +86,12 @@ class EventResource(BaseResource):
|
||||
return event
|
||||
|
||||
@doc(
|
||||
summary="Update event", tags=["Events"], security=[{"oauth2": ["event:write"]}]
|
||||
summary="Update event",
|
||||
tags=["Events"],
|
||||
)
|
||||
@use_kwargs(EventPostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("event:write")
|
||||
@require_api_access("event:write")
|
||||
def put(self, id):
|
||||
login_api_user_or_401()
|
||||
event = Event.query.get_or_404(id)
|
||||
@ -106,10 +107,13 @@ class EventResource(BaseResource):
|
||||
|
||||
return make_response("", 204)
|
||||
|
||||
@doc(summary="Patch event", tags=["Events"], security=[{"oauth2": ["event:write"]}])
|
||||
@doc(
|
||||
summary="Patch event",
|
||||
tags=["Events"],
|
||||
)
|
||||
@use_kwargs(EventPatchRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("event:write")
|
||||
@require_api_access("event:write")
|
||||
def patch(self, id):
|
||||
login_api_user_or_401()
|
||||
event = Event.query.get_or_404(id)
|
||||
@ -126,10 +130,11 @@ class EventResource(BaseResource):
|
||||
return make_response("", 204)
|
||||
|
||||
@doc(
|
||||
summary="Delete event", tags=["Events"], security=[{"oauth2": ["event:write"]}]
|
||||
summary="Delete event",
|
||||
tags=["Events"],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("event:write")
|
||||
@require_api_access("event:write")
|
||||
def delete(self, id):
|
||||
login_api_user_or_401()
|
||||
event = Event.query.get_or_404(id)
|
||||
@ -145,7 +150,7 @@ class EventDatesResource(BaseResource):
|
||||
@doc(summary="List dates for event", tags=["Events", "Event Dates"])
|
||||
@use_kwargs(EventDateListRequestSchema, location=("query"))
|
||||
@marshal_with(EventDateListResponseSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
event = Event.query.options(
|
||||
load_only(Event.id, Event.public_status)
|
||||
@ -164,7 +169,7 @@ class EventSearchResource(BaseResource):
|
||||
@doc(summary="Search for events", tags=["Events"])
|
||||
@use_kwargs(EventSearchRequestSchema, location=("query"))
|
||||
@marshal_with(EventSearchResponseSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, **kwargs):
|
||||
login_api_user()
|
||||
params = EventSearchParams()
|
||||
@ -177,6 +182,7 @@ class EventReportsResource(BaseResource):
|
||||
@doc(summary="Add event report", tags=["Events"])
|
||||
@use_kwargs(EventReportPostSchema, location="json", apply=False)
|
||||
@marshal_with(NoneSchema, 204)
|
||||
@require_api_access()
|
||||
def post(self, id):
|
||||
event = Event.query.options(
|
||||
load_only(Event.id, Event.public_status)
|
||||
|
||||
@ -5,7 +5,7 @@ from project.api.event_category.schemas import (
|
||||
EventCategoryListRequestSchema,
|
||||
EventCategoryListResponseSchema,
|
||||
)
|
||||
from project.api.resources import BaseResource
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.models import EventCategory
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ class EventCategoryListResource(BaseResource):
|
||||
@doc(summary="List event categories", tags=["Event Categories"])
|
||||
@use_kwargs(EventCategoryListRequestSchema, location=("query"))
|
||||
@marshal_with(EventCategoryListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, **kwargs):
|
||||
pagination = EventCategory.query.paginate()
|
||||
return pagination
|
||||
|
||||
@ -12,9 +12,8 @@ from project.api.event_date.schemas import (
|
||||
EventDateSearchRequestSchema,
|
||||
EventDateSearchResponseSchema,
|
||||
)
|
||||
from project.api.resources import BaseResource
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.models import AdminUnit, Event, EventDate, PublicStatus
|
||||
from project.oauth2 import require_oauth
|
||||
from project.services.event import get_event_dates_query
|
||||
from project.services.event_search import EventSearchParams
|
||||
|
||||
@ -23,6 +22,7 @@ class EventDateListResource(BaseResource):
|
||||
@doc(summary="List event dates", tags=["Event Dates"])
|
||||
@use_kwargs(EventDateListRequestSchema, location=("query"))
|
||||
@marshal_with(EventDateListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, **kwargs):
|
||||
pagination = (
|
||||
EventDate.query.join(EventDate.event)
|
||||
@ -42,7 +42,7 @@ class EventDateListResource(BaseResource):
|
||||
class EventDateResource(BaseResource):
|
||||
@doc(summary="Get event date", tags=["Event Dates"])
|
||||
@marshal_with(EventDateSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
event_date = EventDate.query.options(
|
||||
defaultload(EventDate.event).load_only(
|
||||
@ -57,7 +57,7 @@ class EventDateSearchResource(BaseResource):
|
||||
@doc(summary="Search for event dates", tags=["Event Dates"])
|
||||
@use_kwargs(EventDateSearchRequestSchema, location=("query"))
|
||||
@marshal_with(EventDateSearchResponseSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, **kwargs):
|
||||
login_api_user()
|
||||
params = EventSearchParams()
|
||||
|
||||
@ -19,13 +19,13 @@ from project.services.event_search import EventSearchParams
|
||||
class EventListModelResource(BaseResource):
|
||||
@doc(summary="Get event list", tags=["Event Lists"])
|
||||
@marshal_with(EventListSchema)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
return EventList.query.get_or_404(id)
|
||||
|
||||
@doc(
|
||||
summary="Update event list",
|
||||
tags=["Event Lists"],
|
||||
security=[{"oauth2": ["eventlist:write"]}],
|
||||
)
|
||||
@use_kwargs(EventListUpdateRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -45,7 +45,6 @@ class EventListModelResource(BaseResource):
|
||||
@doc(
|
||||
summary="Patch event list",
|
||||
tags=["Event Lists"],
|
||||
security=[{"oauth2": ["eventlist:write"]}],
|
||||
)
|
||||
@use_kwargs(EventListPatchRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -65,7 +64,6 @@ class EventListModelResource(BaseResource):
|
||||
@doc(
|
||||
summary="Delete event list",
|
||||
tags=["Event Lists"],
|
||||
security=[{"oauth2": ["eventlist:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("eventlist:write")
|
||||
@ -87,6 +85,7 @@ class EventListEventListResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(EventListRequestSchema, location=("query"))
|
||||
@marshal_with(EventListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
params = EventSearchParams()
|
||||
params.event_list_id = id
|
||||
@ -98,7 +97,6 @@ class EventListEventListWriteResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add event",
|
||||
tags=["Event Lists", "Events"],
|
||||
security=[{"oauth2": ["eventlist:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("eventlist:write")
|
||||
@ -120,7 +118,6 @@ class EventListEventListWriteResource(BaseResource):
|
||||
@doc(
|
||||
summary="Remove event",
|
||||
tags=["Event Lists", "Events"],
|
||||
security=[{"oauth2": ["eventlist:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("eventlist:write")
|
||||
|
||||
@ -2,13 +2,14 @@ from flask_apispec import doc, marshal_with
|
||||
|
||||
from project.api import add_api_resource
|
||||
from project.api.event_reference.schemas import EventReferenceSchema
|
||||
from project.api.resources import BaseResource
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.models import EventReference
|
||||
|
||||
|
||||
class EventReferenceResource(BaseResource):
|
||||
@doc(summary="Get event reference", tags=["Event References"])
|
||||
@marshal_with(EventReferenceSchema)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
return EventReference.query.get_or_404(id)
|
||||
|
||||
|
||||
@ -74,7 +74,6 @@ from project.api.place.schemas import (
|
||||
)
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.models import AdminUnit, Event, PublicStatus
|
||||
from project.oauth2 import require_oauth
|
||||
from project.services.admin_unit import (
|
||||
get_admin_unit_invitation_query,
|
||||
get_admin_unit_query,
|
||||
@ -98,7 +97,7 @@ from project.views.utils import send_mail
|
||||
class OrganizationResource(BaseResource):
|
||||
@doc(summary="Get organization", tags=["Organizations"])
|
||||
@marshal_with(OrganizationSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
return AdminUnit.query.get_or_404(id)
|
||||
|
||||
@ -111,7 +110,7 @@ class OrganizationEventDateSearchResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(EventDateSearchRequestSchema, location=("query"))
|
||||
@marshal_with(EventDateSearchResponseSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
|
||||
@ -128,7 +127,7 @@ class OrganizationEventSearchResource(BaseResource):
|
||||
@doc(summary="Search for events of organization", tags=["Organizations", "Events"])
|
||||
@use_kwargs(EventSearchRequestSchema, location=("query"))
|
||||
@marshal_with(EventSearchResponseSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
|
||||
@ -145,7 +144,7 @@ class OrganizationEventListResource(BaseResource):
|
||||
@doc(summary="List events of organization", tags=["Organizations", "Events"])
|
||||
@use_kwargs(EventListRequestSchema, location=("query"))
|
||||
@marshal_with(EventListResponseSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
|
||||
@ -164,11 +163,10 @@ class OrganizationEventListResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add new event",
|
||||
tags=["Organizations", "Events"],
|
||||
security=[{"oauth2": ["event:write"]}],
|
||||
)
|
||||
@use_kwargs(EventPostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(EventIdSchema, 201)
|
||||
@require_oauth("event:write")
|
||||
@require_api_access("event:write")
|
||||
def post(self, id):
|
||||
login_api_user_or_401()
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
@ -189,6 +187,7 @@ class OrganizationEventImportResource(BaseResource):
|
||||
@marshal_with(EventIdSchema, 201)
|
||||
@require_api_access("event:write")
|
||||
def post(self, id, **kwargs):
|
||||
login_api_user_or_401()
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
access_or_401(admin_unit, "event:create")
|
||||
|
||||
@ -211,10 +210,13 @@ class OrganizationEventImportResource(BaseResource):
|
||||
|
||||
|
||||
class OrganizationListResource(BaseResource):
|
||||
@doc(summary="List organizations", tags=["Organizations"])
|
||||
@doc(
|
||||
summary="List organizations",
|
||||
tags=["Organizations"],
|
||||
)
|
||||
@use_kwargs(OrganizationListRequestSchema, location=("query"))
|
||||
@marshal_with(OrganizationListResponseSchema)
|
||||
@require_oauth(optional=True)
|
||||
@require_api_access()
|
||||
def get(self, **kwargs):
|
||||
keyword = kwargs["keyword"] if "keyword" in kwargs else None
|
||||
|
||||
@ -231,6 +233,7 @@ class OrganizationOrganizerListResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(OrganizerListRequestSchema, location=("query"))
|
||||
@marshal_with(OrganizerListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
name = kwargs["name"] if "name" in kwargs else None
|
||||
@ -241,11 +244,10 @@ class OrganizationOrganizerListResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add new organizer",
|
||||
tags=["Organizations", "Organizers"],
|
||||
security=[{"oauth2": ["organizer:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizerPostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(OrganizerIdSchema, 201)
|
||||
@require_oauth("organizer:write")
|
||||
@require_api_access("organizer:write")
|
||||
def post(self, id):
|
||||
login_api_user_or_401()
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
@ -264,6 +266,7 @@ class OrganizationPlaceListResource(BaseResource):
|
||||
@doc(summary="List places of organization", tags=["Organizations", "Places"])
|
||||
@use_kwargs(PlaceListRequestSchema, location=("query"))
|
||||
@marshal_with(PlaceListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
name = kwargs["name"] if "name" in kwargs else None
|
||||
@ -274,11 +277,10 @@ class OrganizationPlaceListResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add new place",
|
||||
tags=["Organizations", "Places"],
|
||||
security=[{"oauth2": ["place:write"]}],
|
||||
)
|
||||
@use_kwargs(PlacePostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(PlaceIdSchema, 201)
|
||||
@require_oauth("place:write")
|
||||
@require_api_access("place:write")
|
||||
def post(self, id):
|
||||
login_api_user_or_401()
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
@ -300,6 +302,7 @@ class OrganizationIncomingEventReferenceListResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(EventReferenceListRequestSchema, location=("query"))
|
||||
@marshal_with(EventReferenceListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
|
||||
@ -314,6 +317,7 @@ class OrganizationOutgoingEventReferenceListResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(EventReferenceListRequestSchema, location=("query"))
|
||||
@marshal_with(EventReferenceListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
|
||||
@ -325,7 +329,6 @@ class OrganizationOutgoingRelationListResource(BaseResource):
|
||||
@doc(
|
||||
summary="List outgoing relations of organization",
|
||||
tags=["Organizations", "Organization Relations"],
|
||||
security=[{"oauth2": ["organization:read"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationRelationListRequestSchema, location=("query"))
|
||||
@marshal_with(OrganizationRelationListResponseSchema)
|
||||
@ -341,7 +344,6 @@ class OrganizationOutgoingRelationListResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add new outgoing relation",
|
||||
tags=["Organizations", "Organization Relations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationRelationCreateRequestSchema, location="json", apply=False)
|
||||
@marshal_with(OrganizationRelationIdSchema, 201)
|
||||
@ -364,7 +366,6 @@ class OrganizationOrganizationInvitationListResource(BaseResource):
|
||||
@doc(
|
||||
summary="List organization invitations of organization",
|
||||
tags=["Organizations", "Organization Invitations"],
|
||||
security=[{"oauth2": ["organization:read"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationInvitationListRequestSchema, location=("query"))
|
||||
@marshal_with(OrganizationInvitationListResponseSchema)
|
||||
@ -380,7 +381,6 @@ class OrganizationOrganizationInvitationListResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add new organization invitation",
|
||||
tags=["Organizations", "Organization Invitations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationInvitationCreateRequestSchema, location="json", apply=False)
|
||||
@marshal_with(OrganizationInvitationIdSchema, 201)
|
||||
@ -413,6 +413,7 @@ class OrganizationEventListListResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(EventListListRequestSchema, location=("query"))
|
||||
@marshal_with(EventListListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
name = kwargs["name"] if "name" in kwargs else None
|
||||
@ -423,7 +424,6 @@ class OrganizationEventListListResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add new event list",
|
||||
tags=["Organizations", "Event Lists"],
|
||||
security=[{"oauth2": ["eventlist:write"]}],
|
||||
)
|
||||
@use_kwargs(EventListCreateRequestSchema, location="json", apply=False)
|
||||
@marshal_with(EventListIdSchema, 201)
|
||||
@ -449,6 +449,7 @@ class OrganizationEventListStatusListResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(EventListListRequestSchema, location=("query"))
|
||||
@marshal_with(EventListStatusListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, event_id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
name = kwargs["name"] if "name" in kwargs else None
|
||||
@ -466,6 +467,7 @@ class OrganizationCustomWidgetListResource(BaseResource):
|
||||
)
|
||||
@use_kwargs(CustomWidgetListRequestSchema, location=("query"))
|
||||
@marshal_with(CustomWidgetListResponseSchema)
|
||||
@require_api_access()
|
||||
def get(self, id, **kwargs):
|
||||
admin_unit = AdminUnit.query.get_or_404(id)
|
||||
name = kwargs["name"] if "name" in kwargs else None
|
||||
@ -476,7 +478,6 @@ class OrganizationCustomWidgetListResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add new custom widget",
|
||||
tags=["Organizations", "CustomWidgets"],
|
||||
security=[{"oauth2": ["customwidget:write"]}],
|
||||
)
|
||||
@use_kwargs(CustomWidgetPostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(CustomWidgetIdSchema, 201)
|
||||
|
||||
@ -18,7 +18,6 @@ class OrganizationInvitationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Get organization invitation",
|
||||
tags=["Organization Invitations"],
|
||||
security=[{"oauth2": ["organization:read"]}],
|
||||
)
|
||||
@marshal_with(OrganizationInvitationSchema)
|
||||
@require_api_access("organization:read")
|
||||
@ -32,7 +31,6 @@ class OrganizationInvitationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Update organization invitation",
|
||||
tags=["Organization Invitations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationInvitationUpdateRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -52,7 +50,6 @@ class OrganizationInvitationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Patch organization invitation",
|
||||
tags=["Organization Invitations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationInvitationPatchRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -72,7 +69,6 @@ class OrganizationInvitationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Delete organization invitation",
|
||||
tags=["Organization Invitations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("organization:write")
|
||||
|
||||
@ -19,7 +19,6 @@ class OrganizationRelationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Get organization relation",
|
||||
tags=["Organization Relations"],
|
||||
security=[{"oauth2": ["organization:read"]}],
|
||||
)
|
||||
@marshal_with(OrganizationRelationSchema)
|
||||
@require_api_access("organization:read")
|
||||
@ -37,7 +36,6 @@ class OrganizationRelationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Update organization relation",
|
||||
tags=["Organization Relations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationRelationUpdateRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -57,7 +55,6 @@ class OrganizationRelationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Patch organization relation",
|
||||
tags=["Organization Relations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationRelationPatchRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@ -77,7 +74,6 @@ class OrganizationRelationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Delete organization relation",
|
||||
tags=["Organization Relations"],
|
||||
security=[{"oauth2": ["organization:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("organization:write")
|
||||
|
||||
@ -9,25 +9,24 @@ from project.api.organizer.schemas import (
|
||||
OrganizerPostRequestSchema,
|
||||
OrganizerSchema,
|
||||
)
|
||||
from project.api.resources import BaseResource
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.models import EventOrganizer
|
||||
from project.oauth2 import require_oauth
|
||||
|
||||
|
||||
class OrganizerResource(BaseResource):
|
||||
@doc(summary="Get organizer", tags=["Organizers"])
|
||||
@marshal_with(OrganizerSchema)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
return EventOrganizer.query.get_or_404(id)
|
||||
|
||||
@doc(
|
||||
summary="Update organizer",
|
||||
tags=["Organizers"],
|
||||
security=[{"oauth2": ["organizer:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizerPostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("organizer:write")
|
||||
@require_api_access("organizer:write")
|
||||
def put(self, id):
|
||||
login_api_user_or_401()
|
||||
organizer = EventOrganizer.query.get_or_404(id)
|
||||
@ -41,11 +40,10 @@ class OrganizerResource(BaseResource):
|
||||
@doc(
|
||||
summary="Patch organizer",
|
||||
tags=["Organizers"],
|
||||
security=[{"oauth2": ["organizer:write"]}],
|
||||
)
|
||||
@use_kwargs(OrganizerPatchRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("organizer:write")
|
||||
@require_api_access("organizer:write")
|
||||
def patch(self, id):
|
||||
login_api_user_or_401()
|
||||
organizer = EventOrganizer.query.get_or_404(id)
|
||||
@ -61,10 +59,9 @@ class OrganizerResource(BaseResource):
|
||||
@doc(
|
||||
summary="Delete organizer",
|
||||
tags=["Organizers"],
|
||||
security=[{"oauth2": ["organizer:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("organizer:write")
|
||||
@require_api_access("organizer:write")
|
||||
def delete(self, id):
|
||||
login_api_user_or_401()
|
||||
organizer = EventOrganizer.query.get_or_404(id)
|
||||
|
||||
@ -9,23 +9,24 @@ from project.api.place.schemas import (
|
||||
PlacePostRequestSchema,
|
||||
PlaceSchema,
|
||||
)
|
||||
from project.api.resources import BaseResource
|
||||
from project.api.resources import BaseResource, require_api_access
|
||||
from project.models import EventPlace
|
||||
from project.oauth2 import require_oauth
|
||||
|
||||
|
||||
class PlaceResource(BaseResource):
|
||||
@doc(summary="Get place", tags=["Places"])
|
||||
@marshal_with(PlaceSchema)
|
||||
@require_api_access()
|
||||
def get(self, id):
|
||||
return EventPlace.query.get_or_404(id)
|
||||
|
||||
@doc(
|
||||
summary="Update place", tags=["Places"], security=[{"oauth2": ["place:write"]}]
|
||||
summary="Update place",
|
||||
tags=["Places"],
|
||||
)
|
||||
@use_kwargs(PlacePostRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("place:write")
|
||||
@require_api_access("place:write")
|
||||
def put(self, id):
|
||||
login_api_user_or_401()
|
||||
place = EventPlace.query.get_or_404(id)
|
||||
@ -36,10 +37,13 @@ class PlaceResource(BaseResource):
|
||||
|
||||
return make_response("", 204)
|
||||
|
||||
@doc(summary="Patch place", tags=["Places"], security=[{"oauth2": ["place:write"]}])
|
||||
@doc(
|
||||
summary="Patch place",
|
||||
tags=["Places"],
|
||||
)
|
||||
@use_kwargs(PlacePatchRequestSchema, location="json", apply=False)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("place:write")
|
||||
@require_api_access("place:write")
|
||||
def patch(self, id):
|
||||
login_api_user_or_401()
|
||||
place = EventPlace.query.get_or_404(id)
|
||||
@ -51,10 +55,11 @@ class PlaceResource(BaseResource):
|
||||
return make_response("", 204)
|
||||
|
||||
@doc(
|
||||
summary="Delete place", tags=["Places"], security=[{"oauth2": ["place:write"]}]
|
||||
summary="Delete place",
|
||||
tags=["Places"],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_oauth("place:write")
|
||||
@require_api_access("place:write")
|
||||
def delete(self, id):
|
||||
login_api_user_or_401()
|
||||
place = EventPlace.query.get_or_404(id)
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
from functools import wraps
|
||||
|
||||
from authlib.oauth2 import OAuth2Error
|
||||
from authlib.oauth2.rfc6749 import MissingAuthorizationError
|
||||
from flask import request
|
||||
from flask_apispec import marshal_with
|
||||
from flask_apispec.annotations import annotate
|
||||
from flask_apispec.views import MethodResource
|
||||
from flask_security import current_user
|
||||
from flask_wtf.csrf import validate_csrf
|
||||
|
||||
from project import db
|
||||
from project import app, csrf, db
|
||||
from project.api.schemas import ErrorResponseSchema, UnprocessableEntityResponseSchema
|
||||
from project.oauth2 import require_oauth
|
||||
|
||||
@ -22,23 +22,44 @@ def etag_cache(func):
|
||||
return wrapper
|
||||
|
||||
|
||||
def require_api_access(scopes=None, optional=False):
|
||||
def is_internal_request() -> bool:
|
||||
try:
|
||||
validate_csrf(csrf._get_csrf_token())
|
||||
return True
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def require_api_access(scopes=None):
|
||||
def inner_decorator(func):
|
||||
def wrapped(*args, **kwargs): # see authlib ResourceProtector#__call__
|
||||
try: # pragma: no cover
|
||||
try:
|
||||
require_oauth.acquire_token(scopes)
|
||||
except MissingAuthorizationError as error:
|
||||
if optional:
|
||||
return func(*args, **kwargs)
|
||||
require_oauth.raise_error_response(error)
|
||||
except OAuth2Error as error:
|
||||
require_oauth.raise_error_response(error)
|
||||
except Exception as e:
|
||||
if not current_user or not current_user.is_authenticated:
|
||||
if app.config["API_READ_ANONYM"]:
|
||||
return func(*args, **kwargs)
|
||||
if not is_internal_request():
|
||||
raise e
|
||||
return func(*args, **kwargs)
|
||||
|
||||
scope_list = scopes if type(scopes) is list else [scopes] if scopes else list()
|
||||
security = [{"oauth2AuthCode": scope_list}]
|
||||
|
||||
if not scope_list:
|
||||
security.append(
|
||||
{
|
||||
"oauth2ClientCredentials": scope_list,
|
||||
}
|
||||
)
|
||||
|
||||
annotate(
|
||||
wrapped,
|
||||
"docs",
|
||||
[{"security": security}],
|
||||
)
|
||||
return wrapped
|
||||
|
||||
return inner_decorator
|
||||
|
||||
@ -34,7 +34,6 @@ class UserOrganizationInvitationListResource(BaseResource):
|
||||
@doc(
|
||||
summary="List organization invitations of user",
|
||||
tags=["Users", "Organization Invitations"],
|
||||
security=[{"oauth2": ["user:read"]}],
|
||||
)
|
||||
@use_kwargs(OrganizationInvitationListRequestSchema, location=("query"))
|
||||
@marshal_with(OrganizationInvitationListResponseSchema)
|
||||
@ -53,7 +52,6 @@ class UserOrganizationInvitationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Get organization invitation of user",
|
||||
tags=["Users", "Organization Invitations"],
|
||||
security=[{"oauth2": ["user:read"]}],
|
||||
)
|
||||
@marshal_with(OrganizationInvitationSchema)
|
||||
@require_api_access("user:read")
|
||||
@ -67,7 +65,6 @@ class UserOrganizationInvitationResource(BaseResource):
|
||||
@doc(
|
||||
summary="Delete organization invitation of user",
|
||||
tags=["Users", "Organization Invitations"],
|
||||
security=[{"oauth2": ["user:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("user:write")
|
||||
@ -86,7 +83,6 @@ class UserFavoriteEventListResource(BaseResource):
|
||||
@doc(
|
||||
summary="List favorite events of user",
|
||||
tags=["Users", "Events"],
|
||||
security=[{"oauth2": ["user:read"]}],
|
||||
)
|
||||
@use_kwargs(UserFavoriteEventListRequestSchema, location=("query"))
|
||||
@marshal_with(UserFavoriteEventListResponseSchema)
|
||||
@ -104,7 +100,6 @@ class UserFavoriteEventSearchResource(BaseResource):
|
||||
@doc(
|
||||
summary="Search for favorite events of user",
|
||||
tags=["Users", "Events"],
|
||||
security=[{"oauth2": ["user:read"]}],
|
||||
)
|
||||
@use_kwargs(EventSearchRequestSchema, location=("query"))
|
||||
@marshal_with(EventSearchResponseSchema)
|
||||
@ -124,7 +119,6 @@ class UserFavoriteEventListWriteResource(BaseResource):
|
||||
@doc(
|
||||
summary="Add event to users favorites",
|
||||
tags=["Users", "Events"],
|
||||
security=[{"oauth2": ["user:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("user:write")
|
||||
@ -142,7 +136,6 @@ class UserFavoriteEventListWriteResource(BaseResource):
|
||||
@doc(
|
||||
summary="Remove event from users favorites",
|
||||
tags=["Users", "Events"],
|
||||
security=[{"oauth2": ["user:write"]}],
|
||||
)
|
||||
@marshal_with(None, 204)
|
||||
@require_api_access("user:write")
|
||||
|
||||
@ -258,9 +258,6 @@ def _insert_default_oauth2_client(user_id):
|
||||
metadata = dict()
|
||||
metadata["client_name"] = "Mein Client"
|
||||
metadata["scope"] = " ".join(scope_list)
|
||||
metadata["grant_types"] = ["authorization_code", "refresh_token"]
|
||||
metadata["response_types"] = ["code"]
|
||||
metadata["token_endpoint_auth_method"] = "client_secret_post"
|
||||
metadata["redirect_uris"] = ["/"]
|
||||
client.set_client_metadata(metadata)
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import os
|
||||
from flask_babel import lazy_gettext
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, SubmitField, TextAreaField
|
||||
from wtforms.validators import DataRequired
|
||||
from wtforms.validators import DataRequired, Optional
|
||||
|
||||
from project.api import scopes
|
||||
from project.forms.widgets import MultiCheckboxField
|
||||
@ -13,11 +13,11 @@ from project.utils import split_by_crlf
|
||||
class BaseOAuth2ClientForm(FlaskForm):
|
||||
client_name = StringField(lazy_gettext("Client name"), validators=[DataRequired()])
|
||||
redirect_uris = TextAreaField(
|
||||
lazy_gettext("Redirect URIs"), validators=[DataRequired()]
|
||||
lazy_gettext("Redirect URIs"), validators=[Optional()]
|
||||
)
|
||||
scope = MultiCheckboxField(
|
||||
lazy_gettext("Scopes"),
|
||||
validators=[DataRequired()],
|
||||
validators=[Optional()],
|
||||
choices=[(k, k) for k, v in scopes.items()],
|
||||
)
|
||||
|
||||
|
||||
@ -47,16 +47,7 @@ def create_initial_data():
|
||||
"reference_request:delete",
|
||||
"reference_request:verify",
|
||||
]
|
||||
early_adopter_permissions = [
|
||||
"oauth2_client:create",
|
||||
"oauth2_client:read",
|
||||
"oauth2_client:update",
|
||||
"oauth2_client:delete",
|
||||
"oauth2_token:create",
|
||||
"oauth2_token:read",
|
||||
"oauth2_token:update",
|
||||
"oauth2_token:delete",
|
||||
]
|
||||
early_adopter_permissions = []
|
||||
|
||||
upsert_admin_unit_member_role("admin", "Administrator", admin_permissions)
|
||||
upsert_admin_unit_member_role("event_verifier", "Event expert", event_permissions)
|
||||
|
||||
@ -276,7 +276,7 @@ class AdminUnit(db.Model, TrackableMixin):
|
||||
server_default="0",
|
||||
)
|
||||
)
|
||||
incoming_verification_requests_text = Column(UnicodeText())
|
||||
incoming_verification_requests_text = deferred(Column(UnicodeText()))
|
||||
can_invite_other = deferred(
|
||||
Column(
|
||||
Boolean(),
|
||||
|
||||
@ -22,7 +22,7 @@ class OAuth2Client(db.Model, OAuth2ClientMixin):
|
||||
|
||||
@OAuth2ClientMixin.grant_types.getter
|
||||
def grant_types(self):
|
||||
return ["authorization_code", "refresh_token"]
|
||||
return ["authorization_code", "refresh_token", "client_credentials"]
|
||||
|
||||
@OAuth2ClientMixin.response_types.getter
|
||||
def response_types(self):
|
||||
|
||||
@ -71,6 +71,10 @@ class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
|
||||
return db.session.get(User, authorization_code.user_id)
|
||||
|
||||
|
||||
class ClientCredentialsGrant(grants.ClientCredentialsGrant):
|
||||
TOKEN_ENDPOINT_AUTH_METHODS = ["client_secret_basic", "client_secret_post"]
|
||||
|
||||
|
||||
class OpenIDCode(_OpenIDCode):
|
||||
def exists_nonce(self, nonce, request):
|
||||
return exists_nonce(nonce, request)
|
||||
@ -176,6 +180,7 @@ def config_oauth(app):
|
||||
AuthorizationCodeGrant,
|
||||
[CodeChallenge(required=True), OpenIDCode()],
|
||||
)
|
||||
authorization.register_grant(ClientCredentialsGrant)
|
||||
authorization.register_grant(RefreshTokenGrant)
|
||||
|
||||
# support revocation
|
||||
|
||||
@ -44,6 +44,8 @@ def set_manage_admin_unit_cookie(response):
|
||||
@app.after_request
|
||||
def set_response_headers(response):
|
||||
if request and request.endpoint:
|
||||
if request.endpoint.startswith("api_"):
|
||||
return response
|
||||
if request.endpoint != "static" and request.endpoint != "widget_event_dates":
|
||||
response.headers["X-Frame-Options"] = "SAMEORIGIN"
|
||||
|
||||
|
||||
@ -411,7 +411,7 @@ const WidgetConfigurator = {
|
||||
}),
|
||||
computed: {
|
||||
iFrameSource() {
|
||||
return `${window.location.origin}/static/widget/${this.widgetType}.html`;
|
||||
return `${window.location.origin}/custom_widget/${this.widgetType}`;
|
||||
},
|
||||
organizationId() {
|
||||
return this.$route.params.organization_id;
|
||||
|
||||
@ -38,11 +38,11 @@
|
||||
var googleTagManager = false;
|
||||
|
||||
if (customId != null) {
|
||||
var url = baseUrl + "/api/v1/custom-widgets/" + customId;
|
||||
var url = baseUrl + "/js/wlcw/" + customId;
|
||||
|
||||
customWidgetData = loadJSON(url);
|
||||
var settings = customWidgetData.settings;
|
||||
src = baseUrl + "/static/widget/" + customWidgetData.widget_type + ".html";
|
||||
src = baseUrl + "/custom_widget/" + customWidgetData.widget_type;
|
||||
|
||||
if (settings.hasOwnProperty('iFrameAutoResize') && settings.iFrameAutoResize != null) {
|
||||
resize = settings.iFrameAutoResize;
|
||||
@ -233,6 +233,8 @@
|
||||
xmlhttp.overrideMimeType(mimeType);
|
||||
}
|
||||
|
||||
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token() }}");
|
||||
|
||||
xmlhttp.send();
|
||||
return xmlhttp.responseText;
|
||||
}
|
||||
|
||||
@ -1687,24 +1687,6 @@ $('#allday').on('change', function() {
|
||||
</script>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_ajax_csrf_script() %}
|
||||
<script type="text/javascript">
|
||||
{{ render_ajax_csrf() }}
|
||||
</script>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_ajax_csrf() %}
|
||||
var csrf_token = "{{ csrf_token() }}";
|
||||
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(xhr, settings) {
|
||||
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
|
||||
xhr.setRequestHeader("X-CSRFToken", csrf_token);
|
||||
}
|
||||
}
|
||||
});
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_form_scripts() %}
|
||||
<script src="{{ url_for('static', filename='ext/jquery-ui.1.12.1/jquery-ui.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='ext/jquery-ui-i18n.1.11.4.min.js')}}"></script>
|
||||
@ -1712,8 +1694,6 @@ $('#allday').on('change', function() {
|
||||
<script src="{{ url_for('static', filename='ext/select2.i18n.de.4.1.0-beta.1.min.js')}}"></script>
|
||||
<script src="{{ url_for('static', filename='ext/jquery.timepicker.1.13.18.min.js')}}"></script>
|
||||
<script type="text/javascript">
|
||||
{{ render_ajax_csrf() }}
|
||||
|
||||
$.datepicker.setDefaults($.datepicker.regional["de"]);
|
||||
$.fn.select2.defaults.set("language", "de");
|
||||
|
||||
|
||||
@ -96,6 +96,7 @@
|
||||
<script src="/static/ext/moment.2.24.0.with-locales.min.js"></script>
|
||||
<script>
|
||||
axios.defaults.baseURL = window.location.origin;
|
||||
axios.defaults.headers.common["X-CSRFToken"] = "[% csrf_token() %]";
|
||||
moment.locale("de");
|
||||
|
||||
Vue.component('event-warning-pills', {
|
||||
@ -234,6 +234,7 @@
|
||||
</div>
|
||||
<script>
|
||||
axios.defaults.baseURL = window.location.origin;
|
||||
axios.defaults.headers.common["X-CSRFToken"] = "[% csrf_token() %]";
|
||||
moment.locale("de");
|
||||
|
||||
const localizedMessages = {
|
||||
@ -138,6 +138,16 @@
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<script type="text/javascript">
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(xhr, settings) {
|
||||
if (!/^(HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
|
||||
xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token() }}");
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
{% block header %}
|
||||
{% endblock %}
|
||||
{%- endblock head %}
|
||||
|
||||
@ -331,6 +331,7 @@
|
||||
});
|
||||
|
||||
axios.defaults.baseURL = "{{ get_base_url() }}";
|
||||
axios.defaults.headers.common["X-CSRFToken"] = "{{ csrf_token() }}";
|
||||
axios.interceptors.request.use(
|
||||
function (config) {
|
||||
if (config) {
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_ajax_csrf_script %}
|
||||
{%- block title -%}
|
||||
{{ _('Export') }}
|
||||
{%- endblock -%}
|
||||
{% block header %}
|
||||
{{ render_ajax_csrf_script() }}
|
||||
<script>
|
||||
function submit_async() {
|
||||
$("#submit_async"). prop("disabled", true);
|
||||
|
||||
@ -12,11 +12,9 @@
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
{% if current_user.has_permission('oauth2_client:create') %}
|
||||
<div class="my-4">
|
||||
<a class="btn btn-outline-secondary my-1" href="{{ url_for('oauth2_client_create') }}" role="button"><i class="fa fa-plus"></i> {{ _('Create OAuth2 client') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered table-hover table-striped">
|
||||
|
||||
@ -42,7 +42,6 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% if current_user.has_permission('oauth2_client:read') %}
|
||||
<h2>{{ _('Developer') }}</h2>
|
||||
|
||||
<div class="list-group">
|
||||
@ -51,6 +50,5 @@
|
||||
<i class="fa fa-caret-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
@ -175,7 +175,7 @@ def admin_unit_update(id):
|
||||
@auth_required()
|
||||
@manage_required("admin_unit:update")
|
||||
def admin_unit_request_deletion(id):
|
||||
admin_unit = g.admin_unit
|
||||
admin_unit = g.manage_admin_unit
|
||||
|
||||
if admin_unit.deletion_requested_at: # pragma: no cover
|
||||
return redirect(url_for("admin_unit_cancel_deletion", id=admin_unit.id))
|
||||
@ -208,7 +208,7 @@ def admin_unit_request_deletion(id):
|
||||
@auth_required()
|
||||
@manage_required("admin_unit:update")
|
||||
def admin_unit_cancel_deletion(id):
|
||||
admin_unit = g.admin_unit
|
||||
admin_unit = g.manage_admin_unit
|
||||
|
||||
if not admin_unit.deletion_requested_at: # pragma: no cover
|
||||
return redirect(url_for("admin_unit_request_deletion", id=admin_unit.id))
|
||||
|
||||
8
project/views/custom_widget.py
Normal file
8
project/views/custom_widget.py
Normal file
@ -0,0 +1,8 @@
|
||||
from project import app
|
||||
|
||||
|
||||
@app.route("/custom_widget/<string:type>")
|
||||
def custom_widget_type(type: str):
|
||||
env = app.jinja_env.overlay(variable_start_string="[%", variable_end_string="%]")
|
||||
template = env.get_template(f"custom_widget/{type}.html")
|
||||
return template.render()
|
||||
@ -1,12 +1,14 @@
|
||||
from flask import request
|
||||
from flask.json import jsonify
|
||||
from flask_babel import gettext
|
||||
from flask_cors import cross_origin
|
||||
from flask_security import url_for_security
|
||||
from flask_security.utils import localize_callback
|
||||
|
||||
from project import app, csrf
|
||||
from project.api.custom_widget.schemas import CustomWidgetSchema
|
||||
from project.maputils import find_gmaps_places, get_gmaps_place
|
||||
from project.models import AdminUnit
|
||||
from project.models import AdminUnit, CustomWidget
|
||||
from project.services.place import get_event_places
|
||||
from project.services.user import find_user_by_email
|
||||
from project.utils import get_place_str
|
||||
@ -124,3 +126,11 @@ def js_autocomplete_gmaps_place():
|
||||
gmaps_id = request.args["gmaps_id"]
|
||||
place = get_gmaps_place(gmaps_id)
|
||||
return jsonify(place)
|
||||
|
||||
|
||||
@app.route("/js/wlcw/<int:id>")
|
||||
@cross_origin()
|
||||
def js_widget_loader_custom_widget(id: int):
|
||||
widget = CustomWidget.query.get_or_404(id)
|
||||
schema = CustomWidgetSchema()
|
||||
return schema.dump(widget)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
from flask import flash, redirect, render_template, url_for
|
||||
from flask_babel import gettext
|
||||
from flask_security import current_user, permissions_required
|
||||
from flask_security import current_user
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from project import app, db
|
||||
@ -21,7 +21,6 @@ from project.views.utils import (
|
||||
|
||||
|
||||
@app.route("/oauth2_client/create", methods=("GET", "POST"))
|
||||
@permissions_required("oauth2_client:create")
|
||||
def oauth2_client_create():
|
||||
form = CreateOAuth2ClientForm()
|
||||
|
||||
@ -46,7 +45,6 @@ def oauth2_client_create():
|
||||
|
||||
|
||||
@app.route("/oauth2_client/<int:id>/update", methods=("GET", "POST"))
|
||||
@permissions_required("oauth2_client:update")
|
||||
def oauth2_client_update(id):
|
||||
oauth2_client = OAuth2Client.query.get_or_404(id)
|
||||
owner_access_or_401(oauth2_client.user_id)
|
||||
@ -73,7 +71,6 @@ def oauth2_client_update(id):
|
||||
|
||||
|
||||
@app.route("/oauth2_client/<int:id>/delete", methods=("GET", "POST"))
|
||||
@permissions_required("oauth2_client:delete")
|
||||
def oauth2_client_delete(id):
|
||||
oauth2_client = OAuth2Client.query.get_or_404(id)
|
||||
owner_access_or_401(oauth2_client.user_id)
|
||||
@ -101,7 +98,6 @@ def oauth2_client_delete(id):
|
||||
|
||||
|
||||
@app.route("/oauth2_client/<int:id>")
|
||||
@permissions_required("oauth2_client:read")
|
||||
def oauth2_client(id):
|
||||
oauth2_client = OAuth2Client.query.get_or_404(id)
|
||||
owner_access_or_401(oauth2_client.user_id)
|
||||
@ -113,7 +109,6 @@ def oauth2_client(id):
|
||||
|
||||
|
||||
@app.route("/oauth2_clients")
|
||||
@permissions_required("oauth2_client:read")
|
||||
def oauth2_clients():
|
||||
oauth2_clients = (
|
||||
OAuth2Client.query.filter(OAuth2Client.user_id == current_user.id)
|
||||
|
||||
@ -317,8 +317,7 @@ def manage_required(permission=None):
|
||||
url_for("manage_admin_unit", id=admin_unit.id)
|
||||
)
|
||||
|
||||
g.admin_unit = admin_unit
|
||||
|
||||
set_current_admin_unit(admin_unit)
|
||||
return f(id, *args, **kwargs)
|
||||
|
||||
return decorated_function
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
def test_read(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
custom_widget_id = seeder.insert_event_custom_widget(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_custom_widget", id=custom_widget_id)
|
||||
@ -8,7 +12,7 @@ def test_read(client, seeder, utils):
|
||||
assert response.json["settings"]["color"] == "black"
|
||||
|
||||
|
||||
def test_put(client, seeder, utils, app, db):
|
||||
def test_put(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
custom_widget_id = seeder.insert_event_custom_widget(admin_unit_id)
|
||||
|
||||
@ -24,7 +28,7 @@ def test_put(client, seeder, utils, app, db):
|
||||
assert custom_widget.widget_type == "search"
|
||||
|
||||
|
||||
def test_patch(client, seeder, utils, app, db):
|
||||
def test_patch(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
custom_widget_id = seeder.insert_event_custom_widget(admin_unit_id)
|
||||
|
||||
@ -40,7 +44,7 @@ def test_patch(client, seeder, utils, app, db):
|
||||
assert custom_widget.widget_type == "search"
|
||||
|
||||
|
||||
def test_delete(client, seeder, utils, app, db):
|
||||
def test_delete(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
custom_widget_id = seeder.insert_event_custom_widget(admin_unit_id)
|
||||
|
||||
|
||||
@ -1,3 +1,9 @@
|
||||
def test_read(client, seeder, utils):
|
||||
response = utils.get_endpoint("api_v1_dump")
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
url = utils.get_url("api_v1_dump")
|
||||
response = utils.get_json(url)
|
||||
utils.assert_response_notFound(response)
|
||||
|
||||
@ -3,10 +3,11 @@ import base64
|
||||
import pytest
|
||||
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, app, db, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_read(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
with app.app_context():
|
||||
@ -20,12 +21,21 @@ def test_read(client, app, db, seeder, utils):
|
||||
db.session.commit()
|
||||
|
||||
url = utils.get_url("api_v1_event", id=event_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert response.json["status"] == "scheduled"
|
||||
|
||||
|
||||
def test_read_otherDraft(client, app, db, seeder, utils):
|
||||
def test_read_anonym(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
app.config["API_READ_ANONYM"] = True
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_event", id=event_id)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_read_otherDraft(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id, draft=True)
|
||||
|
||||
url = utils.get_url("api_v1_event", id=event_id)
|
||||
@ -33,7 +43,7 @@ def test_read_otherDraft(client, app, db, seeder, utils):
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
|
||||
def test_read_myDraft(client, app, db, seeder, utils):
|
||||
def test_read_myDraft(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id, draft=True)
|
||||
|
||||
@ -43,7 +53,7 @@ def test_read_myDraft(client, app, db, seeder, utils):
|
||||
assert response.json["public_status"] == "draft"
|
||||
|
||||
|
||||
def test_read_otherUnverified(client, app, db, seeder, utils):
|
||||
def test_read_otherUnverified(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False, admin_unit_verified=False)
|
||||
event_id = seeder.create_event(admin_unit_id, draft=True)
|
||||
|
||||
@ -52,7 +62,7 @@ def test_read_otherUnverified(client, app, db, seeder, utils):
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
|
||||
def test_read_myUnverified(client, app, db, seeder, utils):
|
||||
def test_read_myUnverified(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(admin_unit_verified=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -61,8 +71,8 @@ def test_read_myUnverified(client, app, db, seeder, utils):
|
||||
utils.assert_response_ok(response)
|
||||
|
||||
|
||||
def test_read_co_organizers(client, app, db, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_read_co_organizers(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
|
||||
admin_unit_id
|
||||
)
|
||||
@ -74,20 +84,20 @@ def test_read_co_organizers(client, app, db, seeder, utils):
|
||||
assert response.json["co_organizers"][1]["id"] == organizer_b_id
|
||||
|
||||
|
||||
def test_list(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_list(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
seeder.create_event_unverified()
|
||||
|
||||
url = utils.get_url("api_v1_event_list")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == event_id
|
||||
|
||||
|
||||
def test_search(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_search(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
image_id = seeder.upsert_default_image()
|
||||
seeder.assign_image_to_event(event_id, image_id)
|
||||
@ -95,49 +105,52 @@ def test_search(client, seeder, utils):
|
||||
seeder.create_event_unverified()
|
||||
|
||||
url = utils.get_url("api_v1_event_search")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == event_id
|
||||
|
||||
|
||||
def test_search_is_favored(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_search_is_favored(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
seeder.add_favorite_event(user_id, event_id)
|
||||
|
||||
url = utils.get_url("api_v1_event_search")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == event_id
|
||||
assert response.json["items"][0]["is_favored"]
|
||||
|
||||
|
||||
def test_dates(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
def test_dates(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
url = utils.get_url("api_v1_event_dates", id=event_id)
|
||||
utils.get_ok(url)
|
||||
response = utils.get_json(url)
|
||||
utils.assert_response_ok(response)
|
||||
|
||||
event_id = seeder.create_event(admin_unit_id, draft=True)
|
||||
url = utils.get_url("api_v1_event_dates", id=event_id)
|
||||
response = utils.get(url)
|
||||
response = utils.get_json(url)
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
_, _, event_id = seeder.create_event_unverified()
|
||||
url = utils.get_url("api_v1_event_dates", id=event_id)
|
||||
response = utils.get(url)
|
||||
response = utils.get_json(url)
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
event_id = seeder.create_event(
|
||||
admin_unit_id, recurrence_rule="RRULE:FREQ=DAILY;COUNT=51"
|
||||
)
|
||||
url = utils.get_url("api_v1_event_dates", id=event_id)
|
||||
utils.get_ok(url)
|
||||
response = utils.get_json(url)
|
||||
utils.assert_response_ok(response)
|
||||
url = utils.get_url("api_v1_event_dates", id=event_id, page=2)
|
||||
utils.get_ok(url)
|
||||
response = utils.get_json(url)
|
||||
utils.assert_response_ok(response)
|
||||
|
||||
|
||||
def test_dates_myDraft(client, seeder, utils):
|
||||
def test_dates_myDraft(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id, draft=True)
|
||||
|
||||
@ -146,7 +159,7 @@ def test_dates_myDraft(client, seeder, utils):
|
||||
utils.assert_response_ok(response)
|
||||
|
||||
|
||||
def test_dates_myUnverified(client, seeder, utils):
|
||||
def test_dates_myUnverified(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(admin_unit_verified=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -180,7 +193,7 @@ def create_put(
|
||||
@pytest.mark.parametrize(
|
||||
"variant", ["normal", "legacy", "recurrence", "two_date_definitions"]
|
||||
)
|
||||
def test_put(client, seeder, utils, app, db, mocker, variant):
|
||||
def test_put(client, seeder: Seeder, utils: UtilActions, app, db, mocker, variant):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -270,7 +283,7 @@ def test_put(client, seeder, utils, app, db, mocker, variant):
|
||||
assert len_dates == 1
|
||||
|
||||
|
||||
def test_put_invalidRecurrenceRule(client, seeder, utils, app):
|
||||
def test_put_invalidRecurrenceRule(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -284,7 +297,7 @@ def test_put_invalidRecurrenceRule(client, seeder, utils, app):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_put_missingName(client, seeder, utils, app):
|
||||
def test_put_missingName(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -298,7 +311,7 @@ def test_put_missingName(client, seeder, utils, app):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_put_missingPlace(client, seeder, utils, app):
|
||||
def test_put_missingPlace(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -312,7 +325,7 @@ def test_put_missingPlace(client, seeder, utils, app):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_put_placeFromAnotherAdminUnit(client, seeder, utils, app):
|
||||
def test_put_placeFromAnotherAdminUnit(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
@ -326,7 +339,7 @@ def test_put_placeFromAnotherAdminUnit(client, seeder, utils, app):
|
||||
utils.assert_response_api_error(response, "Check Violation")
|
||||
|
||||
|
||||
def test_put_missingOrganizer(client, seeder, utils, app):
|
||||
def test_put_missingOrganizer(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -340,7 +353,9 @@ def test_put_missingOrganizer(client, seeder, utils, app):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_put_organizerFromAnotherAdminUnit(client, seeder, utils, app):
|
||||
def test_put_organizerFromAnotherAdminUnit(
|
||||
client, seeder: Seeder, utils: UtilActions, app
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -354,7 +369,7 @@ def test_put_organizerFromAnotherAdminUnit(client, seeder, utils, app):
|
||||
utils.assert_response_api_error(response, "Check Violation")
|
||||
|
||||
|
||||
def test_put_co_organizers(client, seeder, utils, app, db):
|
||||
def test_put_co_organizers(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -381,7 +396,9 @@ def test_put_co_organizers(client, seeder, utils, app, db):
|
||||
assert event.co_organizers[1].id == organizer_b_id
|
||||
|
||||
|
||||
def test_put_co_organizerFromAnotherAdminUnit(client, seeder, utils, app):
|
||||
def test_put_co_organizerFromAnotherAdminUnit(
|
||||
client, seeder: Seeder, utils: UtilActions, app
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -401,7 +418,7 @@ def test_put_co_organizerFromAnotherAdminUnit(client, seeder, utils, app):
|
||||
utils.assert_response_api_error(response, "Check Violation")
|
||||
|
||||
|
||||
def test_put_invalidDateFormat(client, seeder, utils, app):
|
||||
def test_put_invalidDateFormat(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -414,7 +431,7 @@ def test_put_invalidDateFormat(client, seeder, utils, app):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_put_startAfterEnd(client, seeder: Seeder, utils, app):
|
||||
def test_put_startAfterEnd(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -429,7 +446,9 @@ def test_put_startAfterEnd(client, seeder: Seeder, utils, app):
|
||||
utils.assert_response_bad_request(response)
|
||||
|
||||
|
||||
def test_put_durationMoreThanMaxAllowedDuration(client, seeder, utils, app):
|
||||
def test_put_durationMoreThanMaxAllowedDuration(
|
||||
client, seeder: Seeder, utils: UtilActions, app
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -444,7 +463,7 @@ def test_put_durationMoreThanMaxAllowedDuration(client, seeder, utils, app):
|
||||
utils.assert_response_bad_request(response)
|
||||
|
||||
|
||||
def test_put_categories(client, seeder, utils, app, db):
|
||||
def test_put_categories(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -465,7 +484,7 @@ def test_put_categories(client, seeder, utils, app, db):
|
||||
assert event.category.name == "Art"
|
||||
|
||||
|
||||
def test_put_dateWithTimezone(client, seeder, utils, app, db):
|
||||
def test_put_dateWithTimezone(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
from project.dateutils import create_berlin_date
|
||||
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
@ -488,7 +507,7 @@ def test_put_dateWithTimezone(client, seeder, utils, app, db):
|
||||
assert event.date_definitions[0].start == expected
|
||||
|
||||
|
||||
def test_put_dateWithoutTimezone(client, seeder, utils, app, db):
|
||||
def test_put_dateWithoutTimezone(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
from project.dateutils import create_berlin_date
|
||||
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
@ -511,7 +530,9 @@ def test_put_dateWithoutTimezone(client, seeder, utils, app, db):
|
||||
assert event.date_definitions[0].start == expected
|
||||
|
||||
|
||||
def test_put_referencedEventUpdate_sendsMail(client, seeder, utils, app, mocker):
|
||||
def test_put_referencedEventUpdate_sendsMail(
|
||||
client, seeder: Seeder, utils: UtilActions, app, mocker
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event_via_api(admin_unit_id)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -532,7 +553,7 @@ def test_put_referencedEventUpdate_sendsMail(client, seeder, utils, app, mocker)
|
||||
|
||||
|
||||
def test_put_referencedEventNonDirtyUpdate_doesNotSendMail(
|
||||
client, seeder, utils, app, mocker
|
||||
client, seeder: Seeder, utils: UtilActions, app, mocker
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event_via_api(admin_unit_id)
|
||||
@ -553,7 +574,7 @@ def test_put_referencedEventNonDirtyUpdate_doesNotSendMail(
|
||||
mail_mock.assert_not_called()
|
||||
|
||||
|
||||
def test_patch(client, seeder, utils, app, db):
|
||||
def test_patch(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -569,7 +590,7 @@ def test_patch(client, seeder, utils, app, db):
|
||||
assert event.description == "Neu"
|
||||
|
||||
|
||||
def test_patch_startAfterEnd(client, seeder, utils, app, db):
|
||||
def test_patch_startAfterEnd(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -586,7 +607,9 @@ def test_patch_startAfterEnd(client, seeder, utils, app, db):
|
||||
utils.assert_response_bad_request(response)
|
||||
|
||||
|
||||
def test_patch_referencedEventUpdate_sendsMail(client, seeder, utils, app, mocker):
|
||||
def test_patch_referencedEventUpdate_sendsMail(
|
||||
client, seeder: Seeder, utils: UtilActions, app, mocker
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event_via_api(admin_unit_id)
|
||||
|
||||
@ -602,7 +625,9 @@ def test_patch_referencedEventUpdate_sendsMail(client, seeder, utils, app, mocke
|
||||
utils.assert_send_mail_called(mail_mock, "other@test.de")
|
||||
|
||||
|
||||
def test_patch_photo(client, seeder, utils, app, db, requests_mock):
|
||||
def test_patch_photo(
|
||||
client, seeder: Seeder, utils: UtilActions, app, db, requests_mock
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -625,7 +650,7 @@ def test_patch_photo(client, seeder, utils, app, db, requests_mock):
|
||||
assert event.photo.encoding_format == "image/png"
|
||||
|
||||
|
||||
def test_patch_photo_copyright(client, db, seeder, utils, app):
|
||||
def test_patch_photo_copyright(client, db, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
image_id = seeder.upsert_default_image()
|
||||
@ -647,7 +672,7 @@ def test_patch_photo_copyright(client, db, seeder, utils, app):
|
||||
assert event.photo.copyright_text == "Heiner"
|
||||
|
||||
|
||||
def test_patch_photo_delete(client, db, seeder, utils, app):
|
||||
def test_patch_photo_delete(client, db, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
image_id = seeder.upsert_default_image()
|
||||
@ -670,7 +695,7 @@ def test_patch_photo_delete(client, db, seeder, utils, app):
|
||||
assert image is None
|
||||
|
||||
|
||||
def test_delete(client, seeder, utils, app, db):
|
||||
def test_delete(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -685,8 +710,8 @@ def test_delete(client, seeder, utils, app, db):
|
||||
assert event is None
|
||||
|
||||
|
||||
def test_report_mail(client, seeder, utils, app, mocker):
|
||||
user_id, admin_unit_id = seeder.setup_base(admin=False, log_in=False)
|
||||
def test_report_mail(client, seeder: Seeder, utils: UtilActions, app, mocker):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(admin=False, user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
seeder.create_user(email="admin@test.de", admin=True)
|
||||
seeder.create_user(email="normal@test.de", admin=False)
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
def test_list(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_list(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
seeder.create_event(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_event_category_list")
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
@ -1,17 +1,22 @@
|
||||
def test_read(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
seeder.create_event(admin_unit_id)
|
||||
url = utils.get_url("api_v1_event_date", id=1)
|
||||
utils.get_ok(url)
|
||||
response = utils.get_json(url)
|
||||
utils.assert_response_ok(response)
|
||||
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
draft_url = utils.get_url("api_v1_event_date", id=2)
|
||||
response = utils.get(draft_url)
|
||||
response = utils.get_json(draft_url)
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
seeder.create_event_unverified()
|
||||
unverified_url = utils.get_url("api_v1_event_date", id=3)
|
||||
response = utils.get(unverified_url)
|
||||
response = utils.get_json(unverified_url)
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
seeder.authorize_api_access(user_id, admin_unit_id)
|
||||
@ -19,7 +24,7 @@ def test_read(client, seeder, utils):
|
||||
utils.assert_response_ok(response)
|
||||
|
||||
|
||||
def test_read_myUnverified(client, seeder, utils):
|
||||
def test_read_myUnverified(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access(admin_unit_verified=False)
|
||||
seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -28,75 +33,75 @@ def test_read_myUnverified(client, seeder, utils):
|
||||
utils.assert_response_ok(response)
|
||||
|
||||
|
||||
def test_list(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
def test_list(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
seeder.create_event(admin_unit_id)
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
seeder.create_event_unverified()
|
||||
|
||||
url = utils.get_url("api_v1_event_date_list")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == 1
|
||||
|
||||
|
||||
def test_search(client, seeder, utils, app, db):
|
||||
def test_search(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
from project.dateutils import create_berlin_date
|
||||
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
start = create_berlin_date(2020, 10, 3, 10)
|
||||
event_id = seeder.create_event(admin_unit_id, start=start)
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
seeder.create_event_unverified()
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", sort="-rating")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["event"]["id"] == event_id
|
||||
assert response.json["items"][0]["start"] == "2020-10-03T10:00:00+02:00"
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", keyword="name")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", category_id=0)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", category_id=2000)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", weekday=1)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
url = utils.get_url(
|
||||
"api_v1_event_date_search", date_from="2020-10-03", date_to="2021-10-03"
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
url = utils.get_url(
|
||||
"api_v1_event_date_search", coordinate="51.9077888,10.4333312", distance=500
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
url = utils.get_url("api_v1_event_date_search", organizer_id=organizer_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
event_place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
url = utils.get_url("api_v1_event_date_search", event_place_id=event_place_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", organization_id=admin_unit_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
|
||||
listed_event_id = seeder.create_event(admin_unit_id)
|
||||
event_list_id = seeder.create_event_list(admin_unit_id, listed_event_id)
|
||||
url = utils.get_url("api_v1_event_date_search", event_list_id=event_list_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["event"]["id"] == listed_event_id
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", status="scheduled")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 2
|
||||
|
||||
with app.app_context():
|
||||
@ -107,18 +112,18 @@ def test_search(client, seeder, utils, app, db):
|
||||
db.session.commit()
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", status="scheduled")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search", status=["scheduled", "cancelled"])
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 2
|
||||
|
||||
|
||||
def test_search_oneDay(client, seeder, utils):
|
||||
def test_search_oneDay(client, seeder: Seeder, utils: UtilActions):
|
||||
from project.dateutils import create_berlin_date
|
||||
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
|
||||
start = create_berlin_date(2020, 10, 3, 10)
|
||||
end = create_berlin_date(2020, 10, 3, 11)
|
||||
@ -128,18 +133,18 @@ def test_search_oneDay(client, seeder, utils):
|
||||
url = utils.get_url(
|
||||
"api_v1_event_date_search", date_from="2020-10-03", date_to="2020-10-03"
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["event"]["id"] == event_id
|
||||
|
||||
|
||||
def test_search_is_favored(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_search_is_favored(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
seeder.add_favorite_event(user_id, event_id)
|
||||
|
||||
url = utils.get_url("api_v1_event_date_search")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["event"]["id"] == event_id
|
||||
assert response.json["items"][0]["event"]["is_favored"]
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
def test_read(client, app, db, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_list_id = seeder.create_event_list(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_event_list_model", id=event_list_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert response.json["id"] == event_list_id
|
||||
|
||||
|
||||
def test_put(client, seeder, utils, app, db):
|
||||
def test_put(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
event_list_id = seeder.create_event_list(admin_unit_id)
|
||||
|
||||
@ -22,7 +26,7 @@ def test_put(client, seeder, utils, app, db):
|
||||
assert event_list.name == "Neuer Name"
|
||||
|
||||
|
||||
def test_patch(client, seeder, utils, app, db):
|
||||
def test_patch(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
event_list_id = seeder.create_event_list(admin_unit_id)
|
||||
|
||||
@ -37,7 +41,7 @@ def test_patch(client, seeder, utils, app, db):
|
||||
assert event_list.name == "Neuer Name"
|
||||
|
||||
|
||||
def test_delete(client, seeder, utils, app, db):
|
||||
def test_delete(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
event_list_id = seeder.create_event_list(admin_unit_id)
|
||||
|
||||
@ -52,18 +56,18 @@ def test_delete(client, seeder, utils, app, db):
|
||||
assert event_list is None
|
||||
|
||||
|
||||
def test_events(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
def test_events(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
event_list_id = seeder.create_event_list(admin_unit_id, event_id)
|
||||
|
||||
url = utils.get_url("api_v1_event_list_event_list", id=event_list_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == event_id
|
||||
|
||||
|
||||
def test_events_put(client, seeder, utils, app, db):
|
||||
def test_events_put(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
event_list_id = seeder.create_event_list(admin_unit_id)
|
||||
@ -82,7 +86,7 @@ def test_events_put(client, seeder, utils, app, db):
|
||||
assert event_list.events[0].id == event_id
|
||||
|
||||
|
||||
def test_events_delete(client, seeder, utils, app, db):
|
||||
def test_events_delete(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
event_list_id = seeder.create_event_list(admin_unit_id, event_id)
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
def test_read(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
(
|
||||
other_user_id,
|
||||
other_admin_unit_id,
|
||||
@ -8,4 +12,4 @@ def test_read(client, seeder, utils):
|
||||
) = seeder.create_any_reference(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_event_reference", id=reference_id)
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
@ -1,27 +1,30 @@
|
||||
import pytest
|
||||
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
def test_read(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(admin=True, log_in=False)
|
||||
|
||||
def test_read(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
|
||||
url = utils.get_url("api_v1_organization", id=admin_unit_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert "can_verify_other" not in response.json
|
||||
|
||||
seeder.authorize_api_access(user_id, admin_unit_id)
|
||||
|
||||
response = utils.get_json(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert "can_verify_other" in response.json
|
||||
|
||||
|
||||
def test_list(client, seeder, utils):
|
||||
seeder.setup_base()
|
||||
def test_list(client, seeder: Seeder, utils: UtilActions):
|
||||
seeder.setup_api_access(user_access=False)
|
||||
url = utils.get_url("api_v1_organization_list", keyword="crew")
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_list_unverified(client, app, seeder, utils):
|
||||
_, verified_admin_unit_id = seeder.setup_base(
|
||||
def test_list_unverified(client, app, seeder: Seeder, utils: UtilActions):
|
||||
user_id, verified_admin_unit_id = seeder.setup_base(
|
||||
email="verified@test.de",
|
||||
log_in=False,
|
||||
name="Verified",
|
||||
@ -33,17 +36,18 @@ def test_list_unverified(client, app, seeder, utils):
|
||||
name="Unverified",
|
||||
admin_unit_verified=False,
|
||||
)
|
||||
seeder.grant_client_credentials_api_access(user_id)
|
||||
|
||||
# Unauthorisierte Nutzer sehen nur verifizierte Organisationen
|
||||
url = utils.get_url("api_v1_organization_list")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == verified_admin_unit_id
|
||||
|
||||
# user_id1 sieht verified_admin_unit_id, weil sie verifiziert ist,
|
||||
# aber nicht unverified_admin_unit_id, weil sie nicht verifiziert ist.
|
||||
utils.login("verified@test.de")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == verified_admin_unit_id
|
||||
|
||||
@ -56,7 +60,7 @@ def test_list_unverified(client, app, seeder, utils):
|
||||
|
||||
utils.logout()
|
||||
utils.login("admin@eventcally.com")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 3
|
||||
assert response.json["items"][0]["id"] == eventcally_id
|
||||
assert response.json["items"][1]["id"] == unverified_admin_unit_id
|
||||
@ -66,12 +70,12 @@ def test_list_unverified(client, app, seeder, utils):
|
||||
seeder.create_user("admin@test.de", admin=True)
|
||||
utils.logout()
|
||||
utils.login("admin@test.de")
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 3
|
||||
|
||||
|
||||
def test_event_date_search(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
def test_event_date_search(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
seeder.create_event_unverified()
|
||||
@ -79,7 +83,7 @@ def test_event_date_search(client, seeder, utils):
|
||||
url = utils.get_url(
|
||||
"api_v1_organization_event_date_search", id=admin_unit_id, sort="-rating"
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["event"]["id"] == event_id
|
||||
|
||||
@ -90,14 +94,14 @@ def test_event_date_search(client, seeder, utils):
|
||||
assert response.json["items"][1]["event"]["public_status"] == "draft"
|
||||
|
||||
|
||||
def test_event_search(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
def test_event_search(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
seeder.create_event_unverified()
|
||||
|
||||
url = utils.get_url("api_v1_organization_event_search", id=admin_unit_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == event_id
|
||||
|
||||
@ -111,17 +115,17 @@ def test_event_search(client, seeder, utils):
|
||||
)
|
||||
|
||||
|
||||
def test_organizers(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_organizers(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
|
||||
url = utils.get_url(
|
||||
"api_v1_organization_organizer_list", id=admin_unit_id, name="crew"
|
||||
)
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_organizers_post(client, seeder, utils, app):
|
||||
def test_organizers_post(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
|
||||
url = utils.get_url("api_v1_organization_organizer_list", id=admin_unit_id)
|
||||
@ -140,13 +144,13 @@ def test_organizers_post(client, seeder, utils, app):
|
||||
assert organizer is not None
|
||||
|
||||
|
||||
def test_events(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
def test_events(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
|
||||
url = utils.get_url("api_v1_organization_event_list", id=admin_unit_id)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == event_id
|
||||
|
||||
@ -178,7 +182,7 @@ def prepare_events_post_data(seeder, utils, legacy=False):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("variant", ["allday", "legacy", "two_date_definitions"])
|
||||
def test_events_post(client, seeder, utils, app, variant):
|
||||
def test_events_post(client, seeder: Seeder, utils: UtilActions, app, variant):
|
||||
url, data, admin_unit_id, place_id, organizer_id = prepare_events_post_data(
|
||||
seeder, utils, variant == "legacy"
|
||||
)
|
||||
@ -215,7 +219,7 @@ def test_events_post(client, seeder, utils, app, variant):
|
||||
assert len(event.date_definitions) == 1
|
||||
|
||||
|
||||
def test_events_post_co_organizers(client, seeder, utils, app, db):
|
||||
def test_events_post_co_organizers(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
url, data, admin_unit_id, place_id, organizer_id = prepare_events_post_data(
|
||||
seeder, utils
|
||||
)
|
||||
@ -239,7 +243,7 @@ def test_events_post_co_organizers(client, seeder, utils, app, db):
|
||||
assert event.co_organizers[1].id == organizer_b_id
|
||||
|
||||
|
||||
def test_events_post_photo_no_data(client, seeder, utils, app):
|
||||
def test_events_post_photo_no_data(client, seeder: Seeder, utils: UtilActions, app):
|
||||
url, data, admin_unit_id, place_id, organizer_id = prepare_events_post_data(
|
||||
seeder, utils
|
||||
)
|
||||
@ -252,7 +256,7 @@ def test_events_post_photo_no_data(client, seeder, utils, app):
|
||||
assert error["message"] == "Either image_url or image_base64 has to be defined."
|
||||
|
||||
|
||||
def test_events_post_photo_too_small(client, seeder, utils, app):
|
||||
def test_events_post_photo_too_small(client, seeder: Seeder, utils: UtilActions, app):
|
||||
url, data, admin_unit_id, place_id, organizer_id = prepare_events_post_data(
|
||||
seeder, utils
|
||||
)
|
||||
@ -267,13 +271,15 @@ def test_events_post_photo_too_small(client, seeder, utils, app):
|
||||
assert error["message"] == "Image is too small (1x1px). At least 320x320px."
|
||||
|
||||
|
||||
def test_events_import(client, seeder, utils, app, db, shared_datadir):
|
||||
def test_events_import(
|
||||
client, seeder: Seeder, utils: UtilActions, app, db, shared_datadir
|
||||
):
|
||||
external_url = "https://www.harzinfo.de/event/xy"
|
||||
utils.mock_get_request_with_file(
|
||||
external_url, shared_datadir, "harzinfo_biathlon.html"
|
||||
)
|
||||
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
url = utils.get_url("api_v1_organization_event_import", id=admin_unit_id)
|
||||
response = utils.post_json(url, {"url": external_url})
|
||||
|
||||
@ -294,15 +300,15 @@ def test_events_import(client, seeder, utils, app, db, shared_datadir):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_places(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_places(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
seeder.upsert_default_event_place(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_organization_place_list", id=admin_unit_id, name="crew")
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_places_post(client, seeder, utils, app):
|
||||
def test_places_post(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
|
||||
url = utils.get_url("api_v1_organization_place_list", id=admin_unit_id)
|
||||
@ -331,19 +337,19 @@ def test_places_post(client, seeder, utils, app):
|
||||
assert place.location.city == "Goslar"
|
||||
|
||||
|
||||
def test_event_lists(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
def test_event_lists(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_list_id = seeder.create_event_list(admin_unit_id, name="Meine Liste")
|
||||
|
||||
url = utils.get_url(
|
||||
"api_v1_organization_event_list_list", id=admin_unit_id, name="meine"
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["id"] == event_list_id
|
||||
|
||||
|
||||
def test_event_lists_post(client, seeder, utils, app):
|
||||
def test_event_lists_post(client, seeder: Seeder, utils: UtilActions, app):
|
||||
_, admin_unit_id = seeder.setup_api_access()
|
||||
|
||||
url = utils.get_url("api_v1_organization_event_list_list", id=admin_unit_id)
|
||||
@ -368,8 +374,8 @@ def test_event_lists_post(client, seeder, utils, app):
|
||||
assert event_list.name == "Neue Liste"
|
||||
|
||||
|
||||
def test_event_lists_status(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
def test_event_lists_status(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
event_list_id = seeder.create_event_list(
|
||||
admin_unit_id, event_id, name="Meine Liste"
|
||||
@ -381,14 +387,14 @@ def test_event_lists_status(client, seeder, utils):
|
||||
event_id=event_id,
|
||||
name="meine",
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
response = utils.get_json_ok(url)
|
||||
assert len(response.json["items"]) == 1
|
||||
assert response.json["items"][0]["event_list"]["id"] == event_list_id
|
||||
assert response.json["items"][0]["contains_event"]
|
||||
|
||||
|
||||
def test_references_incoming(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_references_incoming(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
(
|
||||
other_user_id,
|
||||
other_admin_unit_id,
|
||||
@ -401,11 +407,11 @@ def test_references_incoming(client, seeder, utils):
|
||||
id=admin_unit_id,
|
||||
name="crew",
|
||||
)
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_references_outgoing(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_references_outgoing(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
other_user_id = seeder.create_user("other@test.de")
|
||||
@ -417,13 +423,17 @@ def test_references_outgoing(client, seeder, utils):
|
||||
id=admin_unit_id,
|
||||
name="crew",
|
||||
)
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("session_based", [True, False])
|
||||
def test_outgoing_relation_list(client, seeder, utils, session_based):
|
||||
def test_outgoing_relation_list(
|
||||
client, seeder: Seeder, utils: UtilActions, session_based
|
||||
):
|
||||
user_id, admin_unit_id = (
|
||||
seeder.setup_base() if session_based else seeder.setup_api_access()
|
||||
seeder.setup_api_access(user_access=False)
|
||||
if session_based
|
||||
else seeder.setup_api_access()
|
||||
)
|
||||
(
|
||||
other_user_id,
|
||||
@ -443,8 +453,10 @@ def test_outgoing_relation_list(client, seeder, utils, session_based):
|
||||
assert response.json["items"][0]["target_organization"]["id"] == other_admin_unit_id
|
||||
|
||||
|
||||
def test_outgoing_relation_list_notAuthenticated(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
def test_outgoing_relation_list_notAuthenticated(
|
||||
client, seeder: Seeder, utils: UtilActions
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
(
|
||||
other_user_id,
|
||||
other_admin_unit_id,
|
||||
@ -459,7 +471,7 @@ def test_outgoing_relation_list_notAuthenticated(client, seeder, utils):
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
|
||||
def test_outgoing_relation_post(client, app, seeder, utils, db):
|
||||
def test_outgoing_relation_post(client, app, seeder: Seeder, utils: UtilActions, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
other_user_id = seeder.create_user("other@test.de")
|
||||
other_admin_unit_id = seeder.create_admin_unit(other_user_id, "Other Crew")
|
||||
@ -487,7 +499,9 @@ def test_outgoing_relation_post(client, app, seeder, utils, db):
|
||||
assert relation.auto_verify_event_reference_requests
|
||||
|
||||
|
||||
def test_outgoing_relation_post_unknownTarget(client, app, seeder, utils):
|
||||
def test_outgoing_relation_post_unknownTarget(
|
||||
client, app, seeder: Seeder, utils: UtilActions
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
|
||||
url = utils.get_url(
|
||||
@ -503,7 +517,9 @@ def test_outgoing_relation_post_unknownTarget(client, app, seeder, utils):
|
||||
utils.assert_response_unprocessable_entity(response)
|
||||
|
||||
|
||||
def test_outgoing_relation_post_selfReference(client, app, seeder, utils):
|
||||
def test_outgoing_relation_post_selfReference(
|
||||
client, app, seeder: Seeder, utils: UtilActions
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
|
||||
url = utils.get_url(
|
||||
@ -519,8 +535,8 @@ def test_outgoing_relation_post_selfReference(client, app, seeder, utils):
|
||||
utils.assert_response_bad_request(response)
|
||||
|
||||
|
||||
def test_organization_invitation_list(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
def test_organization_invitation_list(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
invitation_id = seeder.create_admin_unit_invitation(admin_unit_id)
|
||||
|
||||
url = utils.get_url(
|
||||
@ -573,17 +589,17 @@ def test_organization_invitation_list_post(client, app, seeder, db, utils, mocke
|
||||
utils.assert_send_mail_called(mail_mock, "invited@test.de", invitation_url)
|
||||
|
||||
|
||||
def test_custom_widgets(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
def test_custom_widgets(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
seeder.insert_event_custom_widget(admin_unit_id)
|
||||
|
||||
url = utils.get_url(
|
||||
"api_v1_organization_custom_widget_list", id=admin_unit_id, name="mein"
|
||||
)
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_custom_widgets_post(client, seeder, utils, app):
|
||||
def test_custom_widgets_post(client, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
|
||||
url = utils.get_url("api_v1_organization_custom_widget_list", id=admin_unit_id)
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
def test_read(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_organizer", id=organizer_id)
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_put(client, seeder, utils, app, db):
|
||||
def test_put(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
|
||||
@ -21,7 +25,7 @@ def test_put(client, seeder, utils, app, db):
|
||||
assert organizer.name == "Neuer Name"
|
||||
|
||||
|
||||
def test_patch(client, seeder, utils, app, db):
|
||||
def test_patch(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
|
||||
@ -37,7 +41,7 @@ def test_patch(client, seeder, utils, app, db):
|
||||
assert organizer.phone == "55555"
|
||||
|
||||
|
||||
def test_delete(client, seeder, utils, app, db):
|
||||
def test_delete(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
organizer_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
def test_read(client, app, db, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_read(client, app, db, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
|
||||
url = utils.get_url("api_v1_place", id=place_id)
|
||||
utils.get_ok(url)
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_put(client, seeder, utils, app, db):
|
||||
def test_put(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
|
||||
@ -37,7 +41,7 @@ def test_put_nonActiveReturnsUnauthorized(client, seeder, db, utils, app):
|
||||
utils.assert_response_unauthorized(response)
|
||||
|
||||
|
||||
def test_patch(client, seeder, utils, app, db):
|
||||
def test_patch(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
|
||||
@ -53,7 +57,7 @@ def test_patch(client, seeder, utils, app, db):
|
||||
assert place.description == "Klasse"
|
||||
|
||||
|
||||
def test_patch_location(db, seeder, utils, app):
|
||||
def test_patch_location(db, seeder: Seeder, utils: UtilActions, app):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
|
||||
@ -85,7 +89,7 @@ def test_patch_location(db, seeder, utils, app):
|
||||
assert place.location.postalCode == "54321"
|
||||
|
||||
|
||||
def test_delete(client, seeder, utils, app, db):
|
||||
def test_delete(client, seeder: Seeder, utils: UtilActions, app, db):
|
||||
user_id, admin_unit_id = seeder.setup_api_access()
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
def test_organization_invitation_list(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
invitation_id = seeder.create_admin_unit_invitation(admin_unit_id)
|
||||
|
||||
seeder.create_user("invited@test.de")
|
||||
@ -15,7 +15,7 @@ def test_organization_invitation_list(client, seeder, utils):
|
||||
|
||||
|
||||
def test_organization_invitation_read(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
invitation_id = seeder.create_admin_unit_invitation(admin_unit_id)
|
||||
|
||||
seeder.create_user("invited@test.de")
|
||||
@ -33,7 +33,7 @@ def test_organization_invitation_read(client, seeder, utils):
|
||||
|
||||
|
||||
def test_organization_invitation_read_wrongEmail(client, seeder, utils):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
invitation_id = seeder.create_admin_unit_invitation(admin_unit_id)
|
||||
|
||||
seeder.create_user("other@test.de")
|
||||
@ -45,7 +45,7 @@ def test_organization_invitation_read_wrongEmail(client, seeder, utils):
|
||||
|
||||
|
||||
def test_organization_invitation_delete(client, app, seeder, utils, db):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
_, admin_unit_id = seeder.setup_api_access(user_access=False)
|
||||
invitation_id = seeder.create_admin_unit_invitation(admin_unit_id)
|
||||
|
||||
seeder.create_user("invited@test.de")
|
||||
|
||||
@ -33,6 +33,7 @@ def app():
|
||||
app.config["SERVER_NAME"] = None
|
||||
app.config["TESTING"] = True
|
||||
app.config["ADMIN_UNIT_CREATE_REQUIRES_ADMIN"] = False
|
||||
app.config["API_READ_ANONYM"] = False
|
||||
app.testing = True
|
||||
|
||||
return app
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
class Seeder(object):
|
||||
def __init__(self, app, db, utils):
|
||||
def __init__(self, app, db, utils: UtilActions):
|
||||
self._app = app
|
||||
self._db = db
|
||||
self._utils = utils
|
||||
@ -247,6 +250,25 @@ class Seeder(object):
|
||||
|
||||
return organizer_id
|
||||
|
||||
def upsert_admin_unit_api_key(self, admin_unit_id, name):
|
||||
from project.services.api_key import upsert_api_key
|
||||
|
||||
with self._app.app_context():
|
||||
api_key = upsert_api_key(admin_unit_id, name)
|
||||
self._db.session.commit()
|
||||
api_key_id = api_key.id
|
||||
|
||||
return api_key_id
|
||||
|
||||
def upsert_default_admin_unit_api_key(self, admin_unit_id):
|
||||
from project.services.admin_unit import get_admin_unit_by_id
|
||||
|
||||
with self._app.app_context():
|
||||
admin_unit = get_admin_unit_by_id(admin_unit_id)
|
||||
api_key_id = self.upsert_admin_unit_api_key(admin_unit_id, admin_unit.name)
|
||||
|
||||
return api_key_id
|
||||
|
||||
def insert_event_custom_widget(
|
||||
self,
|
||||
admin_unit_id,
|
||||
@ -282,9 +304,6 @@ class Seeder(object):
|
||||
metadata = dict()
|
||||
metadata["client_name"] = "Mein Client"
|
||||
metadata["scope"] = " ".join(scope_list)
|
||||
metadata["grant_types"] = ["authorization_code", "refresh_token"]
|
||||
metadata["response_types"] = ["code"]
|
||||
metadata["token_endpoint_auth_method"] = "client_secret_post"
|
||||
metadata["redirect_uris"] = [self._utils.get_url("swagger_oauth2_redirect")]
|
||||
client.set_client_metadata(metadata)
|
||||
|
||||
@ -294,11 +313,17 @@ class Seeder(object):
|
||||
|
||||
return client_id
|
||||
|
||||
def setup_api_access(self, admin=True, admin_unit_verified=True):
|
||||
def setup_api_access(self, admin=True, admin_unit_verified=True, user_access=True):
|
||||
user_id, admin_unit_id = self.setup_base(
|
||||
admin=admin, log_in=False, admin_unit_verified=admin_unit_verified
|
||||
)
|
||||
return self.authorize_api_access(user_id, admin_unit_id)
|
||||
|
||||
if user_access:
|
||||
self.authorize_api_access(user_id, admin_unit_id)
|
||||
else:
|
||||
self.grant_client_credentials_api_access(user_id)
|
||||
|
||||
return (user_id, admin_unit_id)
|
||||
|
||||
def authorize_api_access(self, user_id, admin_unit_id):
|
||||
oauth2_client_id = self.insert_default_oauth2_client(user_id)
|
||||
@ -316,6 +341,19 @@ class Seeder(object):
|
||||
self._utils.logout()
|
||||
return (user_id, admin_unit_id)
|
||||
|
||||
def grant_client_credentials_api_access(self, user_id):
|
||||
oauth2_client_id = self.insert_default_oauth2_client(user_id)
|
||||
|
||||
with self._app.app_context():
|
||||
from project.models import OAuth2Client
|
||||
|
||||
oauth2_client = self._db.session.get(OAuth2Client, oauth2_client_id)
|
||||
client_id = oauth2_client.client_id
|
||||
client_secret = oauth2_client.client_secret
|
||||
scope = oauth2_client.scope
|
||||
|
||||
self._utils.grant_client_credentials(client_id, client_secret, scope)
|
||||
|
||||
def get_event_category_id(self, category_name):
|
||||
from project.services.event import get_event_category
|
||||
|
||||
|
||||
@ -105,7 +105,7 @@ class UtilActions(object):
|
||||
)
|
||||
|
||||
def get_ajax_csrf(self, response):
|
||||
pattern = 'var csrf_token = "(.*)";'
|
||||
pattern = r"xhr\.setRequestHeader\(\"X-CSRFToken\", \"(.*)\"\);"
|
||||
match = re.search(pattern.encode("utf-8"), response.data)
|
||||
|
||||
if not match:
|
||||
@ -161,6 +161,11 @@ class UtilActions(object):
|
||||
self.log_response(response)
|
||||
return response
|
||||
|
||||
def get_json_ok(self, url):
|
||||
response = self.get_json(url)
|
||||
self.assert_response_ok(response)
|
||||
return response
|
||||
|
||||
def post_json(self, url, data: dict):
|
||||
self.log_json_request(url, data)
|
||||
response = self._client.post(url, json=data, headers=self.get_headers())
|
||||
@ -374,31 +379,48 @@ class UtilActions(object):
|
||||
code = params["code"]
|
||||
|
||||
# Mit dem Code den Access-Token abfragen
|
||||
token_url = self.get_url("issue_token")
|
||||
response = self.post_form_data(
|
||||
token_url,
|
||||
data={
|
||||
"client_id": client_id,
|
||||
"client_secret": client_secret,
|
||||
"grant_type": "authorization_code",
|
||||
"scope": scope,
|
||||
"code": code,
|
||||
"redirect_uri": redirect_uri,
|
||||
},
|
||||
self._get_token(
|
||||
client_id, client_secret, scope, "authorization_code", code, redirect_uri
|
||||
)
|
||||
|
||||
def grant_client_credentials(self, client_id, client_secret, scope):
|
||||
# Mit den Credentials den Access-Token abfragen
|
||||
self._get_token(client_id, client_secret, scope, "client_credentials")
|
||||
|
||||
def _get_token(
|
||||
self, client_id, client_secret, scope, grant_type, code=None, redirect_uri=None
|
||||
):
|
||||
data = {
|
||||
"client_id": client_id,
|
||||
"client_secret": client_secret,
|
||||
"grant_type": grant_type,
|
||||
"scope": scope,
|
||||
}
|
||||
|
||||
if grant_type == "authorization_code":
|
||||
data["code"] = code
|
||||
data["redirect_uri"] = redirect_uri
|
||||
|
||||
token_url = self.get_url("issue_token")
|
||||
response = self.post_form_data(token_url, data=data)
|
||||
|
||||
self.assert_response_ok(response)
|
||||
assert response.content_type == "application/json"
|
||||
assert "access_token" in response.json
|
||||
assert "expires_in" in response.json
|
||||
assert "refresh_token" in response.json
|
||||
|
||||
if grant_type == "authorization_code":
|
||||
assert "refresh_token" in response.json
|
||||
|
||||
assert response.json["scope"] == scope
|
||||
assert response.json["token_type"] == "Bearer"
|
||||
|
||||
self._client_id = client_id
|
||||
self._client_secret = client_secret
|
||||
self._access_token = response.json["access_token"]
|
||||
self._refresh_token = response.json["refresh_token"]
|
||||
|
||||
if grant_type == "authorization_code":
|
||||
self._refresh_token = response.json["refresh_token"]
|
||||
|
||||
def refresh_token(self):
|
||||
token_url = self.get_url("issue_token")
|
||||
|
||||
10
tests/views/test_custom_widget.py
Normal file
10
tests/views/test_custom_widget.py
Normal file
@ -0,0 +1,10 @@
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_custom_widget_type(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
custom_widget_id = seeder.insert_event_custom_widget(admin_unit_id)
|
||||
|
||||
url = utils.get_url("custom_widget_type", type="search", id=custom_widget_id)
|
||||
utils.get_ok(url)
|
||||
@ -2,7 +2,7 @@ from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_js_check_org_short_name(client, seeder, utils):
|
||||
def test_js_check_org_short_name(client, seeder, utils: UtilActions):
|
||||
seeder.create_user(admin=True)
|
||||
utils.login()
|
||||
|
||||
@ -210,3 +210,11 @@ def test_js_autocomplete_gmaps_place(client, seeder: Seeder, utils: UtilActions)
|
||||
|
||||
utils.assert_response_ok(response)
|
||||
assert response.json["place_id"] == "123"
|
||||
|
||||
|
||||
def test_js_widget_loader_custom_widget(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
custom_widget_id = seeder.insert_event_custom_widget(admin_unit_id)
|
||||
|
||||
url = utils.get_url("js_widget_loader_custom_widget", id=custom_widget_id)
|
||||
utils.get_ok(url)
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
def test_organizations(client, seeder, utils):
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
def test_organizations(client, seeder: Seeder, utils: UtilActions):
|
||||
url = utils.get_url("organizations")
|
||||
utils.get_ok(url)
|
||||
|
||||
url = utils.get_url("api_v1_organization_list")
|
||||
utils.get_json_ok(url)
|
||||
|
||||
|
||||
def test_ical(client, seeder, utils):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user