diff --git a/beat/web/algorithms/templates/algorithms/diff.html b/beat/web/algorithms/templates/algorithms/diff.html
index cee54a2d1b31e9cedd5fafe54a0e1010d276c656..9234c6923ef3865c44afb4bcf7e92b684ec12670 100644
--- a/beat/web/algorithms/templates/algorithms/diff.html
+++ b/beat/web/algorithms/templates/algorithms/diff.html
@@ -2,21 +2,21 @@
 {% comment %}
  * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
  * Contact: beat.support@idiap.ch
- * 
+ *
  * This file is part of the beat.web module of the BEAT platform.
- * 
+ *
  * Commercial License Usage
  * Licensees holding valid commercial BEAT licenses may use this file in
  * accordance with the terms contained in a written agreement between you
  * and Idiap. For further information contact tto@idiap.ch
- * 
+ *
  * Alternatively, this file may be used under the terms of the GNU Affero
  * Public License version 3 as published by the Free Software and appearing
  * in the file LICENSE.AGPL included in the packaging of this file.
  * The BEAT platform is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.
- * 
+ *
  * You should have received a copy of the GNU Affero Public License along
  * with the BEAT platform. If not, see http://www.gnu.org/licenses/.
 {% endcomment %}
@@ -129,13 +129,6 @@ function process_diff(lines, editor, diff_line_numbers_classname)
   </div>
 </div>
 
-<div id="errors" class="row" style="display:none">
-  <div class="col-sm-offset-1 col-sm-10">
-    <h2></h2>
-    <p></p>
-  </div>
-</div>
-
 <script type="text/javascript">
 
 jQuery(document).ready(function() {
@@ -143,79 +136,58 @@ jQuery(document).ready(function() {
   $('h4').hide();
   $('#progress').show();
 
-  $.get('{% url 'api_algorithms:diff' algorithm1_author algorithm1_name algorithm1_version algorithm2_author algorithm2_name algorithm2_version %}')
-    .done(function(data) {
-
-      $('#progress').hide();
-      $('h4').show();
-
-      var source_code_lines = data.source_code_diff.split('\n')
-
-        var code = '';
-      for (var i = 0; i < source_code_lines.length; ++i)
-        code += source_code_lines[i].substr(2) + '\n';
-
-      var declaration_lines = data.diff.split('\n')
-
-        var declaration = '';
-      for (var i = 0; i < declaration_lines.length; ++i)
-        declaration += declaration_lines[i].substr(2) + '\n';
-
-      var diff_line_numbers_classname = (Math.log10(Math.max(source_code_lines.length, declaration_lines.length)) > 3 ?
-          'diff_line_numbers_large' :
-          'diff_line_numbers');
-
-      var code_editor = CodeMirror($('#code_editor_container')[0],
-          {
-            value:       code,
-            mode:        'python',
-            readOnly:    true,
-            lineNumbers: false,
-            gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
-          }
-          );
-
-      var declaration_editor = CodeMirror($('#declaration_container')[0],
-          {
-            value:       declaration,
-            mode:        'javascript',
-            readOnly:    true,
-            lineNumbers: false,
-            gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
-          }
-          );
-
-      process_diff(source_code_lines, code_editor, diff_line_numbers_classname);
-      process_diff(declaration_lines, declaration_editor, diff_line_numbers_classname);
-    })
-  .fail(function(jqXHR, textStatus, errorThrown) {
-    $('#title').hide();
-
-    var errors_box = $('.container #errors');
-
-    if (jqXHR.status == 404)
-    {
-      errors_box.find('h2').text('Algorithm not found');
-      errors_box.find('p').html("We are sorry, but the algorithm called <strong>" +
-          jqXHR.responseText + "</strong> could not be found.");
-    }
-    else if (jqXHR.status == 401)
-    {
-      errors_box.find('h2').text('Unauthorized access');
-      errors_box.find('p').html("We are sorry, but your aren't authorized to access the algorithm called <strong>" +
-          jqXHR.responseText + "</strong>.");
-    }
-    else if (jqXHR.responseText.length > 0)
-    {
-      errors_box.find('h2').text(textStatus);
-      errors_box.find('p').html(jqXHR.responseText);
+  var d = $.get('{% url 'api_algorithms:diff' algorithm1_author algorithm1_name algorithm1_version algorithm2_author algorithm2_name algorithm2_version %}');
+
+  d.done(function(data) {
+
+    $('#progress').hide();
+    $('h4').show();
+
+    var source_code_lines = data.source_code_diff.split('\n');
+
+    var code = '';
+    for (var i = 0; i < source_code_lines.length; ++i) {
+      code += source_code_lines[i].substr(2) + '\n';
     }
-    else
-    {
-      errors_box.find('h2').text(textStatus);
+
+    var declaration_lines = data.diff.split('\n');
+    var declaration = '';
+
+    for (var i = 0; i < declaration_lines.length; ++i) {
+      declaration += declaration_lines[i].substr(2) + '\n';
     }
 
-    errors_box.show();
+    var diff_line_numbers_classname = (Math.log10(Math.max(source_code_lines.length, declaration_lines.length)) > 3 ?
+        'diff_line_numbers_large' :
+        'diff_line_numbers');
+
+    var code_editor = CodeMirror($('#code_editor_container')[0],
+        {
+          value:       code,
+          mode:        'python',
+          readOnly:    true,
+          lineNumbers: false,
+          gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
+        }
+        );
+
+    var declaration_editor = CodeMirror($('#declaration_container')[0],
+        {
+          value:       declaration,
+          mode:        'javascript',
+          readOnly:    true,
+          lineNumbers: false,
+          gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
+        }
+        );
+
+    process_diff(source_code_lines, code_editor, diff_line_numbers_classname);
+    process_diff(declaration_lines, declaration_editor, diff_line_numbers_classname);
+  });
+
+  d.fail(function (data, status_text) {
+    $('#progress').hide();
+    process_error(data, status_text, document.referrer);
   });
 });
 
diff --git a/beat/web/code/api.py b/beat/web/code/api.py
index 1a0fdd037e3280be4df23274d117e0c84ce9a2e8..7046ce6d46c355cdf8724079ad5c8836d07a69a4 100644
--- a/beat/web/code/api.py
+++ b/beat/web/code/api.py
@@ -58,7 +58,6 @@ class ShareCodeView(ShareView):
 
 class DiffView(generics.RetrieveAPIView):
     model = Code
-    permission_classes = [permissions.IsAuthenticated]
     serializer_class = DiffSerializer
 
     def get(self, request, author1, name1, version1, author2, name2, version2):
@@ -79,13 +78,15 @@ class DiffView(generics.RetrieveAPIView):
 
 
         # Check that the user can access them
-        accessibility = object1.accessibility_for(request.user)
-        if not accessibility[1]:
-            return ForbiddenResponse(object1.fullname())
-
-        accessibility = object2.accessibility_for(request.user)
-        if not accessibility[1]:
-            return ForbiddenResponse(object2.fullname())
+        has_access, open_source, _ = object1.accessibility_for(request.user)
+        if not ((request.user == object1.author) or \
+            (has_access and open_source)):
+            return ForbiddenResponse("You cannot access the source-code of \"%s\"" % object1.fullname())
+
+        has_access, open_source, _ = object2.accessibility_for(request.user)
+        if not ((request.user == object2.author) or \
+            (has_access and open_source)):
+            return ForbiddenResponse("You cannot access the source-code of \"%s\"" % object2.fullname())
 
         # Compute the diff
         serializer = self.get_serializer({'object1': object1,
diff --git a/beat/web/common/api.py b/beat/web/common/api.py
index 8ae0a0f0f5af708cf0678a32bd55ade654872407..bc5cad89aa3a59e57af4bb78ab0dc458e88d39e1 100644
--- a/beat/web/common/api.py
+++ b/beat/web/common/api.py
@@ -178,7 +178,6 @@ class ListCreateContributionView(IsAuthorOrReadOnlyMixin, ListCreateBaseView):
 
 class DiffView(generics.RetrieveAPIView):
     model = Versionable
-    permission_classes = [permissions.IsAuthenticated]
     serializer_class = DiffSerializer
 
     def get(self, request, author1, name1, version1, author2, name2, version2):
diff --git a/beat/web/libraries/templates/libraries/diff.html b/beat/web/libraries/templates/libraries/diff.html
index c99165a7dad9ca3e4f5d4eeba9c36318b884edce..b3ef4196d45acb9b1ec6afea08aa101712d8dbc3 100644
--- a/beat/web/libraries/templates/libraries/diff.html
+++ b/beat/web/libraries/templates/libraries/diff.html
@@ -2,21 +2,21 @@
 {% comment %}
  * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
  * Contact: beat.support@idiap.ch
- * 
+ *
  * This file is part of the beat.web module of the BEAT platform.
- * 
+ *
  * Commercial License Usage
  * Licensees holding valid commercial BEAT licenses may use this file in
  * accordance with the terms contained in a written agreement between you
  * and Idiap. For further information contact tto@idiap.ch
- * 
+ *
  * Alternatively, this file may be used under the terms of the GNU Affero
  * Public License version 3 as published by the Free Software and appearing
  * in the file LICENSE.AGPL included in the packaging of this file.
  * The BEAT platform is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.
- * 
+ *
  * You should have received a copy of the GNU Affero Public License along
  * with the BEAT platform. If not, see http://www.gnu.org/licenses/.
 {% endcomment %}
@@ -129,93 +129,61 @@ function process_diff(lines, editor, diff_line_numbers_classname)
   </div>
 </div>
 
-<div id="errors" class="row" style="display:none">
-  <div class="col-sm-offset-1 col-sm-10">
-    <h2></h2>
-    <p></p>
-  </div>
-</div>
-
 <script type="text/javascript">
 jQuery(document).ready(function() {
 
   $('#progress').show();
   $('h4').hide();
 
-  $.get('{% url 'api_libraries:diff' library1_author library1_name library1_version library2_author library2_name library2_version %}')
-    .done(function(data) {
-      $('#progress').hide();
-      $('h4').show();
-
-      var source_code_lines = data.source_code_diff.split('\n')
-
-        var code = '';
-      for (var i = 0; i < source_code_lines.length; ++i)
-        code += source_code_lines[i].substr(2) + '\n';
-
-      var declaration_lines = data.diff.split('\n')
-
-        var declaration = '';
-      for (var i = 0; i < declaration_lines.length; ++i)
-        declaration += declaration_lines[i].substr(2) + '\n';
-
-      var diff_line_numbers_classname = (Math.log10(Math.max(source_code_lines.length, declaration_lines.length)) > 3 ?
-          'diff_line_numbers_large' :
-          'diff_line_numbers');
-
-      var code_editor = CodeMirror($('#code_editor_container')[0],
-          {
-            value:       code,
-            mode:        'python',
-            readOnly:    true,
-            lineNumbers: false,
-            gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
-          }
-          );
-
-      var declaration_editor = CodeMirror($('#declaration_container')[0],
-          {
-            value:       declaration,
-            mode:        'javascript',
-            readOnly:    true,
-            lineNumbers: false,
-            gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
-          }
-          );
-
-      process_diff(source_code_lines, code_editor, diff_line_numbers_classname);
-      process_diff(declaration_lines, declaration_editor, diff_line_numbers_classname);
-    })
-  .fail(function(jqXHR, textStatus, errorThrown) {
+  var d = $.get('{% url 'api_libraries:diff' library1_author library1_name library1_version library2_author library2_name library2_version %}');
+
+  d.done(function(data) {
     $('#progress').hide();
-    $('#title').hide();
+    $('h4').show();
 
-    var errors_box = $('.container #errors');
+    var source_code_lines = data.source_code_diff.split('\n');
 
-    if (jqXHR.status == 404)
-    {
-      errors_box.find('h2').text('Library not found');
-      errors_box.find('p').html("We are sorry, but the library called <strong>" +
-          jqXHR.responseText + "</strong> could not be found.");
-    }
-    else if (jqXHR.status == 401)
-    {
-      errors_box.find('h2').text('Unauthorized access');
-      errors_box.find('p').html("We are sorry, but your aren't authorized to access the library called <strong>" +
-          jqXHR.responseText + "</strong>.");
+    var code = '';
+    for (var i = 0; i < source_code_lines.length; ++i) {
+      code += source_code_lines[i].substr(2) + '\n';
     }
-    else if (jqXHR.responseText.length > 0)
-    {
-      errors_box.find('h2').text(textStatus);
-      errors_box.find('p').html(jqXHR.responseText);
-    }
-    else
-    {
-      errors_box.find('h2').text(textStatus);
+
+    var declaration_lines = data.diff.split('\n');
+
+    var declaration = '';
+    for (var i = 0; i < declaration_lines.length; ++i) {
+      declaration += declaration_lines[i].substr(2) + '\n';
     }
 
-    errors_box.show();
+    var diff_line_numbers_classname = (Math.log10(Math.max(source_code_lines.length, declaration_lines.length)) > 3 ?
+        'diff_line_numbers_large' :
+        'diff_line_numbers');
+
+    var code_editor = CodeMirror($('#code_editor_container')[0],
+        {
+          value:       code,
+          mode:        'python',
+          readOnly:    true,
+          lineNumbers: false,
+          gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
+        }
+        );
+
+    var declaration_editor = CodeMirror($('#declaration_container')[0],
+        {
+          value:       declaration,
+          mode:        'javascript',
+          readOnly:    true,
+          lineNumbers: false,
+          gutters:     [diff_line_numbers_classname, 'diff_addition_deletion'],
+        }
+        );
+
+    process_diff(source_code_lines, code_editor, diff_line_numbers_classname);
+    process_diff(declaration_lines, declaration_editor, diff_line_numbers_classname);
   });
+
+  d.fail(process_error);
 });
 
 </script>
diff --git a/beat/web/ui/static/ui/js/widgets.js b/beat/web/ui/static/ui/js/widgets.js
index 201f670ae9572ff26dce0c7f256e759ec75e512c..0a340e44210ee1eee51fd1ac4889fb8c6658b8d3 100644
--- a/beat/web/ui/static/ui/js/widgets.js
+++ b/beat/web/ui/static/ui/js/widgets.js
@@ -1,21 +1,21 @@
 /*
  * Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/
  * Contact: beat.support@idiap.ch
- * 
+ *
  * This file is part of the beat.web module of the BEAT platform.
- * 
+ *
  * Commercial License Usage
  * Licensees holding valid commercial BEAT licenses may use this file in
  * accordance with the terms contained in a written agreement between you
  * and Idiap. For further information contact tto@idiap.ch
- * 
+ *
  * Alternatively, this file may be used under the terms of the GNU Affero
  * Public License version 3 as published by the Free Software and appearing
  * in the file LICENSE.AGPL included in the packaging of this file.
  * The BEAT platform is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  * or FITNESS FOR A PARTICULAR PURPOSE.
- * 
+ *
  * You should have received a copy of the GNU Affero Public License along
  * with the BEAT platform. If not, see http://www.gnu.org/licenses/.
 */
@@ -131,8 +131,8 @@ function process_error(data, status_text, redirect) {
       type: BootstrapDialog.TYPE_DANGER,
       title: 'Error during submission' + ' - ' + data.statusText + ' (' + data.status + ')',
       message: div,
-      onhidden: function() {
-        if (redirect !== undefined) window.location = redirect;
+      callback: function(result) {
+        if (redirect !== undefined) window.location.href = redirect;
       }
     });
   }
@@ -142,8 +142,8 @@ function process_error(data, status_text, redirect) {
       message: 'An empty response was received by your browser, for a request you sent. This normally indicates it cannot establish a connection with the web service. In the hopes it is a temporary issue, you may re-submit your request again at a later moment. Otherwise, please contact the system administrators.',
       type: BootstrapDialog.TYPE_DANGER,
       title: 'Empty response',
-      onhidden: function() {
-        if (redirect !== undefined) window.location = redirect;
+      callback: function(result) {
+        if (redirect !== undefined) window.location.href = redirect;
       }
     });
   }
@@ -152,8 +152,8 @@ function process_error(data, status_text, redirect) {
       message: data.responseJSON,
       type: BootstrapDialog.TYPE_DANGER,
       title: data.statusText + ' (' + data.status + ')',
-      onhidden: function() {
-        if (redirect !== undefined) window.location = redirect;
+      callback: function(result) {
+        if (redirect !== undefined) window.location.href = redirect;
       }
     });
   }