Add more logics bareframes

This commit is contained in:
Reckless_Satoshi 2022-01-06 12:33:40 -08:00
parent a1771ae5ea
commit 34e05465c2
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
8 changed files with 173 additions and 117 deletions

View File

@ -30,7 +30,7 @@ class OrderAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
@admin.register(LNPayment) @admin.register(LNPayment)
class LNPaymentAdmin(AdminChangeLinksMixin, admin.ModelAdmin): class LNPaymentAdmin(AdminChangeLinksMixin, admin.ModelAdmin):
list_display = ('id','concept','status','num_satoshis','type','invoice','preimage','expires_at','sender_link','receiver_link') list_display = ('id','concept','status','num_satoshis','type','invoice','expires_at','sender_link','receiver_link')
list_display_links = ('id','concept') list_display_links = ('id','concept')
change_links = ('sender','receiver') change_links = ('sender','receiver')

View File

@ -13,7 +13,7 @@ class LNNode():
Place holder functions to interact with Lightning Node Place holder functions to interact with Lightning Node
''' '''
def gen_hodl_invoice(num_satoshis, description): def gen_hodl_invoice(num_satoshis, description, expiry):
'''Generates hodl invoice to publish an order''' '''Generates hodl invoice to publish an order'''
# TODO # TODO
invoice = ''.join(random.choices(string.ascii_uppercase + string.digits, k=80)) #FIX invoice = ''.join(random.choices(string.ascii_uppercase + string.digits, k=80)) #FIX

View File

