Skip to content

Adding docs and updating #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d395bbc
Some refactoring and adding docs
destos Jul 7, 2020
f520d41
bump some versions
destos Dec 2, 2020
9d4c54f
allow different versions of waffle
destos Dec 2, 2020
285df28
try a different way
destos Dec 2, 2020
a326d8e
with all lower waffle versions
destos Dec 2, 2020
c470602
update pytest, poetry, fix waffle and django filter versioning
destos Jan 10, 2021
4a86e35
flake8
destos Jan 10, 2021
eae8024
specify higher poetry version
destos Jan 10, 2021
0dc4e1a
update setup-poetry
destos Jan 10, 2021
e8dfcff
remove defunct waffle fallback code, test still works
destos Jan 10, 2021
9138e1a
futzing with docs
destos Jan 10, 2021
8a814ae
Merge branch 'master' into docs
destos Jan 10, 2021
d5af412
Bump version: 0.1.12 → 0.1.13a1
destos Jan 10, 2021
45813d2
add proper request context, switch methods to use request
destos Feb 15, 2021
1ac50a4
django 3.2 added
destos Feb 15, 2021
6fafcbd
Adjust root Resolver class init and reference kwargs to use parent, f…
destos Feb 16, 2021
22cb4ec
Bump version: 0.1.13a1 → 0.2.0
destos Feb 16, 2021
aad6725
Fix UpdateModelMixin to inherit from InputMixin
destos Feb 17, 2021
81c90c5
Add some field docts to Waffle type
destos Feb 17, 2021
3d846d4
Bump version: 0.2.0 → 0.2.1
destos Feb 17, 2021
b6c163f
change info to request
buddylindsey Mar 2, 2021
ed1e943
Bump version: 0.2.1 → 0.2.2
buddylindsey Mar 2, 2021
32d9f66
Update test matrix to only include relevant versions
destos May 24, 2021
6ae1e35
add some words to workspace
destos May 24, 2021
359dda1
update ariadne and new lock file
destos May 24, 2021
8f3c651
linting and fixing tests
destos May 24, 2021
2457a65
use proper drf version
destos May 24, 2021
d7f3bfa
Bump version: 0.2.2 → 0.2.3
destos May 25, 2021
db11778
Add settings and global permission to resolvers
buddylindsey Jul 12, 2021
e512c0b
Fix linting
buddylindsey Jul 12, 2021
0b38a76
Ignore flake-8 error to make way for black check
buddylindsey Jul 12, 2021
5ab0ea3
adding latest django and drf to matrix
destos Jul 13, 2021
a8fcde8
fixing deprecation warnings from imports
destos Jul 13, 2021
291601e
update project deps
destos Jul 13, 2021
2d759a4
fix settings.py formatting
destos Jul 13, 2021
b5f0af7
Add AllowAny to default Resolver attr test
destos Jul 13, 2021
3689095
Add ability to compare operation holders for equality
destos Jul 27, 2021
d56cc5d
rename view to resolver in permissions args
destos Jul 27, 2021
38d01dc
formatting
destos Jul 27, 2021
f062b45
Update permissions.py
destos Jul 27, 2021
0636d15
comparison case for non-operand holder comparison
destos Jul 28, 2021
29f034d
Bump version: 0.2.3 → 0.2.4
destos Jul 29, 2021
86c4b22
Merge pull request #9 from patriotresearch/settings
destos Jul 29, 2021
5121f1a
Allow the active field to resolve without permissions
destos Aug 5, 2021
75cdac4
Make resolver exceptions more informative and capture more data
destos Aug 5, 2021
aa1b062
Merge pull request #10 from patriotresearch/TI-894-waffle-perm-fix
buddylindsey Aug 5, 2021
61dc862
Bump version: 0.2.4 → 0.2.5
destos Aug 6, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.1.12
current_version = 0.2.5
commit = True
tag = True

Expand Down
30 changes: 5 additions & 25 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,9 @@ jobs:
fail-fast: false
max-parallel: 3
matrix:
python-version: [3.7, 3.8]
django-version: [2.2.12, 3.0.5]
drf-version: [3.7.7, 3.8.2, 3.9.4, 3.11.0]
# Remove unsupported combinations
exclude:
- python-version: 3.7
django-version: 3.0.5
drf-version: 3.7.7
- python-version: 3.7
django-version: 3.0.5
drf-version: 3.8.2
- python-version: 3.7
django-version: 3.0.5
drf-version: 3.9.4
- python-version: 3.8
django-version: 3.0.5
drf-version: 3.7.7
- python-version: 3.8
django-version: 3.0.5
drf-version: 3.8.2
- python-version: 3.8
django-version: 3.0.5
drf-version: 3.9.4
python-version: [3.8]
django-version: [2.2.23, 3.1.11, 3.2.5]
drf-version: [3.11.2, 3.12.1, 3.12.4]

