all(major): add most models to API
This commit is contained in:
parent
846a86fb62
commit
cffe09b02e
3
Pipfile
3
Pipfile
|
@ -10,7 +10,7 @@ defusedxml = "*"
|
|||
django = "*"
|
||||
kombu = "==4.5.0"
|
||||
django-cors-middleware = "*"
|
||||
django-filters = "*"
|
||||
django-filter = "*"
|
||||
django-ipware = "*"
|
||||
django-model-utils = "*"
|
||||
django-oauth-toolkit = "*"
|
||||
|
@ -41,6 +41,7 @@ django-guardian = "*"
|
|||
django-dbbackup = "*"
|
||||
boto3 = "*"
|
||||
django-storages = "*"
|
||||
swagger-spec-validator = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "fa76852e940fed079700de54816889e85ca1f59213210efc2537d38a9086c010"
|
||||
"sha256": "045f299c421b29003cbc657397d79fcb1c16a0bce9991aaeadc76f55339f7f09"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -204,12 +204,13 @@
|
|||
"index": "pypi",
|
||||
"version": "==3.2.0"
|
||||
},
|
||||
"django-filters": {
|
||||
"django-filter": {
|
||||
"hashes": [
|
||||
"sha256:1a9799a41106dc53ed894e952a24e8dee9b4fb37f010f22d178c09c90c61d711"
|
||||
"sha256:558c727bce3ffa89c4a7a0b13bc8976745d63e5fd576b3a9a851650ef11c401b",
|
||||
"sha256:c3deb57f0dd7ff94d7dce52a047516822013e2b441bed472b722a317658cfd14"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.2.1"
|
||||
"version": "==2.2.0"
|
||||
},
|
||||
"django-guardian": {
|
||||
"hashes": [
|
||||
|
@ -338,6 +339,13 @@
|
|||
],
|
||||
"version": "==2.8"
|
||||
},
|
||||
"importlib-metadata": {
|
||||
"hashes": [
|
||||
"sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26",
|
||||
"sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af"
|
||||
],
|
||||
"version": "==0.23"
|
||||
},
|
||||
"inflection": {
|
||||
"hashes": [
|
||||
"sha256:18ea7fb7a7d152853386523def08736aa8c32636b047ade55f7578c4edeb16ca"
|
||||
|
@ -371,6 +379,13 @@
|
|||
],
|
||||
"version": "==0.9.4"
|
||||
},
|
||||
"jsonschema": {
|
||||
"hashes": [
|
||||
"sha256:2fa0684276b6333ff3c0b1b27081f4b2305f0a36cf702a23db50edb141893c3f",
|
||||
"sha256:94c0a13b4a0616458b42529091624e66700a17f847453e52279e35509a5b7631"
|
||||
],
|
||||
"version": "==3.1.1"
|
||||
},
|
||||
"kombu": {
|
||||
"hashes": [
|
||||
"sha256:389ba09e03b15b55b1a7371a441c894fd8121d174f5583bbbca032b9ea8c9edd",
|
||||
|
@ -392,6 +407,7 @@
|
|||
"sha256:02ca7bf899da57084041bb0f6095333e4d239948ad3169443f454add9f4e9cb4",
|
||||
"sha256:096b82c5e0ea27ce9138bcbb205313343ee66a6e132f25c5ed67e2c8d960a1bc",
|
||||
"sha256:0a920ff98cf1aac310470c644bc23b326402d3ef667ddafecb024e1713d485f1",
|
||||
"sha256:1409b14bf83a7d729f92e2a7fbfe7ec929d4883ca071b06e95c539ceedb6497c",
|
||||
"sha256:17cae1730a782858a6e2758fd20dd0ef7567916c47757b694a06ffafdec20046",
|
||||
"sha256:17e3950add54c882e032527795c625929613adbd2ce5162b94667334458b5a36",
|
||||
"sha256:1f4f214337f6ee5825bf90a65d04d70aab05526c08191ab888cb5149501923c5",
|
||||
|
@ -402,11 +418,14 @@
|
|||
"sha256:760c12276fee05c36f95f8040180abc7fbebb9e5011447a97cdc289b5d6ab6fc",
|
||||
"sha256:796685d3969815a633827c818863ee199440696b0961e200b011d79b9394bbe7",
|
||||
"sha256:891fe897b49abb7db470c55664b198b1095e4943b9f82b7dcab317a19116cd38",
|
||||
"sha256:9277562f175d2334744ad297568677056861070399cec56ff06abbe2564d1232",
|
||||
"sha256:a471628e20f03dcdfde00770eeaf9c77811f0c331c8805219ca7b87ac17576c5",
|
||||
"sha256:a63b4fd3e2cabdcc9d918ed280bdde3e8e9641e04f3c59a2a3109644a07b9832",
|
||||
"sha256:ae88588d687bd476be588010cbbe551e9c2872b816f2da8f01f6f1fda74e1ef0",
|
||||
"sha256:b0b84408d4eabc6de9dd1e1e0bc63e7731e890c0b378a62443e5741cfd0ae90a",
|
||||
"sha256:be78485e5d5f3684e875dab60f40cddace2f5b2a8f7fede412358ab3214c3a6f",
|
||||
"sha256:c27eaed872185f047bb7f7da2d21a7d8913457678c9a100a50db6da890bc28b9",
|
||||
"sha256:c7fccd08b14aa437fe096c71c645c0f9be0655a9b1a4b7cffc77bcb23b3d61d2",
|
||||
"sha256:c81cb40bff373ab7a7446d6bbca0190bccc5be3448b47b51d729e37799bb5692",
|
||||
"sha256:d11874b3c33ee441059464711cd365b89fa1a9cf19ae75b0c189b01fbf735b84",
|
||||
"sha256:e9c028b5897901361d81a4718d1db217b716424a0283afe9d6735fe0caf70f79",
|
||||
|
@ -629,6 +648,12 @@
|
|||
],
|
||||
"version": "==2.4.2"
|
||||
},
|
||||
"pyrsistent": {
|
||||
"hashes": [
|
||||
"sha256:eb6545dbeb1aa69ab1fb4809bfbf5a8705e44d92ef8fc7c2361682a47c46c778"
|
||||
],
|
||||
"version": "==0.15.5"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
|
||||
|
@ -659,6 +684,7 @@
|
|||
"sha256:861c94442b28cd64af033e88e0f63c66dbd5609f67952dc18694098b47a43f3a",
|
||||
"sha256:957bc6316ffc8463795d56d9953d58e7f32aa5aad1c5ac80bc45c69f3299961e",
|
||||
"sha256:9760c3f56fb5f15852d163429096600906478e9ed2c189a52f2bb21d8a2a986c",
|
||||
"sha256:9fdfb98a2992de01e8efad2aeed22c825e36db628b144b2d6b93d81fb549f811",
|
||||
"sha256:a4b24703ea818196d0be1dc64b3b57b79c67e8dee0cfa207a4216220912035a7",
|
||||
"sha256:ad7f4968c1ddbf139a306d9b075360d959cc554d994ba5e1f512af9a40e62357",
|
||||
"sha256:b1127d34b90f74faf1707718c57a4193ac028b9f4aec0238638983132297d456",
|
||||
|
@ -669,6 +695,7 @@
|
|||
"sha256:ce777ebdf49ce736fc04abf555b5c41ab3f130127543a689dcf8d4871cd18fe4",
|
||||
"sha256:d8b4bf930b6a19bc9ee982b9163d948c87501ad91b71516924e8ed25fe85d2ee",
|
||||
"sha256:e2a420f2c4d35f3ec0b7e752a80d7bd385e2c5a64f67c05f2d2d74230e3114b6",
|
||||
"sha256:ef5eb630f541af6b69378d58594be90a0922fa6d6a50a9248c25b9502585f6bf",
|
||||
"sha256:fed899ce96f4f2b4d1b9f338dd145a4040ee1d8a5152213af0dd8d4a4d36e9fe"
|
||||
],
|
||||
"index": "pypi",
|
||||
|
@ -807,6 +834,14 @@
|
|||
"index": "pypi",
|
||||
"version": "==19.2.0"
|
||||
},
|
||||
"swagger-spec-validator": {
|
||||
"hashes": [
|
||||
"sha256:57e29feb3aa921a9fb98bd70af148746b27c77d3207266f5571cebcce211e685",
|
||||
"sha256:62ef22eca3f429d93fddda5d793d2a1a9057d3732e7a14606e641805326ae4a6"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.4.3"
|
||||
},
|
||||
"tempora": {
|
||||
"hashes": [
|
||||
"sha256:cb60b1d2b1664104e307f8e5269d7f4acdb077c82e35cd57246ae14a3427d2d6",
|
||||
|
@ -847,6 +882,13 @@
|
|||
"sha256:cc33599b549f0c8a248cb72f3bf32d77712de1ff7ee8814312eb6456b42c015f"
|
||||
],
|
||||
"version": "==2.0"
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e",
|
||||
"sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"
|
||||
],
|
||||
"version": "==0.6.0"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
|
@ -972,26 +1014,29 @@
|
|||
},
|
||||
"lazy-object-proxy": {
|
||||
"hashes": [
|
||||
"sha256:02b260c8deb80db09325b99edf62ae344ce9bc64d68b7a634410b8e9a568edbf",
|
||||
"sha256:18f9c401083a4ba6e162355873f906315332ea7035803d0fd8166051e3d402e3",
|
||||
"sha256:1f2c6209a8917c525c1e2b55a716135ca4658a3042b5122d4e3413a4030c26ce",
|
||||
"sha256:2f06d97f0ca0f414f6b707c974aaf8829c2292c1c497642f63824119d770226f",
|
||||
"sha256:616c94f8176808f4018b39f9638080ed86f96b55370b5a9463b2ee5c926f6c5f",
|
||||
"sha256:63b91e30ef47ef68a30f0c3c278fbfe9822319c15f34b7538a829515b84ca2a0",
|
||||
"sha256:77b454f03860b844f758c5d5c6e5f18d27de899a3db367f4af06bec2e6013a8e",
|
||||
"sha256:83fe27ba321e4cfac466178606147d3c0aa18e8087507caec78ed5a966a64905",
|
||||
"sha256:84742532d39f72df959d237912344d8a1764c2d03fe58beba96a87bfa11a76d8",
|
||||
"sha256:874ebf3caaf55a020aeb08acead813baf5a305927a71ce88c9377970fe7ad3c2",
|
||||
"sha256:9f5caf2c7436d44f3cec97c2fa7791f8a675170badbfa86e1992ca1b84c37009",
|
||||
"sha256:a0c8758d01fcdfe7ae8e4b4017b13552efa7f1197dd7358dc9da0576f9d0328a",
|
||||
"sha256:a4def978d9d28cda2d960c279318d46b327632686d82b4917516c36d4c274512",
|
||||
"sha256:ad4f4be843dace866af5fc142509e9b9817ca0c59342fdb176ab6ad552c927f5",
|
||||
"sha256:ae33dd198f772f714420c5ab698ff05ff900150486c648d29951e9c70694338e",
|
||||
"sha256:b4a2b782b8a8c5522ad35c93e04d60e2ba7f7dcb9271ec8e8c3e08239be6c7b4",
|
||||
"sha256:c462eb33f6abca3b34cdedbe84d761f31a60b814e173b98ede3c81bb48967c4f",
|
||||
"sha256:fd135b8d35dfdcdb984828c84d695937e58cc5f49e1c854eb311c4d6aa03f4f1"
|
||||
"sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d",
|
||||
"sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449",
|
||||
"sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08",
|
||||
"sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a",
|
||||
"sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50",
|
||||
"sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd",
|
||||
"sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239",
|
||||
"sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb",
|
||||
"sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea",
|
||||
"sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e",
|
||||
"sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156",
|
||||
"sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142",
|
||||
"sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442",
|
||||
"sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62",
|
||||
"sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db",
|
||||
"sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531",
|
||||
"sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383",
|
||||
"sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a",
|
||||
"sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357",
|
||||
"sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4",
|
||||
"sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"
|
||||
],
|
||||
"version": "==1.4.2"
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"mccabe": {
|
||||
"hashes": [
|
||||
|
|
|
@ -2,5 +2,6 @@
|
|||
# from django import forms
|
||||
|
||||
SOURCE_FORM_FIELDS = ['name', 'slug', 'enabled', 'policies']
|
||||
SOURCE_SERIALIZER_FIELDS = ['pk', 'name', 'slug', 'enabled', 'policies']
|
||||
|
||||
# class SourceForm(forms.Form)
|
||||
|
|
|
@ -25,5 +25,7 @@ class PolicyPermissions(BasePermission):
|
|||
policy_engine: PolicyEngine
|
||||
|
||||
def has_object_permission(self, request, view, obj: PolicyModel) -> bool:
|
||||
# if not obj.po
|
||||
self.policy_engine = PolicyEngine(obj.policies, request.user, request)
|
||||
self.policy_engine.request.obj = obj
|
||||
return self.policy_engine.build().passing
|
||||
|
|
|
@ -1,16 +1,85 @@
|
|||
"""api v2 urls"""
|
||||
from django.conf.urls import url
|
||||
from django.urls import path
|
||||
from drf_yasg import openapi
|
||||
from drf_yasg.views import get_schema_view
|
||||
from rest_framework import routers
|
||||
from structlog import get_logger
|
||||
|
||||
from passbook.api.permissions import CustomObjectPermissions
|
||||
from passbook.audit.api.events import EventViewSet
|
||||
from passbook.core.api.applications import ApplicationViewSet
|
||||
from passbook.core.api.groups import GroupViewSet
|
||||
from passbook.core.api.invitations import InvitationViewSet
|
||||
from passbook.core.api.policies import PolicyViewSet
|
||||
from passbook.core.api.providers import ProviderViewSet
|
||||
from passbook.core.api.sources import SourceViewSet
|
||||
from passbook.core.api.users import UserViewSet
|
||||
from passbook.lib.utils.reflection import get_apps
|
||||
from passbook.policies.expiry.api import PasswordExpiryPolicyViewSet
|
||||
from passbook.policies.group.api import GroupMembershipPolicyViewSet
|
||||
from passbook.policies.hibp.api import HaveIBeenPwendPolicyViewSet
|
||||
from passbook.policies.matcher.api import FieldMatcherPolicyViewSet
|
||||
from passbook.policies.password.api import PasswordPolicyViewSet
|
||||
from passbook.policies.reputation.api import ReputationPolicyViewSet
|
||||
from passbook.policies.sso.api import SSOLoginPolicyViewSet
|
||||
from passbook.policies.webhook.api import WebhookPolicyViewSet
|
||||
from passbook.providers.app_gw.api import ApplicationGatewayProviderViewSet
|
||||
from passbook.providers.oauth.api import OAuth2ProviderViewSet
|
||||
from passbook.providers.oidc.api import OpenIDProviderViewSet
|
||||
from passbook.providers.saml.api import SAMLProviderViewSet
|
||||
from passbook.sources.ldap.api import LDAPSourceViewSet
|
||||
from passbook.sources.oauth.api import OAuthSourceViewSet
|
||||
|
||||
LOGGER = get_logger()
|
||||
router = routers.DefaultRouter()
|
||||
|
||||
for _passbook_app in get_apps():
|
||||
if hasattr(_passbook_app, 'api_mountpoint'):
|
||||
for prefix, viewset in _passbook_app.api_mountpoint:
|
||||
router.register(prefix, viewset)
|
||||
LOGGER.debug("Mounted API URLs", app_name=_passbook_app.name)
|
||||
|
||||
router.register('core/applications', ApplicationViewSet)
|
||||
router.register('core/invitations', InvitationViewSet)
|
||||
router.register('core/groups', GroupViewSet)
|
||||
router.register('core/users', UserViewSet)
|
||||
router.register('audit/events', EventViewSet)
|
||||
urlpatterns = router.urls
|
||||
router.register('sources/all', SourceViewSet)
|
||||
router.register('sources/ldap', LDAPSourceViewSet)
|
||||
router.register('sources/oauth', OAuthSourceViewSet)
|
||||
router.register('policies/all', PolicyViewSet)
|
||||
router.register('policies/passwordexpiry', PasswordExpiryPolicyViewSet)
|
||||
router.register('policies/groupmembership', GroupMembershipPolicyViewSet)
|
||||
router.register('policies/haveibeenpwned', HaveIBeenPwendPolicyViewSet)
|
||||
router.register('policies/fieldmatcher', FieldMatcherPolicyViewSet)
|
||||
router.register('policies/password', PasswordPolicyViewSet)
|
||||
router.register('policies/reputation', ReputationPolicyViewSet)
|
||||
router.register('policies/ssologin', SSOLoginPolicyViewSet)
|
||||
router.register('policies/webhook', WebhookPolicyViewSet)
|
||||
router.register('providers/all', ProviderViewSet)
|
||||
router.register('providers/applicationgateway', ApplicationGatewayProviderViewSet)
|
||||
router.register('providers/oauth', OAuth2ProviderViewSet)
|
||||
router.register('providers/openid', OpenIDProviderViewSet)
|
||||
router.register('providers/saml', SAMLProviderViewSet)
|
||||
|
||||
info = openapi.Info(
|
||||
title="passbook API",
|
||||
default_version='v2',
|
||||
# description="Test description",
|
||||
# terms_of_service="https://www.google.com/policies/terms/",
|
||||
contact=openapi.Contact(email="hello@beryju.org"),
|
||||
license=openapi.License(name="MIT License"),
|
||||
)
|
||||
SchemaView = get_schema_view(
|
||||
info,
|
||||
public=True,
|
||||
permission_classes=(CustomObjectPermissions,),
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^swagger(?P<format>\.json|\.yaml)$',
|
||||
SchemaView.without_ui(cache_timeout=0), name='schema-json'),
|
||||
path('swagger/', SchemaView.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
|
||||
path('redoc/', SchemaView.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
|
||||
] + router.urls
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
"""Policy API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.core.models import Policy
|
||||
from passbook.policies.forms import GENERAL_FIELDS
|
||||
|
||||
|
||||
class PolicySerializer(ModelSerializer):
|
||||
"""Policy Serializer"""
|
||||
|
||||
__type__ = SerializerMethodField(method_name='get_type')
|
||||
|
||||
def get_type(self, obj):
|
||||
"""Get object type so that we know which API Endpoint to use to get the full object"""
|
||||
return obj._meta.object_name.lower().replace('policy', '')
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Policy
|
||||
fields = ['pk'] + GENERAL_FIELDS + ['__type__']
|
||||
|
||||
|
||||
class PolicyViewSet(ReadOnlyModelViewSet):
|
||||
"""Policy Viewset"""
|
||||
|
||||
queryset = Policy.objects.all()
|
||||
serializer_class = PolicySerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Policy.objects.select_subclasses()
|
|
@ -0,0 +1,30 @@
|
|||
"""Provider API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.core.models import Provider
|
||||
|
||||
|
||||
class ProviderSerializer(ModelSerializer):
|
||||
"""Provider Serializer"""
|
||||
|
||||
__type__ = SerializerMethodField(method_name='get_type')
|
||||
|
||||
def get_type(self, obj):
|
||||
"""Get object type so that we know which API Endpoint to use to get the full object"""
|
||||
return obj._meta.object_name.lower().replace('provider', '')
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Provider
|
||||
fields = ['pk', 'property_mappings', '__type__']
|
||||
|
||||
|
||||
class ProviderViewSet(ReadOnlyModelViewSet):
|
||||
"""Provider Viewset"""
|
||||
|
||||
queryset = Provider.objects.all()
|
||||
serializer_class = ProviderSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Provider.objects.select_subclasses()
|
|
@ -0,0 +1,31 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.admin.forms.source import SOURCE_SERIALIZER_FIELDS
|
||||
from passbook.core.models import Source
|
||||
|
||||
|
||||
class SourceSerializer(ModelSerializer):
|
||||
"""Source Serializer"""
|
||||
|
||||
__type__ = SerializerMethodField(method_name='get_type')
|
||||
|
||||
def get_type(self, obj):
|
||||
"""Get object type so that we know which API Endpoint to use to get the full object"""
|
||||
return obj._meta.object_name.lower().replace('source', '')
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Source
|
||||
fields = SOURCE_SERIALIZER_FIELDS + ['__type__']
|
||||
|
||||
|
||||
class SourceViewSet(ReadOnlyModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = Source.objects.all()
|
||||
serializer_class = SourceSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Source.objects.select_subclasses()
|
|
@ -33,15 +33,15 @@ class PolicyEngine:
|
|||
|
||||
use_cache: bool = True
|
||||
policies: List[Policy] = []
|
||||
__request: HttpRequest
|
||||
__user: User
|
||||
request: PolicyRequest
|
||||
|
||||
__processes: List[PolicyProcessInfo] = []
|
||||
|
||||
def __init__(self, policies, user: User = None, request: HttpRequest = None):
|
||||
def __init__(self, policies, user: User, request: HttpRequest = None):
|
||||
self.policies = policies
|
||||
self.__request = request
|
||||
self.__user = user
|
||||
self.request = PolicyRequest(user)
|
||||
if request:
|
||||
self.request.http_request = request
|
||||
self.__processes = []
|
||||
|
||||
def _select_subclasses(self) -> List[Policy]:
|
||||
|
@ -53,20 +53,16 @@ class PolicyEngine:
|
|||
|
||||
def build(self) -> 'PolicyEngine':
|
||||
"""Build task group"""
|
||||
if not self.__user:
|
||||
raise ValueError("User not set.")
|
||||
cached_policies = []
|
||||
request = PolicyRequest(self.__user)
|
||||
request.http_request = self.__request
|
||||
for policy in self._select_subclasses():
|
||||
cached_policy = cache.get(cache_key(policy, self.__user), None)
|
||||
cached_policy = cache.get(cache_key(policy, self.request.user), None)
|
||||
if cached_policy and self.use_cache:
|
||||
LOGGER.debug("Taking result from cache", policy=policy)
|
||||
cached_policies.append(cached_policy)
|
||||
else:
|
||||
LOGGER.debug("Evaluating policy", policy=policy)
|
||||
our_end, task_end = Pipe(False)
|
||||
task = PolicyProcess(policy, request, task_end)
|
||||
task = PolicyProcess(policy, self.request, task_end)
|
||||
LOGGER.debug("Starting Process", policy=policy)
|
||||
task.start()
|
||||
self.__processes.append(PolicyProcessInfo(process=task,
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.expiry.models import PasswordExpiryPolicy
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
|
||||
|
||||
class PasswordExpiryPolicySerializer(ModelSerializer):
|
||||
"""Password Expiry Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = PasswordExpiryPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS + ['days', 'deny_only']
|
||||
|
||||
|
||||
class PasswordExpiryPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = PasswordExpiryPolicy.objects.all()
|
||||
serializer_class = PasswordExpiryPolicySerializer
|
|
@ -1,3 +1,4 @@
|
|||
"""General fields"""
|
||||
|
||||
GENERAL_FIELDS = ['name', 'negate', 'order', 'timeout']
|
||||
GENERAL_SERIALIZER_FIELDS = ['pk', 'name', 'negate', 'order', 'timeout']
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
from passbook.policies.group.models import GroupMembershipPolicy
|
||||
|
||||
|
||||
class GroupMembershipPolicySerializer(ModelSerializer):
|
||||
"""Group Membership Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = GroupMembershipPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS + ['group']
|
||||
|
||||
|
||||
class GroupMembershipPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = GroupMembershipPolicy.objects.all()
|
||||
serializer_class = GroupMembershipPolicySerializer
|
|
@ -0,0 +1,21 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
from passbook.policies.hibp.models import HaveIBeenPwendPolicy
|
||||
|
||||
|
||||
class HaveIBeenPwendPolicySerializer(ModelSerializer):
|
||||
"""Have I Been Pwned Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = HaveIBeenPwendPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS + ['allowed_count']
|
||||
|
||||
|
||||
class HaveIBeenPwendPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = HaveIBeenPwendPolicy.objects.all()
|
||||
serializer_class = HaveIBeenPwendPolicySerializer
|
|
@ -0,0 +1,21 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
from passbook.policies.matcher.models import FieldMatcherPolicy
|
||||
|
||||
|
||||
class FieldMatcherPolicySerializer(ModelSerializer):
|
||||
"""Field Matcher Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = FieldMatcherPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS + ['user_field', 'match_action', 'value', ]
|
||||
|
||||
|
||||
class FieldMatcherPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = FieldMatcherPolicy.objects.all()
|
||||
serializer_class = FieldMatcherPolicySerializer
|
|
@ -0,0 +1,23 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
from passbook.policies.password.models import PasswordPolicy
|
||||
|
||||
|
||||
class PasswordPolicySerializer(ModelSerializer):
|
||||
"""Password Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = PasswordPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS + ['amount_uppercase', 'amount_lowercase',
|
||||
'amount_symbols', 'length_min', 'symbol_charset',
|
||||
'error_message']
|
||||
|
||||
|
||||
class PasswordPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = PasswordPolicy.objects.all()
|
||||
serializer_class = PasswordPolicySerializer
|
|
@ -0,0 +1,21 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
from passbook.policies.reputation.models import ReputationPolicy
|
||||
|
||||
|
||||
class ReputationPolicySerializer(ModelSerializer):
|
||||
"""Reputation Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = ReputationPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS + ['check_ip', 'check_username', 'threshold']
|
||||
|
||||
|
||||
class ReputationPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = ReputationPolicy.objects.all()
|
||||
serializer_class = ReputationPolicySerializer
|
|
@ -0,0 +1,21 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
from passbook.policies.sso.models import SSOLoginPolicy
|
||||
|
||||
|
||||
class SSOLoginPolicySerializer(ModelSerializer):
|
||||
"""SSO Login Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = SSOLoginPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS
|
||||
|
||||
|
||||
class SSOLoginPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = SSOLoginPolicy.objects.all()
|
||||
serializer_class = SSOLoginPolicySerializer
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING, List
|
||||
|
||||
from django.db.models import Model
|
||||
from django.http import HttpRequest
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -13,6 +14,7 @@ class PolicyRequest:
|
|||
|
||||
user: User
|
||||
http_request: HttpRequest
|
||||
obj: Model
|
||||
|
||||
def __init__(self, user: User):
|
||||
self.user = user
|
||||
|
|
|
@ -34,11 +34,6 @@ class PolicyTestEngine(TestCase):
|
|||
engine = PolicyEngine([], self.user)
|
||||
self.assertEqual(engine.build().passing, True)
|
||||
|
||||
def test_engine_without_user(self):
|
||||
"""Ensure engine raises error if no user is set"""
|
||||
with self.assertRaises(ValueError):
|
||||
PolicyEngine([]).build()
|
||||
|
||||
def test_engine(self):
|
||||
"""Ensure all policies passes (Mix of false and true -> false)"""
|
||||
engine = PolicyEngine(DebugPolicy.objects.filter(negate__exact=False), self.user)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
||||
from passbook.policies.webhook.models import WebhookPolicy
|
||||
|
||||
|
||||
class WebhookPolicySerializer(ModelSerializer):
|
||||
"""Webhook Policy Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = WebhookPolicy
|
||||
fields = GENERAL_SERIALIZER_FIELDS + ['url', 'method', 'json_body', 'json_headers',
|
||||
'result_jsonpath', 'result_json_value', ]
|
||||
|
||||
|
||||
class WebhookPolicyViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = WebhookPolicy.objects.all()
|
||||
serializer_class = WebhookPolicySerializer
|
|
@ -0,0 +1,21 @@
|
|||
"""ApplicationGatewayProvider API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.providers.app_gw.models import ApplicationGatewayProvider
|
||||
|
||||
|
||||
class ApplicationGatewayProviderSerializer(ModelSerializer):
|
||||
"""ApplicationGatewayProvider Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = ApplicationGatewayProvider
|
||||
fields = ['pk', 'server_name', 'upstream', 'enabled', 'authentication_header',
|
||||
'default_content_type', 'upstream_ssl_verification', 'property_mappings']
|
||||
|
||||
class ApplicationGatewayProviderViewSet(ModelViewSet):
|
||||
"""ApplicationGatewayProvider Viewset"""
|
||||
|
||||
queryset = ApplicationGatewayProvider.objects.all()
|
||||
serializer_class = ApplicationGatewayProviderSerializer
|
|
@ -0,0 +1,21 @@
|
|||
"""OAuth2Provider API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.providers.oauth.models import OAuth2Provider
|
||||
|
||||
|
||||
class OAuth2ProviderSerializer(ModelSerializer):
|
||||
"""OAuth2Provider Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = OAuth2Provider
|
||||
fields = ['pk', 'name', 'redirect_uris', 'client_type',
|
||||
'authorization_grant_type', 'client_id', 'client_secret', ]
|
||||
|
||||
class OAuth2ProviderViewSet(ModelViewSet):
|
||||
"""OAuth2Provider Viewset"""
|
||||
|
||||
queryset = OAuth2Provider.objects.all()
|
||||
serializer_class = OAuth2ProviderSerializer
|
|
@ -0,0 +1,22 @@
|
|||
"""OpenIDProvider API Views"""
|
||||
from oidc_provider.models import Client
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
# from passbook.providers.oidc.models import OpenIDProvider
|
||||
|
||||
|
||||
class OpenIDProviderSerializer(ModelSerializer):
|
||||
"""OpenIDProvider Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Client
|
||||
fields = ['pk', 'name', 'client_type', 'client_id', 'client_secret', 'response_types',
|
||||
'jwt_alg', 'reuse_consent', 'require_consent', '_redirect_uris', '_scope']
|
||||
|
||||
class OpenIDProviderViewSet(ModelViewSet):
|
||||
"""OpenIDProvider Viewset"""
|
||||
|
||||
queryset = Client.objects.all()
|
||||
serializer_class = OpenIDProviderSerializer
|
|
@ -0,0 +1,38 @@
|
|||
"""SAMLProvider API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.providers.saml.models import SAMLPropertyMapping, SAMLProvider
|
||||
|
||||
|
||||
class SAMLProviderSerializer(ModelSerializer):
|
||||
"""SAMLProvider Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = SAMLProvider
|
||||
fields = ['pk', 'name', 'property_mappings', 'acs_url', 'audience', 'processor_path',
|
||||
'issuer', 'assertion_valid_for', 'signing', 'signing_cert', 'signing_key', ]
|
||||
|
||||
|
||||
class SAMLProviderViewSet(ModelViewSet):
|
||||
"""SAMLProvider Viewset"""
|
||||
|
||||
queryset = SAMLProvider.objects.all()
|
||||
serializer_class = SAMLProviderSerializer
|
||||
|
||||
|
||||
class SAMLPropertyMappingSerializer(ModelSerializer):
|
||||
"""SAMLPropertyMapping Serializer"""
|
||||
|
||||
class Meta:
|
||||
|
||||
model = SAMLPropertyMapping
|
||||
fields = ['pk', 'name', 'saml_name', 'friendly_name', 'values']
|
||||
|
||||
|
||||
class SAMLPropertyMappingViewSet(ModelViewSet):
|
||||
"""SAMLPropertyMapping Viewset"""
|
||||
|
||||
queryset = SAMLPropertyMapping.objects.all()
|
||||
serializer_class = SAMLPropertyMappingSerializer
|
|
@ -104,12 +104,33 @@ INSTALLED_APPS = [
|
|||
|
||||
GUARDIAN_MONKEY_PATCH = False
|
||||
|
||||
SWAGGER_SETTINGS = {
|
||||
'DEFAULT_INFO': 'passbook.api.v2.urls.info',
|
||||
# 'SECURITY_DEFINITIONS': {
|
||||
# 'JWT': {
|
||||
# 'type': 'apiKey',
|
||||
# 'name': 'Authorization',
|
||||
# 'in': 'header'
|
||||
# }
|
||||
# }
|
||||
}
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
# Use Django's standard `django.contrib.auth` permissions,
|
||||
# or allow read-only access for unauthenticated users.
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
|
||||
]
|
||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
||||
'PAGE_SIZE': 100,
|
||||
'DEFAULT_FILTER_BACKENDS': [
|
||||
'django_filters.rest_framework.DjangoFilterBackend',
|
||||
'rest_framework.filters.OrderingFilter',
|
||||
'rest_framework.filters.SearchFilter',
|
||||
],
|
||||
'DEFAULT_PERMISSION_CLASSES': (
|
||||
# 'rest_framework.permissions.IsAuthenticated',
|
||||
'passbook.api.permissions.CustomObjectPermissions',
|
||||
),
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
# 'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
|
||||
),
|
||||
}
|
||||
|
||||
CACHES = {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.admin.forms.source import SOURCE_SERIALIZER_FIELDS
|
||||
from passbook.sources.ldap.models import LDAPSource
|
||||
|
||||
|
||||
class LDAPSourceSerializer(ModelSerializer):
|
||||
"""LDAP Source Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = LDAPSource
|
||||
fields = SOURCE_SERIALIZER_FIELDS + [
|
||||
'server_uri',
|
||||
'bind_cn',
|
||||
'bind_password',
|
||||
'start_tls',
|
||||
'base_dn',
|
||||
'additional_user_dn',
|
||||
'additional_group_dn',
|
||||
'user_object_filter',
|
||||
'group_object_filter',
|
||||
'user_group_membership_field',
|
||||
'object_uniqueness_field',
|
||||
'sync_groups',
|
||||
'sync_parent_group',
|
||||
'property_mappings',
|
||||
]
|
||||
extra_kwargs = {
|
||||
'password': {'bind_password': True}
|
||||
}
|
||||
|
||||
|
||||
class LDAPSourceViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = LDAPSource.objects.all()
|
||||
serializer_class = LDAPSourceSerializer
|
|
@ -0,0 +1,23 @@
|
|||
"""OAuth Source Serializer"""
|
||||
from rest_framework.serializers import ModelSerializer
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from passbook.admin.forms.source import SOURCE_SERIALIZER_FIELDS
|
||||
from passbook.sources.oauth.models import OAuthSource
|
||||
|
||||
|
||||
class OAuthSourceSerializer(ModelSerializer):
|
||||
"""OAuth Source Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = OAuthSource
|
||||
fields = SOURCE_SERIALIZER_FIELDS + ['provider_type', 'request_token_url',
|
||||
'authorization_url', 'access_token_url',
|
||||
'profile_url', 'consumer_key', 'consumer_secret']
|
||||
|
||||
|
||||
class OAuthSourceViewSet(ModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = OAuthSource.objects.all()
|
||||
serializer_class = OAuthSourceSerializer
|
Reference in New Issue