@ -11,6 +11,12 @@ BOND_SIZE = float(config('BOND_SIZE'))
MARKET_PRICE_API = config('MARKET_PRICE_API') MARKET_PRICE_API = config('MARKET_PRICE_API')
ESCROW_USERNAME = config('ESCROW_USERNAME') ESCROW_USERNAME = config('ESCROW_USERNAME')
EXP_MAKER_BOND_INVOICE = int(config('EXP_MAKER_BOND_INVOICE'))
EXP_TAKER_BOND_INVOICE = int(config('EXP_TAKER_BOND_INVOICE'))
EXP_TRADE_ESCR_INVOICE = int(config('EXP_TRADE_ESCR_INVOICE'))
BOND_EXPIRY = int(config('BOND_EXPIRY'))
ESCROW_EXPIRY = int(config('ESCROW_EXPIRY'))
class Logics(): class Logics():
@ -46,12 +52,10 @@ class Logics():
if order.is_explicit: if order.is_explicit:
satoshis_now = order.satoshis satoshis_now = order.satoshis
else: else:
# TODO Add fallback Public APIs and error handling
market_prices = requests.get(MARKET_PRICE_API).json() market_prices = requests.get(MARKET_PRICE_API).json()
print(market_prices)
exchange_rate = float(market_prices[Order.Currencies(order.currency).label]['last']) exchange_rate = float(market_prices[Order.Currencies(order.currency).label]['last'])
print(exchange_rate)
satoshis_now = ((float(order.amount) * 1+float(order.premium)) / exchange_rate) * 100*1000*1000 satoshis_now = ((float(order.amount) * 1+float(order.premium)) / exchange_rate) * 100*1000*1000
print(satoshis_now)
return satoshis_now return satoshis_now
@ -85,25 +89,57 @@ class Logics():
if order.status == Order.Status.FAI: if order.status == Order.Status.FAI:
order.status = Order.Status.UPI order.status = Order.Status.UPI
order.save() order.save()
return True return True, None
return False, {'bad_request':'Invalid Lightning Network Invoice. It starts by LNTB...'}
@classmethod
def cancel_order(cls, order, user, state):
# 1) When maker cancels before bond
'''The order never shows up on the book and status
changes to cancelled. That's it.'''
# 2) When maker cancels after bond
'''The order dissapears from book and goes to cancelled.
Maker is charged a small amount of sats, to prevent DDOS
on the LN node and order book'''
# 3) When taker cancels before bond
''' The order goes back to the book as public.
LNPayment "order.taker_bond" is deleted() '''
# 4) When taker or maker cancel after bond
'''The order goes into cancelled status if maker cancels.
The order goes into the public book if taker cancels.
In both cases there is a small fee.'''
# 5) When trade collateral has been posted
'''Always goes to cancelled status. Collaboration is needed.
When a user asks for cancel, 'order.is_pending_cancel' goes True.
When the second user asks for cancel. Order is totally cancelled.
Has a small cost for both parties to prevent node DDOS.'''
pass
return False
@classmethod @classmethod
def gen_maker_hodl_invoice(cls, order, user): def gen_maker_hodl_invoice(cls, order, user):
# Do not and delete if order is more than 5 minutes old # Do not gen and delete if order is more than 5 minutes old
if order.expires_at < timezone.now(): if order.expires_at < timezone.now():
cls.order_expires(order) cls.order_expires(order)
return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'} return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'}
# Return the previous invoice if there was one
if order.maker_bond: if order.maker_bond:
return True, {'invoice':order.maker_bond.invoice,'bond_satoshis':order.maker_bond.num_satoshis} return True, {'invoice':order.maker_bond.invoice,'bond_satoshis':order.maker_bond.num_satoshis}
order.satoshis_now = cls.satoshis_now(order) order.satoshis_now = cls.satoshis_now(order)
bond_satoshis = order.satoshis_now * BOND_SIZE bond_satoshis = order.satoshis_now * BOND_SIZE
description = f'Robosats maker bond for order ID {order.id}. Will return to you if you do not cheat!' description = f'RoboSats - Maker bond for order ID {order.id}. These sats will return to you if you do not cheat!'
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(num_satoshis = bond_satoshis, description=description)
# Gen HODL Invoice
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(bond_satoshis, description, BOND_EXPIRY*3600)
order.maker_bond = LNPayment.objects.create( order.maker_bond = LNPayment.objects.create(
concept = LNPayment.Concepts.MAKEBOND, concept = LNPayment.Concepts.MAKEBOND,
@ -115,30 +151,32 @@ class Logics():
num_satoshis = bond_satoshis, num_satoshis = bond_satoshis,
description = description, description = description,
payment_hash = payment_hash, payment_hash = payment_hash,
expires_at = expires_at, expires_at = expires_at)
)
order.save() order.save()
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis} return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}
@classmethod @classmethod
def gen_taker_buyer_hodl_invoice(cls, order, user): def gen_takerbuyer_hodl_invoice(cls, order, user):
# Do not and delete if order is more than 5 minutes old # Do not gen and cancel if a taker invoice is there and older than 2 minutes
if order.expires_at < timezone.now(): if order.taker_bond.created_at < (timezone.now()+timedelta(minutes=EXP_TAKER_BOND_INVOICE)):
cls.order_expires(order) cls.cancel_order(order, user, 3) # State 3, cancel order before taker bond
return False, {'Order expired':'cannot generate a bond invoice for an expired order. Make a new one.'} return False, {'Invoice expired':'You did not confirm taking the order in time.'}
if order.maker_bond: # Return the previous invoice if there was one
return True, {'invoice':order.maker_bond.invoice,'bond_satoshis':order.maker_bond.num_satoshis} if order.taker_bond:
return True, {'invoice':order.taker_bond.invoice,'bond_satoshis':order.taker_bond.num_satoshis}
order.satoshis_now = cls.satoshis_now(order) order.satoshis_now = cls.satoshis_now(order)
bond_satoshis = order.satoshis_now * BOND_SIZE bond_satoshis = order.satoshis_now * BOND_SIZE
description = f'Robosats maker bond for order ID {order.id}. Will return to you if you do not cheat!' description = f'RoboSats - Taker bond for order ID {order.id}. These sats will return to you if you do not cheat!'
invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(num_satoshis = bond_satoshis, description=description)
order.maker_bond = LNPayment.objects.create( # Gen HODL Invoice
concept = LNPayment.Concepts.MAKEBOND, invoice, payment_hash, expires_at = LNNode.gen_hodl_invoice(bond_satoshis, description, BOND_EXPIRY*3600)
order.taker_bond = LNPayment.objects.create(
concept = LNPayment.Concepts.TAKEBOND,
type = LNPayment.Types.HODL, type = LNPayment.Types.HODL,
sender = user, sender = user,
receiver = User.objects.get(username=ESCROW_USERNAME), receiver = User.objects.get(username=ESCROW_USERNAME),
@ -147,8 +185,7 @@ class Logics():
num_satoshis = bond_satoshis, num_satoshis = bond_satoshis,
description = description, description = description,
payment_hash = payment_hash, payment_hash = payment_hash,
expires_at = expires_at, expires_at = expires_at)
)
order.save() order.save()
return True, {'invoice':invoice,'bond_satoshis':bond_satoshis} return True, {'invoice':invoice,'bond_satoshis':bond_satoshis}

View File

@ -49,7 +49,6 @@ class LNPayment(models.Model):
# payment info # payment info
invoice = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True) invoice = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
payment_hash = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True) payment_hash = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
preimage = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
description = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True) description = models.CharField(max_length=300, unique=False, null=True, default=None, blank=True)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
expires_at = models.DateTimeField() expires_at = models.DateTimeField()
@ -79,22 +78,21 @@ class Order(models.Model):
PUB = 1, 'Public' PUB = 1, 'Public'
DEL = 2, 'Deleted' DEL = 2, 'Deleted'
TAK = 3, 'Waiting for taker bond' # only needed when taker is a buyer TAK = 3, 'Waiting for taker bond' # only needed when taker is a buyer
UCA = 4, 'Unilaterally cancelled' UCA = 4, 'Cancelled'
RET = 5, 'Returned to order book' # Probably same as 1 in most cases. WF2 = 5, 'Waiting for trade collateral and buyer invoice'
WF2 = 6, 'Waiting for trade collateral and buyer invoice' WTC = 6, 'Waiting only for seller trade collateral'
WTC = 7, 'Waiting only for trade collateral' WBI = 7, 'Waiting only for buyer invoice'
WBI = 8, 'Waiting only for buyer invoice' EXF = 8, 'Sending fiat - In chatroom'
EXF = 9, 'Exchanging fiat / In chat' CCA = 9, 'Collaboratively cancelled'
CCA = 10, 'Collaboratively cancelled' FSE = 10, 'Fiat sent - In chatroom'
FSE = 11, 'Fiat sent' FCO = 11, 'Fiat confirmed'
FCO = 12, 'Fiat confirmed' SUC = 12, 'Sucessfully settled'
SUC = 13, 'Sucessfully settled' FAI = 13, 'Failed lightning network routing'
FAI = 14, 'Failed lightning network routing' UPI = 14, 'Updated invoice'
UPI = 15, 'Updated invoice' DIS = 15, 'In dispute'
DIS = 16, 'In dispute' MLD = 16, 'Maker lost dispute'
MLD = 17, 'Maker lost dispute' TLD = 17, 'Taker lost dispute'
TLD = 18, 'Taker lost dispute' EXP = 18, 'Expired'
EXP = 19, 'Expired'
# order info # order info
status = models.PositiveSmallIntegerField(choices=Status.choices, null=False, default=Status.WFB) status = models.PositiveSmallIntegerField(choices=Status.choices, null=False, default=Status.WFB)
@ -117,10 +115,10 @@ class Order(models.Model):
t0_satoshis = models.PositiveBigIntegerField(null=True, validators=[MinValueValidator(MIN_TRADE), MaxValueValidator(MAX_TRADE)], blank=True) # sats at creation t0_satoshis = models.PositiveBigIntegerField(null=True, validators=[MinValueValidator(MIN_TRADE), MaxValueValidator(MAX_TRADE)], blank=True) # sats at creation
last_satoshis = models.PositiveBigIntegerField(null=True, validators=[MinValueValidator(0), MaxValueValidator(MAX_TRADE*2)], blank=True) # sats last time checked. Weird if 2* trade max... last_satoshis = models.PositiveBigIntegerField(null=True, validators=[MinValueValidator(0), MaxValueValidator(MAX_TRADE*2)], blank=True) # sats last time checked. Weird if 2* trade max...
# order participants # order participants
maker = models.ForeignKey(User, related_name='maker', on_delete=models.CASCADE, null=True, default=None) # unique = True, a maker can only make one order maker = models.ForeignKey(User, related_name='maker', on_delete=models.CASCADE, null=True, default=None) # unique = True, a maker can only make one order
taker = models.ForeignKey(User, related_name='taker', on_delete=models.SET_NULL, null=True, default=None, blank=True) # unique = True, a taker can only take one order taker = models.ForeignKey(User, related_name='taker', on_delete=models.SET_NULL, null=True, default=None, blank=True) # unique = True, a taker can only take one order
is_pending_cancel = models.BooleanField(default=False, null=False) # When collaborative cancel is needed and one partner has cancelled.
# order collateral # order collateral
maker_bond = models.ForeignKey(LNPayment, related_name='maker_bond', on_delete=models.SET_NULL, null=True, default=None, blank=True) maker_bond = models.ForeignKey(LNPayment, related_name='maker_bond', on_delete=models.SET_NULL, null=True, default=None, blank=True)

View File

@ -11,12 +11,7 @@ class MakeOrderSerializer(serializers.ModelSerializer):
model = Order model = Order
fields = ('type','currency','amount','payment_method','is_explicit','premium','satoshis') fields = ('type','currency','amount','payment_method','is_explicit','premium','satoshis')
class UpdateOrderSerializer(serializers.ModelSerializer): class UpdateOrderSerializer(serializers.Serializer):
class Meta: invoice = serializers.CharField(max_length=300, allow_null=True, allow_blank=True, default=None)
model = Order action = serializers.ChoiceField(choices=('take','dispute','cancel','confirm','rate'), allow_null=False)
fields = ('id','buyer_invoice') rating = serializers.ChoiceField(choices=('1','2','3','4','5'), allow_null=True, allow_blank=True, default=None)
class UpdateInvoiceSerializer(serializers.ModelSerializer):
class Meta:
model = LNPayment
fields = ['invoice']

View File

@ -3,7 +3,7 @@ from .views import OrderMakerView, OrderView, UserView, BookView
urlpatterns = [ urlpatterns = [
path('make/', OrderMakerView.as_view()), path('make/', OrderMakerView.as_view()),
path('order/', OrderView.as_view({'get':'get','post':'take_or_update'})), path('order/', OrderView.as_view({'get':'get','post':'take_update_confirm_dispute_cancel'})),
path('usergen/', UserView.as_view()), path('usergen/', UserView.as_view()),
path('book/', BookView.as_view()), path('book/', BookView.as_view()),
] ]

View File

