This commit is contained in:
mahdavi 2024-07-20 15:00:08 +03:30
parent 9ef96b9479
commit dffa0a86f8
17 changed files with 11 additions and 192 deletions

View file

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -1,6 +0,0 @@
from django.apps import AppConfig
class ApiConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.api'

View file

@ -1,19 +0,0 @@
from django.db import models
from oauth2_provider.models import get_application_model
from apps.users.models import User
Application = get_application_model()
class Invoke(models.Model):
caller_application = models.ForeignKey(to=Application, on_delete=models.PROTECT)
callee_application = models.CharField(to=Application, on_delete=models.PROTECT)
caller_user = models.ForeignKey(to=User, on_delete=models.PROTECT)
cost = models.DecimalField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# TODO: move to external model
request = models.JSONField()
response = models.JSONField()

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,9 +0,0 @@
from django.urls import path, include
from .views import myview
app_name = "core"
urlpatterns = [
# path('', HomeView.as_view(), name='home'),
path('proxy/(?P<path>.*)', myview),
]

View file

@ -1,129 +0,0 @@
import re
import requests
from django.http import HttpResponse
from django.http import QueryDict
from urllib.parse import urlparse
def proxy_view(request, url, requests_args=None):
"""
Forward as close to an exact copy of the request as possible along to the
given url. Respond with as close to an exact copy of the resulting
response as possible.
If there are any additional arguments you wish to send to requests, put
them in the requests_args dictionary.
"""
requests_args = (requests_args or {}).copy()
headers = get_headers(request.META)
params = request.GET.copy()
if 'headers' not in requests_args:
requests_args['headers'] = {}
if 'data' not in requests_args:
requests_args['data'] = request.body
if 'params' not in requests_args:
requests_args['params'] = QueryDict('', mutable=True)
# Overwrite any headers and params from the incoming request with explicitly
# specified values for the requests library.
headers.update(requests_args['headers'])
params.update(requests_args['params'])
# If there's a content-length header from Django, it's probably in all-caps
# and requests might not notice it, so just remove it.
for key in list(headers.keys()):
if key.lower() == 'content-length':
del headers[key]
requests_args['headers'] = headers
requests_args['params'] = params
response = requests.request(request.method, url, **requests_args)
proxy_response = HttpResponse(
response.content,
status=response.status_code)
excluded_headers = set([
# Hop-by-hop headers
# ------------------
# Certain response headers should NOT be just tunneled through. These
# are they. For more info, see:
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
'connection', 'keep-alive', 'proxy-authenticate',
'proxy-authorization', 'te', 'trailers', 'transfer-encoding',
'upgrade',
# Although content-encoding is not listed among the hop-by-hop headers,
# it can cause trouble as well. Just let the server set the value as
# it should be.
'content-encoding',
# Since the remote server may or may not have sent the content in the
# same encoding as Django will, let Django worry about what the length
# should be.
'content-length',
])
# Treat Set-Cookie header in a special way, as Django uses a cookie jar to
# manage cookies instead of the normal headers dict:
# https://docs.djangoproject.com/en/5.0/ref/request-response/#django.http.HttpResponse.headers
#
# Use headers.get instead of headers.pop in case there are users that rely
# on the Set-Cookie header value.
cookies_header = response.headers.get('set-cookie', '')
proxy_response.cookies.load(cookies_header)
for key, value in response.headers.items():
if key.lower() in excluded_headers:
continue
elif key.lower() == 'location':
# If the location is relative at all, we want it to be absolute to
# the upstream server.
proxy_response[key] = make_absolute_location(response.url, value)
else:
proxy_response[key] = value
return proxy_response
def make_absolute_location(base_url, location):
"""
Convert a location header into an absolute URL.
"""
absolute_pattern = re.compile(r'^[a-zA-Z]+://.*$')
if absolute_pattern.match(location):
return location
parsed_url = urlparse(base_url)
if location.startswith('//'):
# scheme relative
return parsed_url.scheme + ':' + location
elif location.startswith('/'):
# host relative
return parsed_url.scheme + '://' + parsed_url.netloc + location
else:
# path relative
return parsed_url.scheme + '://' + parsed_url.netloc + parsed_url.path.rsplit('/', 1)[0] + '/' + location
return location
def get_headers(environ):
"""
Retrieve the HTTP headers from a WSGI environment dictionary. See
https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.META
"""
headers = {}
for key, value in environ.items():
# Sometimes, things don't like when you send the requesting host through.
if key.startswith('HTTP_') and key != 'HTTP_HOST':
headers[key[5:].replace('_', '-')] = value
elif key in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
headers[key.replace('_', '-')] = value
return headers

View file

@ -1,12 +0,0 @@
from django.shortcuts import render
# Create your views here.
from django.views.decorators.csrf import csrf_exempt
from .utils.views import proxy_view
@csrf_exempt
def proxy_view(request, path):
extra_requests_args = {...}
remoteurl = 'http://<host_name>/' + path
return proxy_view(request, remoteurl, extra_requests_args)

View file

@ -24,4 +24,4 @@ class OAUTHLoginRequestForm(forms.ModelForm):
class AccountUpdateForm(forms.ModelForm):
class Meta:
model = UserModel
fields = ['iban']
fields = []

View file

@ -91,7 +91,7 @@ class OAuthCode(models.Model):
return code_challenge
def generate_login_url(self):
url = f'''{settings.BASE_OAUTH2_PROVIDER_URL}/oauth2/authorize/?response_type=code&code_challenge={self.generate_code_challenge()}&code_challenge_method=S256&client_id={settings.CLIENT_ID}&scope=wallet.wallet:get_balance+wallet.transaction:list&state={self.uuid}'''
url = f'''{settings.BASE_OAUTH2_PROVIDER_URL}/oauth2/authorize/?response_type=code&code_challenge={self.generate_code_challenge()}&code_challenge_method=S256&client_id={settings.CLIENT_ID}&scope={settings.SCOPES}&state={self.uuid}'''
return url
def validate_code(self):

View file

@ -8,5 +8,5 @@
{% block content %}
wallet
data crud
{% endblock %}

View file

@ -4,8 +4,8 @@
{#{% load jalali_tags %}#}
{#{% load tags %}#}
{% block title %}wallet: user account{% endblock %}
{% block page_title %}wallet: user account{% endblock %}
{% block title %}data crud: user account{% endblock %}
{% block page_title %}data crud: user account{% endblock %}
{% block page_action %}
<div class="me-2">

View file

@ -3,8 +3,8 @@
{% load crispy_forms_tags %}
{% load jalali_tags %}
{% block title %}user account{% endblock %}
{% block page_title %}user account{% endblock %}
{% block title %}data crud: user account{% endblock %}
{% block page_title %}data crud: user account{% endblock %}
{% block content %}
<form action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data" novalidate>

View file

@ -4,8 +4,8 @@
{#{% load jalali_tags %}#}
{#{% load tags %}#}
{% block title %}wallet: user account{% endblock %}
{% block page_title %}wallet: user account{% endblock %}
{% block title %}data crud: user account{% endblock %}
{% block page_title %}data crud: user account{% endblock %}
{% block page_action %}
<div class="me-2">

View file

@ -4,8 +4,8 @@
{#{% load jalali_tags %}#}
{#{% load tags %}#}
{% block title %}wallet: user account{% endblock %}
{% block page_title %}wallet: user account{% endblock %}
{% block title %}data crud: user account{% endblock %}
{% block page_title %}data crud: user account{% endblock %}
{% block content %}
<form method="post" action="{% url 'users:login_request' %}">