steps:
- uses: actions/checkout@v1
Expand All @@ -60,9 +40,9 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: "Install Poetry"
uses: Gr1N/setup-poetry@v2
uses: Gr1N/setup-poetry@v4
with:
poetry-version: 1.0.5
poetry-version: 1.1.4

- uses: actions/cache@v1
id: cache
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"python.formatting.provider": "black"
"python.formatting.provider": "black",
"restructuredtext.confPath": "${workspaceFolder}/docs"
}
28 changes: 28 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Security

## 🔐 Reporting Security Issues

> Do not open issues that might have security implications!
> It is critical that security related issues are reported privately so we have time to address them before they become public knowledge.

Vulnerabilities can be reported by emailing core members:

- Patrick Forringer [[email protected]](mailto:[email protected])
- Buddy Lindsey [[email protected]](mailto:[email protected])

Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:

- Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
- Full paths of source file(s) related to the manifestation of the issue
- The location of the affected source code (tag/branch/commit or direct URL)
- Any special configuration required to reproduce the issue
- Environment (e.g. Linux / Windows / macOS)
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact of the issue, including how an attacker might exploit the issue

This information will help us triage your report more quickly.

## Preferred Languages

We prefer all communications to be in English.
7 changes: 6 additions & 1 deletion ariadne_extended.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,10 @@
"path": "."
}
],
"settings": {}
"settings": {
"cSpell.words": [
"camelize",
"decamelize"
]
}
}
2 changes: 1 addition & 1 deletion ariadne_extended/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1.12"
__version__ = "0.2.5"
43 changes: 35 additions & 8 deletions ariadne_extended/contrib/waffle_graph/resolvers.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
from ariadne_extended.resolvers import ListModelResolver, Resolver
from ariadne_extended.resolvers import ListModelResolver, Resolver, DetailModelMixin
from ariadne_extended.permissions import AllowAny
from waffle import get_waffle_flag_model
from waffle.models import Sample, Switch
from waffle.utils import get_setting

from .types import query, waffle_item_interface, waffle_type


class WaffleResolver(ListModelResolver):
class WaffleResolver(DetailModelMixin, ListModelResolver):
"""
Base resolver for waffle models, allows all users to resolve as the data is not sensitive
and may even be resolved by users that aren't logged in.
"""

lookup_arg = "name"
lookup_field = "name"
permission_classes = [AllowAny]

def get_object(self):
"""
Use the get method provided by the django-waffle library to lookup a flag/switch/sample

Waffle models don't require object level permissions

Returns an empty model class if not found with the used lookup name
"""
lookup = self.get_lookup_filter_kwargs()
return self.model.get(**lookup)

def get_queryset(self):
# Not a true QS, will ask cache for saved model objects
return self.model.get_all()
Expand All @@ -29,18 +50,24 @@ def list(self, *args, **kwargs):
return Switch.get_all() + Sample.get_all() + get_waffle_flag_model().get_all()


@waffle_item_interface.field("active")
def resolve_flag_active(obj, info, *args, **kwargs):
try:
return obj.is_active(info.context)
except TypeError:
return obj.is_active()
class ActiveResolver(Resolver):
permission_classes = [AllowAny]

def check(self, parent, *args, **kwargs):
try:
return parent.is_active(self.request)
except TypeError:
return parent.is_active()


waffle_type.set_field("flags", FlagResolver.as_resolver(method="list"))
waffle_type.set_field("switches", SwitchResolver.as_resolver(method="list"))
waffle_type.set_field("samples", SampleResolver.as_resolver(method="list"))
waffle_type.set_field("all", AllWaffleTypesResolver.as_resolver(method="list"))
waffle_type.set_field("flag", FlagResolver.as_resolver(method="retrieve"))
waffle_type.set_field("switch", SwitchResolver.as_resolver(method="retrieve"))
waffle_type.set_field("sample", SampleResolver.as_resolver(method="retrieve"))
waffle_item_interface.set_field("active", ActiveResolver.as_resolver(method="check"))
query.set_field(
"waffle",
lambda *x: {
Expand Down
17 changes: 13 additions & 4 deletions ariadne_extended/contrib/waffle_graph/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
interface WaffleItem {
id: ID!
id: ID
name: String
active: Boolean
note: String
}

type WaffleFlag implements WaffleItem {
id: ID!
id: ID
name: String
active: Boolean
note: String
}

type WaffleSwitch implements WaffleItem {
id: ID!
id: ID
name: String
active: Boolean
note: String
}

type WaffleSample implements WaffleItem {
id: ID!
id: ID
name: String
active: Boolean
note: String
Expand All @@ -31,8 +31,17 @@ type Waffle {
switches: [WaffleSwitch]
samples: [WaffleSample]
all: [WaffleItem]
"Retrieve a flag"
flag(name: String): WaffleFlag
"Retrieve a switch"
switch(name: String): WaffleSwitch
"Retrieve a sample"
sample(name: String): WaffleSample
"The default flag value as specified in the settings"
flagDefault: Boolean
"The default switch value as specified in the settings"
switchDefault: Boolean
"The default sample value as specified in the settings"
sampleDefault: Boolean
}

Expand Down
1 change: 1 addition & 0 deletions ariadne_extended/cursor_pagination/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# flake8: noqa
from .mixins import RelayModelMixin
from .pagination import CursorPage, CursorPaginator, InternalPaginator, InvalidCursor
from .resolvers import RelayModelResolver, page_info_resolver
11 changes: 5 additions & 6 deletions ariadne_extended/cursor_pagination/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
updated to remove dependency on six
"""
from base64 import b64decode, b64encode
from collections import Sequence
from collections.abc import Sequence

from django.db.models import Field, Func, Value, TextField
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _


class TupleField(Field):
Expand Down Expand Up @@ -87,8 +87,8 @@ def __init__(self, qs, ordering):

self.ordering = ordering

if not all(o.startswith("-") for o in ordering) and not all(
not o.startswith("-") for o in ordering
if not all(o.startswith("-") for o in ordering) and any(
o.startswith("-") for o in ordering
):
raise InvalidCursor("Direction of orderings must match")

Expand Down Expand Up @@ -143,8 +143,7 @@ def decode_cursor(self, cursor):
raise InvalidCursor(self.invalid_cursor_message)

def encode_cursor(self, position):
encoded = b64encode(self.delimiter.join(position).encode("utf8")).decode("ascii")
return encoded
return b64encode(self.delimiter.join(position).encode("utf8")).decode("ascii")

def position_from_instance(self, instance):
position = []
Expand Down
1 change: 1 addition & 0 deletions ariadne_extended/filters/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# flake8: noqa
from .backends import GraphQLFilterBackend
from .mixins import FilterMixin
2 changes: 1 addition & 1 deletion ariadne_extended/filters/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def filter_queryset(self, queryset):
default queryset.
"""
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.info, queryset, self)
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset

def get_filter_data(self):
Expand Down
13 changes: 5 additions & 8 deletions ariadne_extended/graph_loader/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ class GraphLoaderConfig(AppConfig):

def ready(self):
# Find all schema.graphql and resolver modules and load them
self.type_defs = list()
self.types = list()
self.resolvers = list()
self.type_defs = []
self.types = []
self.resolvers = []

logger.debug("Trying to load resolvers and schemas:")
for config in apps.get_app_configs():
self.load_schema(config)
self.load_resolvers(config)
self.load_custom_types(config)

logger.debug("Types: %s", ", ".join([_type.name for _type in self.types]))
logger.debug("Types: %s", ", ".join(_type.name for _type in self.types))

def load_schema(self, config):
try:
Expand Down Expand Up @@ -59,10 +59,7 @@ def load_custom_types(self, config):
for type_name in [
t
for _, t in types_module.__dict__.items()
if isinstance(t, ObjectType)
or isinstance(t, ScalarType)
or isinstance(t, EnumType)
or isinstance(t, UnionType)
if isinstance(t, (ObjectType, ScalarType, EnumType, UnionType))
]:
self.types.append(type_name)
except ModuleNotFoundError as e:
Expand Down
7 changes: 2 additions & 5 deletions ariadne_extended/payload/resolvers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from copy import copy

import humps.main as humps
from ariadne import FallbackResolversSetter
from graphql.type import GraphQLList, GraphQLField
from .types import error_detail, payload
from rest_framework.exceptions import ErrorDetail

Expand All @@ -14,10 +12,9 @@ def resolve_error_detail_error(parent, info, *args, **kwargs):


def traverse_errors(fields, node, stack=""):

# Does the list contain errors or more fields?
if isinstance(node, list):
if any([isinstance(i, ErrorDetail) for i in node]):
if any(isinstance(i, ErrorDetail) for i in node):
stack_key = copy(stack)
fields.append(dict(name=humps.camelize(stack_key), values=node))
else:
Expand All @@ -32,7 +29,7 @@ def traverse_errors(fields, node, stack=""):
# If node is a dict, use the keys
if isinstance(node, dict):
for name, errors in node.items():
# Copy key so the ref is lost and the chain becomes unique
# Copy key so the ref is lost and the stack becomes unique
stack_key = copy(stack)
if bool(stack_key):
if isinstance(name, int):
Expand Down
Loading