@ -7,9 +7,9 @@ from rest_framework.response import Response
from django.contrib.auth import authenticate, login, logout from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User from django.contrib.auth.models import User
from .serializers import ListOrderSerializer, MakeOrderSerializer, UpdateInvoiceSerializer from .serializers import ListOrderSerializer, MakeOrderSerializer, UpdateOrderSerializer
from .models import Order from .models import Order
from .logics import Logics from .logics import EXP_MAKER_BOND_INVOICE, Logics
from .nick_generator.nick_generator import NickGenerator from .nick_generator.nick_generator import NickGenerator
from robohash import Robohash from robohash import Robohash
@ -23,7 +23,7 @@ from django.utils import timezone
from decouple import config from decouple import config
EXPIRATION_MAKE = config('EXPIRATION_MAKE') EXP_MAKER_BOND_INVOICE = int(config('EXP_MAKER_BOND_INVOICE'))
avatar_path = Path('frontend/static/assets/avatars') avatar_path = Path('frontend/static/assets/avatars')
avatar_path.mkdir(parents=True, exist_ok=True) avatar_path.mkdir(parents=True, exist_ok=True)
@ -36,8 +36,9 @@ class OrderMakerView(CreateAPIView):
def post(self,request): def post(self,request):
serializer = self.serializer_class(data=request.data) serializer = self.serializer_class(data=request.data)
if serializer.is_valid(): if not serializer.is_valid(): return Response(status=status.HTTP_400_BAD_REQUEST)
otype = serializer.data.get('type')
type = serializer.data.get('type')
currency = serializer.data.get('currency') currency = serializer.data.get('currency')
amount = serializer.data.get('amount') amount = serializer.data.get('amount')
payment_method = serializer.data.get('payment_method') payment_method = serializer.data.get('payment_method')
@ -46,34 +47,28 @@ class OrderMakerView(CreateAPIView):
is_explicit = serializer.data.get('is_explicit') is_explicit = serializer.data.get('is_explicit')
valid, context = Logics.validate_already_maker_or_taker(request.user) valid, context = Logics.validate_already_maker_or_taker(request.user)
if not valid: if not valid: return Response(context, status=status.HTTP_409_CONFLICT)
return Response(context, status=status.HTTP_409_CONFLICT)
# Creates a new order in db # Creates a new order
order = Order( order = Order(
type=otype, type=type,
status=Order.Status.WFB,
currency=currency, currency=currency,
amount=amount, amount=amount,
payment_method=payment_method, payment_method=payment_method,
premium=premium, premium=premium,
satoshis=satoshis, satoshis=satoshis,
is_explicit=is_explicit, is_explicit=is_explicit,
expires_at=timezone.now()+timedelta(minutes=EXPIRATION_MAKE), expires_at=timezone.now()+timedelta(minutes=EXP_MAKER_BOND_INVOICE),
maker=request.user) maker=request.user)
order.t0_satoshis=Logics.satoshis_now(order) # TODO reate Order class method when new instance is created! order.last_satoshis = order.t0_satoshis = Logics.satoshis_now(order) # TODO move to Order class method when new instance is created!
order.last_satoshis=Logics.satoshis_now(order)
order.save() order.save()
if not serializer.is_valid():
return Response(status=status.HTTP_400_BAD_REQUEST)
return Response(ListOrderSerializer(order).data, status=status.HTTP_201_CREATED) return Response(ListOrderSerializer(order).data, status=status.HTTP_201_CREATED)
class OrderView(viewsets.ViewSet): class OrderView(viewsets.ViewSet):
serializer_class = UpdateInvoiceSerializer serializer_class = UpdateOrderSerializer
lookup_url_kwarg = 'order_id' lookup_url_kwarg = 'order_id'
def get(self, request, format=None): def get(self, request, format=None):
@ -88,7 +83,7 @@ class OrderView(viewsets.ViewSet):
if len(order) == 1 : if len(order) == 1 :
order = order[0] order = order[0]
# If order expired # 1) If order expired
if order.status == Order.Status.EXP: if order.status == Order.Status.EXP:
return Response({'bad_request':'This order has expired'},status.HTTP_400_BAD_REQUEST) return Response({'bad_request':'This order has expired'},status.HTTP_400_BAD_REQUEST)
@ -99,11 +94,11 @@ class OrderView(viewsets.ViewSet):
data['is_taker'] = order.taker == request.user data['is_taker'] = order.taker == request.user
data['is_participant'] = data['is_maker'] or data['is_taker'] data['is_participant'] = data['is_maker'] or data['is_taker']
# If not a participant and order is not public, forbid. # 2) If not a participant and order is not public, forbid.
if not data['is_participant'] and order.status != Order.Status.PUB: if not data['is_participant'] and order.status != Order.Status.PUB:
return Response({'bad_request':'Not allowed to see this order'},status.HTTP_403_FORBIDDEN) return Response({'bad_request':'Not allowed to see this order'},status.HTTP_403_FORBIDDEN)
# non participants can view some details, but only if PUB # 3) Non participants can view details (but only if PUB)
elif not data['is_participant'] and order.status != Order.Status.PUB: elif not data['is_participant'] and order.status != Order.Status.PUB:
return Response(data, status=status.HTTP_200_OK) return Response(data, status=status.HTTP_200_OK)
@ -114,45 +109,73 @@ class OrderView(viewsets.ViewSet):
data['taker_nick'] = str(order.taker) data['taker_nick'] = str(order.taker)
data['status_message'] = Order.Status(order.status).label data['status_message'] = Order.Status(order.status).label
# If status is 'waiting for maker bond', reply with a hodl invoice too. # 4) If status is 'waiting for maker bond', reply with a MAKER HODL invoice.
if order.status == Order.Status.WFB and data['is_maker']: if order.status == Order.Status.WFB and data['is_maker']:
valid, context = Logics.gen_maker_hodl_invoice(order, request.user) valid, context = Logics.gen_maker_hodl_invoice(order, request.user)
if valid: data = {**data, **context} if valid else Response(context, status.HTTP_400_BAD_REQUEST)
data = {**data, **context}
else: # 5) If status is 'Public' and user is taker/buyer, reply with a TAKER HODL invoice.
Response(context, status=status.HTTP_400_BAD_REQUEST) elif order.status == Order.Status.PUB and data['is_taker'] and data['is_buyer']:
valid, context = Logics.gen_takerbuyer_hodl_invoice(order, request.user)
data = {**data, **context} if valid else Response(context, status.HTTP_400_BAD_REQUEST)
# 6) If status is 'Public' and user is taker/seller, reply with a ESCROW HODL invoice.
elif order.status == Order.Status.PUB and data['is_taker'] and data['is_seller']:
valid, context = Logics.gen_seller_hodl_invoice(order, request.user)
data = {**data, **context} if valid else Response(context, status.HTTP_400_BAD_REQUEST)
# 7) If status is 'WF2/WTC' and user is maker/seller, reply with an ESCROW HODL invoice.
elif (order.status == Order.Status.WF2 or order.status == Order.Status.WF2) and data['is_maker'] and data['is_seller']:
valid, context = Logics.gen_seller_hodl_invoice(order, request.user)
data = {**data, **context} if valid else Response(context, status=status.HTTP_400_BAD_REQUEST)
return Response(data, status=status.HTTP_200_OK) return Response(data, status=status.HTTP_200_OK)
return Response({'Order Not Found':'Invalid Order Id'},status=status.HTTP_404_NOT_FOUND) return Response({'Order Not Found':'Invalid Order Id'},status=status.HTTP_404_NOT_FOUND)
def take_update_confirm_dispute_cancel(self, request, format=None):
def take_or_update(self, request, format=None):
order_id = request.GET.get(self.lookup_url_kwarg) order_id = request.GET.get(self.lookup_url_kwarg)
serializer = UpdateInvoiceSerializer(data=request.data) serializer = UpdateOrderSerializer(data=request.data)
if not serializer.is_valid(): return Response(status=status.HTTP_400_BAD_REQUEST)
order = Order.objects.get(id=order_id) order = Order.objects.get(id=order_id)
if serializer.is_valid(): # action is either 1)'take', 2)'confirm', 3)'cancel', 4)'dispute' , 5)'update' (invoice) 6)'rate' (counterparty)
action = serializer.data.get('action')
invoice = serializer.data.get('invoice') invoice = serializer.data.get('invoice')
rating = serializer.data.get('rating')
# 1) If action is take, it is be taker request!
# If this is an empty POST request (no invoice), it must be taker request! if action == 'take':
if not invoice and order.status == Order.Status.PUB: if order.status == Order.Status.PUB:
valid, context = Logics.validate_already_maker_or_taker(request.user) valid, context = Logics.validate_already_maker_or_taker(request.user)
if not valid: return Response(context, status=status.HTTP_409_CONFLICT) if not valid: return Response(context, status=status.HTTP_409_CONFLICT)
Logics.take(order, request.user) Logics.take(order, request.user)
else: Response({'bad_request':'This order is not public anymore.'}, status.HTTP_400_BAD_REQUEST)
# An invoice came in! update it # 2) If action is update (invoice)
elif invoice: elif action == 'update' and invoice:
print(invoice) updated, context = Logics.update_invoice(order,request.user,invoice)
updated = Logics.update_invoice(order=order,user=request.user,invoice=invoice) if not updated: return Response(context,status.HTTP_400_BAD_REQUEST)
if not updated:
return Response({'bad_request':'Invalid Lightning Network Invoice. It starts by LNTB...'})
# Something else is going on. Probably not allowed. # 3) If action is cancel
elif action == 'cancel':
pass
# 4) If action is confirm
elif action == 'confirm':
pass
# 5) If action is dispute
elif action == 'dispute':
pass
# 6) If action is dispute
elif action == 'rate' and rating:
pass
# If nothing... something else is going on. Probably not allowed!
else: else:
return Response({'bad_request':'Not allowed'}) return Response({'bad_request':'Not allowed'})
@ -264,6 +287,7 @@ class BookView(ListAPIView):
user = User.objects.filter(id=data['maker']) user = User.objects.filter(id=data['maker'])
if len(user) == 1: if len(user) == 1:
data['maker_nick'] = user[0].username data['maker_nick'] = user[0].username
# Non participants should not see the status or who is the taker # Non participants should not see the status or who is the taker
for key in ('status','taker'): for key in ('status','taker'):
del data[key] del data[key]

View File

@ -87,8 +87,10 @@ export default class OrderPage extends Component {
console.log(this.state) console.log(this.state)
const requestOptions = { const requestOptions = {
method: 'POST', method: 'POST',
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')}, headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
body: JSON.stringify({}), body: JSON.stringify({
'action':'take',
}),
}; };
fetch('/api/order/' + '?order_id=' + this.orderId, requestOptions) fetch('/api/order/' + '?order_id=' + this.orderId, requestOptions)
.then((response) => response.json()) .then((response) => response.json())