Commit 278ac10c authored by Stauros Kroustouris's avatar Stauros Kroustouris

fod rest api

parent 7dc37a14
......@@ -37,6 +37,50 @@ You can find the installation instructions for Debian Wheezy (64)
with Django 1.4.x at [Flowspy documentation](http://flowspy.readthedocs.org).
If upgrading from a previous version bear in mind the changes introduced in Django 1.4.
##Rest Api##
FoD provides a rest api. It uses token as authentication method.
### Generating Tokens
A user can generate a token for his account on "my profile" page from FoD's
UI. Then by using this token in the header of the request he can list, retrieve,
modify and create rules.
### Example Usage
Here are some examples:
#### GET items
- List all the rules your user has created (admin users can see all the rules)
curl -X GET https://fod.example.com/api/routes/ -H 'Authorization: Token <Your users token>'
- Retrieve a specific rule:
curl -X GET https:/fod.example.com/api/routes/<rule_id>/ -H 'Authorization: Token <Your users token>'
- In order to create or modify a rule you have to use POST/PUT methods.
#### POST/PUT items
##### Foreign Keys
In order to create/modify a rule you have to connect the rule with:
###### Ports, Fragmentypes, protocols, thenactions
When creating a rule, one can specify:
- source port
- destination port
- port (if source = destination)
That can be done by getting the url of the desired port instance from `/api/ports/<port_id>/`
Same with Fragmentypes in `/api/fragmenttypes/<fragmenttype_id>/`, protocols in `/api/matchprotocol/<protocol_id>/` and then actions in `/api/thenactions/<action_id>/`.
Since we have the urls we want to connect with the rule we want to create, we can make a POST request like the following:
curl -X POST -H 'Authorization: Token <Your users token>' -F "name=Example" -F "comments=Description" -F "source=0.0.0.0/0" -F "sourceport=https://fod.example.com/api/ports/7/" -F "destination=203.0.113.12" https://fod.example.com/api/routes/
##Contact##
You can find more about FoD or raise your issues at GRNET FoD
......
......@@ -175,6 +175,12 @@ class Route(models.Model):
comments = models.TextField(null=True, blank=True, verbose_name=_("Comments"))
requesters_address = models.CharField(max_length=255, blank=True, null=True)
@property
def applier_username(self):
if self.applier:
return self.applier.username
else:
return None
def __unicode__(self):
return self.name
......
from rest_framework import serializers
from flowspec.models import (
Route,
MatchPort,
ThenAction,
FragmentType,
MatchProtocol
)
# Serializers define the API representation.
class RouteSerializer(serializers.HyperlinkedModelSerializer):
applier = serializers.CharField(source='applier_username', read_only=True)
class Meta:
model = Route
fields = (
'name',
'id',
'comments',
'applier',
'source',
'sourceport',
'destination',
'destinationport',
'port',
'dscp',
'fragmenttype',
'icmpcode',
'packetlength',
'protocol',
'tcpflag',
'then',
'filed',
'last_updated',
'status',
'expires',
'response',
'comments',
'requesters_address'
)
read_only_fields = ('status', 'expires', 'requesters_address', 'response')
class PortSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MatchPort
fields = ('port', )
class ThenActionSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ThenAction
fields = ('action', 'action_value')
class FragmentTypeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = FragmentType
fields = ('fragmenttype', )
class MatchProtocolSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = MatchProtocol
fields = ('protocol', )
from django.shortcuts import get_object_or_404
from rest_framework import status
from rest_framework import viewsets
from flowspec.models import (
Route,
MatchPort,
ThenAction,
FragmentType,
MatchProtocol
)
from flowspec.serializers import (
RouteSerializer,
PortSerializer,
ThenActionSerializer,
FragmentTypeSerializer,
MatchProtocolSerializer,
)
from rest_framework.response import Response
from django.contrib.auth.models import User
class RouteViewSet(viewsets.ModelViewSet):
queryset = Route.objects.all()
serializer_class = RouteSerializer
def get_queryset(self):
if self.request.user.is_anonymous or self.request.user.is_superuser:
return Route.objects.all()
else:
return Route.objects.filter(applier=self.request.user)
def list(self, request):
serializer = RouteSerializer(self.get_queryset(), many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
route = get_object_or_404(self.get_queryset(), pk=pk)
serializer = RouteSerializer(route)
return Response(serializer.data)
def pre_save(self, obj):
if self.request.user.is_anonymous:
obj.applier = User.objects.all()[0]
else:
obj.applier = self.request.user
class PortViewSet(viewsets.ModelViewSet):
queryset = MatchPort.objects.all()
serializer_class = PortSerializer
class ThenActionViewSet(viewsets.ModelViewSet):
queryset = ThenAction.objects.all()
serializer_class = ThenActionSerializer
class FragmentTypeViewSet(viewsets.ModelViewSet):
queryset = FragmentType.objects.all()
serializer_class = FragmentTypeSerializer
class MatchProtocolViewSet(viewsets.ModelViewSet):
queryset = MatchProtocol.objects.all()
serializer_class = MatchProtocolSerializer
......@@ -316,3 +316,19 @@ BRANDING = {
'logo': 'fodlogo2.png',
'favicon': 'favicon.ico',
}
# Django Rest Framework configuration.
# You should leave this intact.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissions',
'rest_framework.permissions.IsAuthenticated'
]
}
{% load url from future %}
{% load rest_framework %}
{% load staticfiles %}
<html>
<head>
{% block style %}
{% block bootstrap_theme %}
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap.min.css" %}"/>
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/bootstrap-tweaks.css" %}"/>
{% endblock %}
<link rel="stylesheet" type="text/css" href="{% static "rest_framework/css/default.css" %}"/>
{% endblock %}
</head>
<body class="container">
<div class="container-fluid" style="margin-top: 30px">
<div class="row-fluid">
<div class="well" style="width: 320px; margin-left: auto; margin-right: auto">
<div class="row-fluid">
<div>
{% block branding %}<h3 style="margin: 0 0 20px;">Django REST framework</h3>{% endblock %}
</div>
</div><!-- /row fluid -->
<div class="row-fluid">
<div>
<form action="{% url 'rest_framework:login' %}" class=" form-inline" method="post">
{% csrf_token %}
<div id="div_id_username" class="clearfix control-group">
<div class="controls">
<Label class="span4">Username:</label>
<input style="height: 25px" type="text" name="username" maxlength="100" autocapitalize="off" autocorrect="off" class="textinput textInput" id="id_username">
</div>
</div>
<div id="div_id_password" class="clearfix control-group">
<div class="controls">
<Label class="span4">Password:</label>
<input style="height: 25px" type="password" name="password" maxlength="100" autocapitalize="off" autocorrect="off" class="textinput textInput" id="id_password">
</div>
</div>
<input type="hidden" name="next" value="{{ next }}" />
<div class="form-actions-no-box">
<input type="submit" name="submit" value="Log in" class="btn btn-primary" id="submit-id-submit">
</div>
</form>
</div>
</div><!-- /.row-fluid -->
</div><!--/.well-->
</div><!-- /.row-fluid -->
</div><!-- /.container-fluid -->
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment