File cobbler_csrf_fix.diff of Package cobbler.openSUSE_12.1_Update

diff --git a/web/settings.py b/web/settings.py
index a8db1fd..79794f4 100644
--- a/web/settings.py
+++ b/web/settings.py
@@ -31,8 +31,7 @@ MEDIA_ROOT = ''
 MEDIA_URL = ''
 ADMIN_MEDIA_PREFIX = '/media/'
 
-# FIXME: ???
-SECRET_KEY = 'w&x*74x-b=ycigsdya03699o!9kt4(z4wyx-us9q=--&7clv4='
+SECRET_KEY = ''
 
 # code config
 
@@ -42,6 +41,7 @@ TEMPLATE_LOADERS = (
 )
 MIDDLEWARE_CLASSES = (
     'django.middleware.common.CommonMiddleware',
+    'django.contrib.csrf.middleware.CsrfMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
 )
diff --git a/web/cobbler_web/templates/generic_edit.tmpl b/web/cobbler_web/templates/generic_edit.tmpl
index 49a1530..93f330d 100644
--- a/web/cobbler_web/templates/generic_edit.tmpl
+++ b/web/cobbler_web/templates/generic_edit.tmpl
@@ -404,6 +404,7 @@ $(document).ready(function()
 <h1>{% ifequal editmode 'edit'  %}Editing{% else %}Adding{% endifequal %} a {{ what|capfirst }}{%ifequal editmode 'edit' %}: {{ name }}{% endifequal %}</h1>
 <hr />
 <form method="post" action="/cobbler_web/{{ what }}/save">
+  {% csrf_token %}
   <input type="hidden" name="editmode" value="{{ editmode }}" />
   <input type="hidden" name="subobject" value="{{ subobject }}" />
   <ol>
diff --git a/web/cobbler_web/templates/generic_list.tmpl b/web/cobbler_web/templates/generic_list.tmpl
index 4736255..99a0d5b 100644
--- a/web/cobbler_web/templates/generic_list.tmpl
+++ b/web/cobbler_web/templates/generic_list.tmpl
@@ -126,6 +126,7 @@ function action_multi(otype) {
 </ul>
 
 <form name="myform" method="post" action="/cobbler_web/{{ what }}/action">
+  {% csrf_token %}
   <table id="listitems" cellspacing="0">
     <thead>
       <tr>
diff --git a/web/cobbler_web/templates/import.tmpl b/web/cobbler_web/templates/import.tmpl
index da59d8d..4e1298b 100644
--- a/web/cobbler_web/templates/import.tmpl
+++ b/web/cobbler_web/templates/import.tmpl
@@ -3,6 +3,7 @@
 <h1>DVD Importer</h1>
 <hr />
 <form method="post" action="/cobbler_web/import/run">
+  {% csrf_token %}
   <div class="sectionbody">
   <ul>
     <li class="editrow">
diff --git a/web/cobbler_web/templates/ksfile_edit.tmpl b/web/cobbler_web/templates/ksfile_edit.tmpl
index 40393dc..63cd3d8 100644
--- a/web/cobbler_web/templates/ksfile_edit.tmpl
+++ b/web/cobbler_web/templates/ksfile_edit.tmpl
@@ -17,6 +17,7 @@
 <h1>{% ifequal editmode 'edit' %}Editing{% else %}Adding{% endifequal %} a Kickstart Template</h1>
 <hr />
 <form id="ksform" method="post" action="/cobbler_web/ksfile/save">
+  {% csrf_token %}
   <ol>
     <li>
       <label for="ksdata">{% if ksfile_name %}Editing: {{ ksfile_name }}{% else %}Filename:{% endif %}</label>
diff --git a/web/cobbler_web/templates/login.tmpl b/web/cobbler_web/templates/login.tmpl
index 0475957..3872d49 100644
--- a/web/cobbler_web/templates/login.tmpl
+++ b/web/cobbler_web/templates/login.tmpl
@@ -12,6 +12,7 @@
     <p class="error">Sorry, that's not a valid username or password</p>
 {% endif %}
     <form action="/cobbler_web/do_login" method="post">
+      {% csrf_token %}
       {% if next %}<input type="hidden" name="next" value="{{ next|escape }}" />{% endif %}
       <div id="username">
         <label for="username">Username: </label>
diff --git a/web/cobbler_web/templates/snippet_edit.tmpl b/web/cobbler_web/templates/snippet_edit.tmpl
index 7f8a7d6..9e36948 100644
--- a/web/cobbler_web/templates/snippet_edit.tmpl
+++ b/web/cobbler_web/templates/snippet_edit.tmpl
@@ -14,6 +14,7 @@ if you need to resolve this.
 <h1>{% ifequal editmode 'edit' %}Editing{% else %}Adding{% endifequal %} a Snippet</h1>
 <hr />
 <form id="snippetform" method="post" action="/cobbler_web/snippet/save">
+  {% csrf_token %}
   <ol>
     <li>
       <label for="snippetdata">{% if snippet_name %}Snippet: {{ snippet_name }}{% else %}Filename:{% endif %}</label>
diff --git a/web/cobbler_web/views.py b/web/cobbler_web/views.py
index 43bc070..01e1230 100644
--- a/web/cobbler_web/views.py
+++ b/web/cobbler_web/views.py
@@ -5,6 +5,25 @@ from django.http import HttpResponse
 from django.http import HttpResponseRedirect
 from django.shortcuts import render_to_response
 
+try:
+    from django.views.decorators.csrf import csrf_protect
+except:
+    # Old Django, fudge the @csrf_protect decorator to be a pass-through 
+    # that does nothing. Django decorator shell based on this page: 
+    # http://passingcuriosity.com/2009/writing-view-decorators-for-django/
+    def csrf_protect(f):
+        def _dec(view_func):
+            def _view(request,*args,**kwargs):
+                return view_func(request,*args,**kwargs)
+            _view.__name__ = view_func.__name__
+            _view.__dict__ = view_func.__dict__
+            _view.__doc__  = view_func.__doc__
+            return _view
+        if f is None:
+            return _dec
+        else:
+            return _dec(f)
+
 import xmlrpclib
 import time
 import simplejson
@@ -37,7 +56,7 @@ def index(request):
    if not test_user_authenticated(request): return login(request,next="/cobbler_web")
 
    t = get_template('index.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
         'version' : remote.version(request.session['token']),
         'username': username,
    }))
