diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7a7e106e8..e10b8b981 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -136,6 +136,7 @@ test_api: - branches before_script: - apk add make git gcc python3-dev musl-dev + - apk add postgresql-dev py3-psycopg2 libldap libffi-dev make zlib-dev jpeg-dev openldap-dev - cd api - pip3 install -r requirements/base.txt - pip3 install -r requirements/local.txt diff --git a/api/funkwhale_api/audio/filters.py b/api/funkwhale_api/audio/filters.py index 9b7088c1d..76f712a7c 100644 --- a/api/funkwhale_api/audio/filters.py +++ b/api/funkwhale_api/audio/filters.py @@ -41,7 +41,7 @@ class ChannelFilter(moderation_filters.HiddenContentFilterSet): class Meta: model = models.Channel - fields = ["q", "scope", "tag", "subscribed", "ordering", "external"] + fields = [] hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["CHANNEL"] def filter_subscribed(self, queryset, name, value): diff --git a/api/funkwhale_api/common/filters.py b/api/funkwhale_api/common/filters.py index dec4a89ab..6b199d531 100644 --- a/api/funkwhale_api/common/filters.py +++ b/api/funkwhale_api/common/filters.py @@ -119,7 +119,6 @@ class MultipleQueryFilter(filters.TypedMultipleChoiceFilter): def __init__(self, *args, **kwargs): kwargs["widget"] = QueryArrayWidget() super().__init__(*args, **kwargs) - self.lookup_expr = "in" def filter_target(value): diff --git a/api/funkwhale_api/favorites/filters.py b/api/funkwhale_api/favorites/filters.py index b4dad93ac..0b76a4dd0 100644 --- a/api/funkwhale_api/favorites/filters.py +++ b/api/funkwhale_api/favorites/filters.py @@ -14,7 +14,7 @@ class TrackFavoriteFilter(moderation_filters.HiddenContentFilterSet): class Meta: model = models.TrackFavorite # XXX: 1.0 remove the user filter, we have scope=me now - fields = ["user", "q", "scope"] + fields = ["user"] hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[ "TRACK_FAVORITE" ] diff --git a/api/funkwhale_api/federation/filters.py b/api/funkwhale_api/federation/filters.py index bfc48bcfb..a57bc4071 100644 --- a/api/funkwhale_api/federation/filters.py +++ b/api/funkwhale_api/federation/filters.py @@ -20,7 +20,7 @@ class FollowFilter(django_filters.FilterSet): class Meta: model = models.Follow - fields = ["approved", "pending", "q"] + fields = ["approved"] def filter_pending(self, queryset, field_name, value): if value.lower() in ["true", "1", "yes"]: diff --git a/api/funkwhale_api/history/filters.py b/api/funkwhale_api/history/filters.py index 16a03204f..1e88f1b22 100644 --- a/api/funkwhale_api/history/filters.py +++ b/api/funkwhale_api/history/filters.py @@ -16,4 +16,4 @@ class ListeningFilter(moderation_filters.HiddenContentFilterSet): hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG[ "LISTENING" ] - fields = ["hidden", "scope"] + fields = [] diff --git a/api/funkwhale_api/manage/filters.py b/api/funkwhale_api/manage/filters.py index 727911995..39ba56d9d 100644 --- a/api/funkwhale_api/manage/filters.py +++ b/api/funkwhale_api/manage/filters.py @@ -60,7 +60,7 @@ class ManageChannelFilterSet(filters.FilterSet): class Meta: model = audio_models.Channel - fields = ["q"] + fields = [] class ManageArtistFilterSet(filters.FilterSet): @@ -89,7 +89,7 @@ class ManageArtistFilterSet(filters.FilterSet): class Meta: model = music_models.Artist - fields = ["q", "name", "mbid", "fid", "content_category"] + fields = ["name", "mbid", "fid", "content_category"] class ManageAlbumFilterSet(filters.FilterSet): @@ -119,7 +119,7 @@ class ManageAlbumFilterSet(filters.FilterSet): class Meta: model = music_models.Album - fields = ["q", "title", "mbid", "fid", "artist"] + fields = ["title", "mbid", "fid", "artist"] class ManageTrackFilterSet(filters.FilterSet): @@ -158,7 +158,7 @@ class ManageTrackFilterSet(filters.FilterSet): class Meta: model = music_models.Track - fields = ["q", "title", "mbid", "fid", "artist", "album", "license"] + fields = ["title", "mbid", "fid", "artist", "album", "license"] class ManageLibraryFilterSet(filters.FilterSet): @@ -204,7 +204,7 @@ class ManageLibraryFilterSet(filters.FilterSet): class Meta: model = music_models.Library - fields = ["q", "name", "fid", "privacy_level", "domain"] + fields = ["name", "fid", "privacy_level"] class ManageUploadFilterSet(filters.FilterSet): @@ -249,10 +249,7 @@ class ManageUploadFilterSet(filters.FilterSet): class Meta: model = music_models.Upload fields = [ - "q", "fid", - "privacy_level", - "domain", "mimetype", "import_reference", "import_status", @@ -275,7 +272,7 @@ class ManageDomainFilterSet(filters.FilterSet): class Meta: model = federation_models.Domain - fields = ["name", "allowed"] + fields = ["name"] class ManageActorFilterSet(filters.FilterSet): @@ -300,7 +297,7 @@ class ManageActorFilterSet(filters.FilterSet): class Meta: model = federation_models.Actor - fields = ["q", "domain", "type", "manually_approves_followers", "local"] + fields = ["domain", "type", "manually_approves_followers"] def filter_local(self, queryset, name, value): return queryset.local(value) @@ -320,7 +317,6 @@ class ManageUserFilterSet(filters.FilterSet): class Meta: model = users_models.User fields = [ - "q", "is_active", "privacy_level", "is_staff", @@ -337,7 +333,7 @@ class ManageInvitationFilterSet(filters.FilterSet): class Meta: model = users_models.Invitation - fields = ["q", "is_open"] + fields = [] def filter_is_open(self, queryset, field_name, value): if value is None: @@ -362,14 +358,10 @@ class ManageInstancePolicyFilterSet(filters.FilterSet): class Meta: model = moderation_models.InstancePolicy fields = [ - "q", "block_all", "silence_activity", "silence_notifications", "reject_media", - "target_domain", - "target_account_domain", - "target_account_username", ] @@ -378,7 +370,7 @@ class ManageTagFilterSet(filters.FilterSet): class Meta: model = tags_models.Tag - fields = ["q"] + fields = [] class ManageReportFilterSet(filters.FilterSet): @@ -404,7 +396,7 @@ class ManageReportFilterSet(filters.FilterSet): class Meta: model = moderation_models.Report - fields = ["q", "is_handled", "type", "submitter_email"] + fields = ["is_handled", "type", "submitter_email"] class ManageNoteFilterSet(filters.FilterSet): @@ -423,7 +415,7 @@ class ManageNoteFilterSet(filters.FilterSet): class Meta: model = moderation_models.Note - fields = ["q"] + fields = [] class ManageUserRequestFilterSet(filters.FilterSet): @@ -446,4 +438,4 @@ class ManageUserRequestFilterSet(filters.FilterSet): class Meta: model = moderation_models.UserRequest - fields = ["q", "status", "type"] + fields = ["status", "type"] diff --git a/api/funkwhale_api/music/filters.py b/api/funkwhale_api/music/filters.py index feebaa542..64c0cd5a6 100644 --- a/api/funkwhale_api/music/filters.py +++ b/api/funkwhale_api/music/filters.py @@ -120,8 +120,6 @@ class ArtistFilter( model = models.Artist fields = { "name": ["exact", "iexact", "startswith", "icontains"], - "playable": ["exact"], - "scope": ["exact"], "mbid": ["exact"], } hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ARTIST"] @@ -174,11 +172,9 @@ class TrackFilter( model = models.Track fields = { "title": ["exact", "iexact", "startswith", "icontains"], - "playable": ["exact"], "id": ["exact"], "album": ["exact"], "license": ["exact"], - "scope": ["exact"], "mbid": ["exact"], } hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["TRACK"] @@ -225,16 +221,9 @@ class UploadFilter(audio_filters.IncludeChannelsFilterSet): class Meta: model = models.Upload fields = [ - "playable", "import_status", "mimetype", - "track", - "track_artist", - "album_artist", - "library", "import_reference", - "scope", - "channel", ] include_channels_field = "track__artist__channel" @@ -273,7 +262,7 @@ class AlbumFilter( class Meta: model = models.Album - fields = ["playable", "q", "artist", "scope", "mbid"] + fields = ["artist", "mbid"] hidden_content_fields_mapping = moderation_filters.USER_FILTER_CONFIG["ALBUM"] include_channels_field = "artist__channel" channel_filter_field = "track__album" @@ -290,4 +279,4 @@ class LibraryFilter(filters.FilterSet): class Meta: model = models.Library - fields = ["privacy_level", "q", "scope"] + fields = ["privacy_level"] diff --git a/api/funkwhale_api/playlists/filters.py b/api/funkwhale_api/playlists/filters.py index f49e9bd1a..e12813b38 100644 --- a/api/funkwhale_api/playlists/filters.py +++ b/api/funkwhale_api/playlists/filters.py @@ -33,9 +33,6 @@ class PlaylistFilter(filters.FilterSet): fields = { "user": ["exact"], "name": ["exact", "icontains"], - "q": "exact", - "playable": "exact", - "scope": "exact", } def filter_playable(self, queryset, name, value): diff --git a/api/funkwhale_api/radios/filtersets.py b/api/funkwhale_api/radios/filtersets.py index 6f548dbea..f570b2d54 100644 --- a/api/funkwhale_api/radios/filtersets.py +++ b/api/funkwhale_api/radios/filtersets.py @@ -11,5 +11,4 @@ class RadioFilter(django_filters.FilterSet): model = models.Radio fields = { "name": ["exact", "iexact", "startswith", "icontains"], - "scope": "exact", } diff --git a/api/funkwhale_api/subsonic/filters.py b/api/funkwhale_api/subsonic/filters.py index a3c251e66..f3fc81111 100644 --- a/api/funkwhale_api/subsonic/filters.py +++ b/api/funkwhale_api/subsonic/filters.py @@ -8,7 +8,7 @@ class AlbumList2FilterSet(filters.FilterSet): class Meta: model = music_models.Album - fields = ["type"] + fields = [] def filter_type(self, queryset, name, value): ORDERING = { diff --git a/api/funkwhale_api/tags/filters.py b/api/funkwhale_api/tags/filters.py index c41ace91b..7922e3e12 100644 --- a/api/funkwhale_api/tags/filters.py +++ b/api/funkwhale_api/tags/filters.py @@ -20,7 +20,7 @@ class TagFilter(filters.FilterSet): class Meta: model = models.Tag - fields = {"q": ["exact"], "name": ["exact", "startswith"]} + fields = {"name": ["exact", "startswith"]} def get_by_similar_tags(qs, tags): diff --git a/api/funkwhale_api/users/migrations/0019_auto_20200718_0741.py b/api/funkwhale_api/users/migrations/0019_auto_20200718_0741.py new file mode 100644 index 000000000..11c0e655e --- /dev/null +++ b/api/funkwhale_api/users/migrations/0019_auto_20200718_0741.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.8 on 2020-07-18 07:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0018_auto_20200705_0829'), + ] + + operations = [ + migrations.AddField( + model_name='grant', + name='code_challenge', + field=models.CharField(blank=True, default='', max_length=128), + ), + migrations.AddField( + model_name='grant', + name='code_challenge_method', + field=models.CharField(blank=True, choices=[('plain', 'plain'), ('S256', 'S256')], default='', max_length=10), + ), + ] diff --git a/api/funkwhale_api/users/oauth/views.py b/api/funkwhale_api/users/oauth/views.py index 90706e708..8fd88d908 100644 --- a/api/funkwhale_api/users/oauth/views.py +++ b/api/funkwhale_api/users/oauth/views.py @@ -155,20 +155,21 @@ class AuthorizeView(views.APIView, oauth_views.AuthorizationView): def form_valid(self, form): try: - response = super().form_valid(form) + return super().form_valid(form) except models.Application.DoesNotExist: return self.json_payload({"non_field_errors": ["Invalid application"]}, 400) - if self.request.is_ajax() and response.status_code == 302: + def redirect(self, redirect_to, application, token=None): + if self.request.is_ajax(): # Web client need this to be able to redirect the user - query = urllib.parse.urlparse(response["Location"]).query + query = urllib.parse.urlparse(redirect_to).query code = urllib.parse.parse_qs(query)["code"][0] return self.json_payload( - {"redirect_uri": response["Location"], "code": code}, status_code=200 + {"redirect_uri": redirect_to, "code": code}, status_code=200 ) - return response + return super().redirect(redirect_to, application, token) def error_response(self, error, application): if isinstance(error, oauth2_exceptions.FatalClientError): diff --git a/api/requirements/base.txt b/api/requirements/base.txt index 6e31f857e..74f33bde1 100644 --- a/api/requirements/base.txt +++ b/api/requirements/base.txt @@ -1,82 +1,82 @@ # Bleeding edge Django -django>=3.0.5,<3.1; python_version > '3.5' +django>=3.0.8,<3.1; python_version > '3.5' django>=2.2.12,<3; python_version < '3.6' setuptools>=36 # Configuration django-environ>=0.4,<0.5 # Images -Pillow>=6.2,<7 +Pillow>=7,<8 # For user registration, either via email or social # Well-built with regular release cycles! -django-allauth>=0.41,<0.42 +django-allauth>=0.42,<0.43 # Python-PostgreSQL Database Adapter psycopg2-binary>=2.8,<=2.9 # Time zones support -pytz==2019.3 +pytz==2020.1 # Redis support -django-redis>=4.11,<4.12 -redis>=3.4,<3.5 -kombu>=4.5,<4.6 +django-redis>=4.12.1,<4.13 +redis>=3.5.3,<3.6 +kombu>=4.6.11,<4.7 -celery>=4.3,<4.4 +celery>=4.4.6,<4.5 # Your custom requirements go here -django-cors-headers>=3.2,<3.3 -musicbrainzngs==0.6 +django-cors-headers>=3.4,<3.5 +musicbrainzngs>=0.7.1,<0.8 djangorestframework>=3.11,<3.12 djangorestframework-jwt>=1.11,<1.12 arrow>=0.15.5,<0.16 persisting-theory>=0.2,<0.3 django-versatileimagefield>=2.0,<2.1 -django-filter>=2.1,<2.2 +django-filter>=2.3,<2.4 django-rest-auth>=0.9,<0.10 # XXX: remove when we drop support for python 3.5 ipython>=7.10,<8; python_version > '3.5' ipython>=7,<7.10; python_version < '3.6' -mutagen>=1.44,<1.45 +mutagen>=1.45,<1.46 pymemoize==1.0.3 -django-dynamic-preferences>=1.8.1,<1.9 +django-dynamic-preferences>=1.10,<1.11 raven>=6.10,<7 -python-magic==0.4.15 +python-magic==0.4.18 channels>=2.4,<2.5 # XXX: remove when we drop support for python 3.5 channels_redis==2.2.1; python_version < '3.6' -channels_redis>=2.3.2,<2.4; python_version > '3.5' +channels_redis>=3,<3.1; python_version > '3.5' uvicorn==0.8.6; python_version < '3.6' -uvicorn>=0.11.3,<0.12; python_version > '3.5' +uvicorn>=0.11.5,<0.12; python_version > '3.5' gunicorn>=20.0.4,<20.1 cryptography>=2.8,<3 # requests-http-signature==0.0.3 # clone until the branch is merged and released upstream git+https://github.com/EliotBerriot/requests-http-signature.git@signature-header-support -django-cleanup>=4,<4.1 +django-cleanup>=5,<5.1 requests>=2.22<2.23 pyOpenSSL>=19<20 # for LDAP authentication -python-ldap>=3.2.0,<3.3 -django-auth-ldap>=2.1.0,<2.2 +python-ldap>=3.3.1,<3.4 +django-auth-ldap>=2.2.0,<2.3 -pydub>=0.23.1,<0.24 -pyld==1.0.4 +pydub>=0.24.1,<0.25 +pyld>=1,<2 aiohttp>=3.6,<3.7 autobahn>=19.3.3 -django-oauth-toolkit==1.2 +django-oauth-toolkit>=1.3.2,<1.4 django-storages>=1.9.1,<1.10 boto3<3 unicode-slugify==0.1.3 -django-cacheops==4.2 +django-cacheops>=5,<5.1 click>=7,<8 service_identity==18.1.0