@@ -51,7 +70,7 @@ def task_created(request):
    """
    if not test_user_authenticated(request): return login(request, next="/cobbler_web/task_created")
    t = get_template("task_created.tmpl")
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'version'  : remote.version(request.session['token']),
        'username' : username
    }))
@@ -69,7 +88,7 @@ def error_page(request,message):
    t = get_template('error_page.tmpl')
    message = message.replace("<Fault 1: \"<class 'cobbler.cexceptions.CX'>:'","Remote exception: ")
    message = message.replace("'\">","")
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'version' : remote.version(request.session['token']),
        'message' : message,
        'username': username
@@ -545,7 +564,7 @@ def generic_domulti(request, what, multi_mode=None, multi_arg=None):
 def import_prompt(request):
    if not test_user_authenticated(request): return login(request, next="/cobbler_web/import/prompt")
    t = get_template('import.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'version'  : remote.version(request.session['token']),
        'username' : username,
    }))
@@ -560,7 +579,7 @@ def check(request):
    if not test_user_authenticated(request): return login(request, next="/cobbler_web/check")
    results = remote.check(request.session['token'])
    t = get_template('check.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'version': remote.version(request.session['token']),
        'username' : username,
        'results'  : results
@@ -606,7 +625,7 @@ def ksfile_list(request, page=None):
          ksfile_list.append((ksfile,ksfile,None))
 
    t = get_template('ksfile_list.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'what':'ksfile',
        'ksfiles': ksfile_list,
        'version': remote.version(request.session['token']),
@@ -617,7 +636,7 @@ def ksfile_list(request, page=None):
 
 # ======================================================================
 
-
+@csrf_protect
 def ksfile_edit(request, ksfile_name=None, editmode='edit'):
    """
    This is the page where a kickstart file is edited.
@@ -635,7 +654,7 @@ def ksfile_edit(request, ksfile_name=None, editmode='edit'):
       ksdata = remote.read_or_write_kickstart_template(ksfile_name, True, "", request.session['token'])
 
    t = get_template('ksfile_edit.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'ksfile_name' : ksfile_name,
        'deleteable'  : deleteable,
        'ksdata'      : ksdata,
@@ -648,6 +667,7 @@ def ksfile_edit(request, ksfile_name=None, editmode='edit'):
 
 # ======================================================================
 
+@csrf_protect
 def ksfile_save(request):
    """
    This page processes and saves edits to a kickstart file.
@@ -691,7 +711,7 @@ def snippet_list(request, page=None):
          snippet_list.append((snippet,snippet,None))
 
    t = get_template('snippet_list.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'what'     : 'snippet',
        'snippets' : snippet_list,
        'version'  : remote.version(request.session['token']),
@@ -701,6 +721,7 @@ def snippet_list(request, page=None):
 
 # ======================================================================
 
+@csrf_protect
 def snippet_edit(request, snippet_name=None, editmode='edit'):
    """
    This page edits a specific snippet.
@@ -718,7 +739,7 @@ def snippet_edit(request, snippet_name=None, editmode='edit'):
       snippetdata = remote.read_or_write_snippet(snippet_name, True, "", request.session['token'])
 
    t = get_template('snippet_edit.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'snippet_name' : snippet_name,
        'deleteable'   : deleteable,
        'snippetdata'  : snippetdata,
@@ -731,6 +752,7 @@ def snippet_edit(request, snippet_name=None, editmode='edit'):
 
 # ======================================================================
 
+@csrf_protect
 def snippet_save(request):
    """
    This snippet saves a snippet once edited.
@@ -774,7 +796,7 @@ def settings(request):
       results.append([k,settings[k]])
 
    t = get_template('settings.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
         'settings' : results,
         'version'  : remote.version(request.session['token']),
         'username' : username,
@@ -800,7 +822,7 @@ def events(request):
    events2.sort(sorter)
 
    t = get_template('events.tmpl')
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'results'  : events2,
        'version'  : remote.version(request.session['token']),
        'username' : username
@@ -834,7 +856,7 @@ def eventlog(request, event=0):
       'version'    : remote.version(request.session['token']),
       'username'  : username
    }
-   html = t.render(Context(vars))
+   html = t.render(RequestContext(request,vars))
    return HttpResponse(html)
 
 # ======================================================================
@@ -912,6 +934,7 @@ def __names_from_dicts(loh,optional=True):
 
 # ======================================================================
 
+@csrf_protect
 def generic_edit(request, what=None, obj_name=None, editmode="new"):
 
    """
@@ -980,7 +1003,7 @@ def generic_edit(request, what=None, obj_name=None, editmode="new"):
    t = get_template('generic_edit.tmpl')
    inames = interfaces.keys()
    inames.sort()
-   html = t.render(Context({
+   html = t.render(RequestContext(request,{
        'what'            : what, 
        'fields'          : fields, 
        'subobject'       : child,
@@ -998,6 +1021,7 @@ def generic_edit(request, what=None, obj_name=None, editmode="new"):
 
 # ======================================================================
 
+@csrf_protect
 def generic_save(request,what):
 
     """
@@ -1146,9 +1170,11 @@ def test_user_authenticated(request):
             pass
     return False
 
+@csrf_protect
 def login(request, next=None):
-    return render_to_response('login.tmpl', {'next':next})
+    return render_to_response('login.tmpl', RequestContext(request,{'next':next}))
 
+@csrf_protect
 def do_login(request):
     global remote
     global username
@@ -1178,6 +1204,7 @@ def do_login(request):
     else:
         return login(request,nextsite)
 
+@csrf_protect
 def do_logout(request):
     request.session['username'] = ""
     request.session['token'] = ""
diff --git a/web/settings.py b/web/settings.py
index 79794f4..3541c8e 100644
--- a/web/settings.py
+++ b/web/settings.py
@@ -1,4 +1,5 @@
 # Django settings for cobbler-web project.
+import django
 
 DEBUG = True
 TEMPLATE_DEBUG = DEBUG
@@ -39,12 +40,25 @@ TEMPLATE_LOADERS = (
     'django.template.loaders.filesystem.load_template_source',
     'django.template.loaders.app_directories.load_template_source',
 )
-MIDDLEWARE_CLASSES = (
-    'django.middleware.common.CommonMiddleware',
-    'django.contrib.csrf.middleware.CsrfMiddleware',
-    'django.contrib.sessions.middleware.SessionMiddleware',
-    'django.contrib.auth.middleware.AuthenticationMiddleware',
-)
+
+if django.VERSION[0] == 1 and django.VERSION[1] < 2:
+    # Legacy django had a different CSRF method, which also had 
+    # different middleware. We check the vesion here so we bring in 
+    # the correct one.
+    MIDDLEWARE_CLASSES = (
+        'django.middleware.common.CommonMiddleware',
+        'django.contrib.csrf.middleware.CsrfMiddleware',
+        'django.contrib.sessions.middleware.SessionMiddleware',
+        'django.contrib.auth.middleware.AuthenticationMiddleware',
+    )
+else:
+    MIDDLEWARE_CLASSES = (
+        'django.middleware.common.CommonMiddleware',
+        'django.middleware.csrf.CsrfViewMiddleware',
+        'django.contrib.sessions.middleware.SessionMiddleware',
+        'django.contrib.auth.middleware.AuthenticationMiddleware',
+    )
+
 ROOT_URLCONF = 'urls'
 
 TEMPLATE_DIRS = (
commit 18eb1c06779b37d89dfb2962a08236dd1bab24a6
Author: James Cammarata <jimi@sngx.net>
Date:   Fri Nov 4 02:33:38 2011 -0500

    Additional CSRF work. All URLs that modify state are now required to be POSTs only.

diff --git a/web/cobbler_web/templates/filter.tmpl b/web/cobbler_web/templates/filter.tmpl
index 9e9c9dc..76a230e 100644
--- a/web/cobbler_web/templates/filter.tmpl
+++ b/web/cobbler_web/templates/filter.tmpl
@@ -1,5 +1,6 @@
 {% if pageinfo %}
 <script type="text/javascript">
+// these functions depend on the "action" form defined in generic_list
 function add_filter() {
     field_name = document.getElementById("filter_field");
     field_value = document.getElementById("filter_value");
@@ -8,9 +9,14 @@ function add_filter() {
     } else if (field_value.value == "") {
         alert("You must select a filter value.");
     } else {
-        location = '/cobbler_web/{{ what }}/modifylist/addfilter/'+field_name.value+':'+field_value.value;
+        document.forms["action"].action = '/cobbler_web/{{ what }}/modifylist/addfilter/'+field_name.value+':'+field_value.value;
+        document.forms["action"].submit();
     }
 }
+function del_filter(filter) {
+    document.forms["action"].action = '/cobbler_web/{{ what }}/modifylist/removefilter/' + filter
+    document.forms["action"].submit();
+}
 </script>
 <ul id="filter-adder">
   <li>
@@ -151,7 +157,7 @@ function add_filter() {
   {% if filters %}
 <ul id="filter-remover">
     {% for key,value in filters.items %}
-  <li><a href="/cobbler_web/{{ what }}/modifylist/removefilter/{{ key }}" title="remove">✖</a> {{ key }} = {{ value }}</li>
+  <li><a href="javascript:del_filter('{{ key }}');" title="remove">✖</a> {{ key }} = {{ value }}</li>
     {% endfor %}
 </ul>
   {% endif %}
diff --git a/web/cobbler_web/templates/generic_list.tmpl b/web/cobbler_web/templates/generic_list.tmpl
index 99a0d5b..7f40afc 100644
--- a/web/cobbler_web/templates/generic_list.tmpl
+++ b/web/cobbler_web/templates/generic_list.tmpl
@@ -2,6 +2,7 @@
 {% load site %}
 {% block content %}
 
+<form id="action" method="POST" action="">{% csrf_token %}</form>
 <script type="text/javascript">
 function items_check_all(){
     var checkall = document.getElementById("itemsall").checked
@@ -31,18 +32,21 @@ function items_checked_values() {
 function obj_rename(old) {
     var newname = window.prompt("Change {{ what }} name to?",old);
     if (newname != null) {
-        window.location = "/cobbler_web/{{ what }}/rename/" + old + "/" + newname;
+        document.forms["action"].action = "/cobbler_web/{{ what }}/rename/" + old + "/" + newname;
+        document.forms["action"].submit();
     }
 }
 function obj_copy(old) {
     var newname = window.prompt("Name for the new {{ what }}?",old);
     if (newname != null) {
-        window.location = "/cobbler_web/{{ what }}/copy/" + old + "/" + newname;
+        document.forms["action"].action = "/cobbler_web/{{ what }}/copy/" + old + "/" + newname;
+        document.forms["action"].submit();
     }
 }
 function obj_delete(old) {
     if (confirm("Delete {{ what }} (" + old + ") and all child objects?")) {
-        window.location = "/cobbler_web/{{ what }}/delete/" + old;
+        document.forms["action"].action = "/cobbler_web/{{ what }}/delete/" + old;
+        document.forms["action"].submit();
     }
 }
 
@@ -53,6 +57,11 @@ function action(otype) {
     document.location = "/cobbler_web/" + what + "/" + action
 }
 
+function action_sort(value) {
+    document.forms["action"].action = '/cobbler_web/{{ what }}/modifylist/sort/' + value;
+    document.forms["action"].submit();
+}
+
 function action_multi(otype) {
     var values = items_checked_values()
     if (values == "") {
@@ -135,7 +144,7 @@ function action_multi(otype) {
         </th>
 {% for value in columns %}
         <th>
-          <a href="/cobbler_web/{{ what }}/modifylist/sort/{{ value.0 }}">{{ value.0|title }}</a>
+          <a href="javascript:action_sort('{{ value.0 }}');">{{ value.0|title }}</a>
   {% ifequal value.1 "asc" %}
           &darr;
   {% endifequal %}
diff --git a/web/cobbler_web/templates/master.tmpl b/web/cobbler_web/templates/master.tmpl
index c83ecf2..44ecb98 100644
--- a/web/cobbler_web/templates/master.tmpl
+++ b/web/cobbler_web/templates/master.tmpl
@@ -14,9 +14,16 @@
 <div id="container">
   <div id='user'>
     <input type="hidden" name="username" id="username" value="{{ username }}" />
-    Logged in: <b>{{ username }}</b> <a class="action" href="/cobbler_web/logout">Logout</a>
+    Logged in: <b>{{ username }}</b> <a class="action" href="javascript:menuaction('/cobbler_web/logout');">Logout</a>
   </div>
     <div id="menubar">
+      <form id="menuaction" method="POST" action="">{% csrf_token %}</form>
+      <script type="text/javascript">
+      function menuaction(action) {
+         document.forms["menuaction"].action = action
+         document.forms["menuaction"].submit();
+      }
+      </script>
       <h1>Configuration</h1>
       <ul>
         <li><a href="/cobbler_web/distro/list" class="edit">Distros</a></li>
@@ -36,11 +43,11 @@
       <h1>Actions</h1>
       <ul>
         <li><a href="/cobbler_web/import/prompt">Import DVD</a></li>
-        <li><a href="/cobbler_web/sync">Sync</a> ☼</li>
-        <li><a href="/cobbler_web/reposync">Reposync</a> ☼ </li>
-        <li><a href="/cobbler_web/hardlink">Hardlink</a> ☼ </li>
-        <!-- <li><a href="/cobbler_web/replicate">Replicate</a> ☼ </li> -->
-        <li><a href="/cobbler_web/buildiso">Build ISO</a> ☼ </li>
+        <li><a href="javascript:menuaction('/cobbler_web/sync');">Sync</a> ☼</li>
+        <li><a href="javascript:menuaction('/cobbler_web/reposync');"">Reposync</a> ☼ </li>
+        <li><a href="javascript:menuaction('/cobbler_web/hardlink');"">Hardlink</a> ☼ </li>
+        <!-- <li><a href="javascript:menuaction('/cobbler_web/replicate');"">Replicate</a> ☼ </li> -->
+        <li><a href="javascript:menuaction('/cobbler_web/buildiso');">Build ISO</a> ☼ </li>
       </ul>
       <h1>Cobbler</h1>
       <ul>
diff --git a/web/cobbler_web/templates/paginate.tmpl b/web/cobbler_web/templates/paginate.tmpl
index b8d1870..79d198c 100644
--- a/web/cobbler_web/templates/paginate.tmpl
+++ b/web/cobbler_web/templates/paginate.tmpl
@@ -1,20 +1,32 @@
 {% if pageinfo %}
+<script type="text/javascript">
+// All of these functions depend on the form "action" defined in generic_list
+function change_limit(value) {
+    document.forms["action"].action = '/cobbler_web/{{ what }}/modifylist/limit/' + value
+    document.forms["action"].submit();
+}
+function change_page(value) {
+    document.forms["action"].action = '/cobbler_web/{{ what }}/modifylist/page/' + value
+    document.forms["action"].submit();
+}
+</script>
+
 <li class="paginate"><label for="limit">Items/page:</label>
-  <select name="limit" id="limit" onchange="javascript:location='/cobbler_web/{{ what }}/modifylist/limit/'+this.value">
+  <select name="limit" id="limit" onchange="javascript:change_limit(this.value)">
   {% for p in pageinfo.items_per_page_list %}
     <option value="{{ p }}"{% ifequal pageinfo.items_per_page p %} selected="selected"{% endifequal %}>{{ p }}</option>
   {% endfor %}
   </select>
   {% ifnotequal pageinfo.prev_page "~" %}
-  <a href="/cobbler_web/{{ what }}/modifylist/page/{{ pageinfo.prev_page }}"><span class="lpointers">&lArr;</span></a>
+  <a href="javascript:change_page('{{ pageinfo.prev_page }}')"><span class="lpointers">&lArr;</span></a>
   {% else %}
   <span class="lpointers">&lArr;</span>
   {% endifnotequal %}
-  <select name="page" id="page" onchange="javascript:location='/cobbler_web/{{ what }}/modifylist/page/'+this.value">
+  <select name="page" id="page" onchange="javascript:change_page(this.value)">
     {% for p in pageinfo.pages %}<option value="{{ p }}"{% ifequal pageinfo.page p %} selected="selected"{% endifequal %}>Page {{ p }}</option>{% endfor %}
   </select>
   {% ifnotequal pageinfo.next_page "~" %}
-  <a href="/cobbler_web/{{ what }}/modifylist/page/{{ pageinfo.next_page }}"><span class="rpointers">&rArr;</span></a>
+  <a href="javascript:change_page('{{ pageinfo.next_page }}')"><span class="rpointers">&rArr;</span></a>
   {% else %}
   <span class="rpointers">&rArr;</span>
   {% endifnotequal %}
diff --git a/web/cobbler_web/views.py b/web/cobbler_web/views.py
index d2f3efe..00abb6a 100644
--- a/web/cobbler_web/views.py
+++ b/web/cobbler_web/views.py
@@ -4,6 +4,7 @@ from django.template import RequestContext
 from django.http import HttpResponse
 from django.http import HttpResponseRedirect
 from django.shortcuts import render_to_response
+from django.views.decorators.http import require_POST
 
 try:
     from django.views.decorators.csrf import csrf_protect
@@ -366,7 +367,8 @@ def genlist(request, what, page=None):
     }))
     return HttpResponse(html)
 
-
+@require_POST
+@csrf_protect
 def modify_list(request, what, pref, value=None):
     """
     This function is used in the generic list view
@@ -433,6 +435,8 @@ def modify_list(request, what, pref, value=None):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def generic_rename(request, what, obj_name=None, obj_newname=None):
 
    """
@@ -453,6 +457,8 @@ def generic_rename(request, what, obj_name=None, obj_newname=None):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def generic_copy(request, what, obj_name=None, obj_newname=None):
    """
    Copies an object.
@@ -472,6 +478,8 @@ def generic_copy(request, what, obj_name=None, obj_newname=None):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def generic_delete(request, what, obj_name=None):
    """
    Deletes an object.
@@ -491,6 +499,8 @@ def generic_delete(request, what, obj_name=None):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def generic_domulti(request, what, multi_mode=None, multi_arg=None):
 
     """
@@ -588,6 +598,8 @@ def check(request):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def buildiso(request):
     if not test_user_authenticated(request): return login(request, next="/cobbler_web/buildiso")
     remote.background_buildiso({},request.session['token'])
@@ -595,6 +607,8 @@ def buildiso(request):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def import_run(request):
     if not test_user_authenticated(request): return login(request, next="/cobbler_web/import/prompt")
     options = {
@@ -667,6 +681,7 @@ def ksfile_edit(request, ksfile_name=None, editmode='edit'):
 
 # ======================================================================
 
+@require_POST
 @csrf_protect
 def ksfile_save(request):
    """
@@ -752,6 +767,7 @@ def snippet_edit(request, snippet_name=None, editmode='edit'):
 
 # ======================================================================
 
+@require_POST
 @csrf_protect
 def snippet_save(request):
    """
@@ -872,6 +888,8 @@ def random_mac(request, virttype="xenpv"):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def sync(request):
    """
    Runs 'cobbler sync' from the API when the user presses the sync button.
@@ -882,6 +900,8 @@ def sync(request):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def reposync(request):
    """
    Syncs all repos that are configured to be synced.
@@ -892,6 +912,8 @@ def reposync(request):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def hardlink(request):
    """
    Hardlinks files between repos and install trees to save space.
@@ -902,6 +924,8 @@ def hardlink(request):
 
 # ======================================================================
 
+@require_POST
+@csrf_protect
 def replicate(request):
    """
    Replicate configuration from the central cobbler server, configured
@@ -1022,6 +1046,7 @@ def generic_edit(request, what=None, obj_name=None, editmode="new"):
 
 # ======================================================================
 
+@require_POST
 @csrf_protect
 def generic_save(request,what):
 
@@ -1175,6 +1200,7 @@ def test_user_authenticated(request):
 def login(request, next=None):
     return render_to_response('login.tmpl', RequestContext(request,{'next':next}))
 
+@require_POST
 @csrf_protect
 def do_login(request):
     global remote
@@ -1205,6 +1231,7 @@ def do_login(request):
     else:
         return login(request,nextsite)
 
+@require_POST
 @csrf_protect
 def do_logout(request):
     request.session['username'] = ""
openSUSE Build Service is sponsored by