aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Post/admin.py2
-rw-r--r--Post/createStatistics.py1
-rw-r--r--Post/feed.py4
-rw-r--r--Post/management/commands/culldb.py2
-rw-r--r--Post/migrations/0006_buildfailure_referer.py19
-rw-r--r--Post/models.py14
-rw-r--r--Post/parser.py25
-rw-r--r--Post/purge.py27
-rw-r--r--Post/views.py41
-rw-r--r--README2
-rwxr-xr-xmanage.py2
-rw-r--r--project/settings.py4
-rw-r--r--project/urls.py4
-rw-r--r--project/wsgi.py4
-rw-r--r--requirements.txt1
-rw-r--r--templates/error-details.html2
-rw-r--r--templates/latest-errors.html2
-rwxr-xr-xtest-data/test-send-error.py3
18 files changed, 125 insertions, 34 deletions
diff --git a/Post/admin.py b/Post/admin.py
index f11ff65..43aa9a6 100644
--- a/Post/admin.py
+++ b/Post/admin.py
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MIT
+#
# error reporting tool - admin interface definitions
#
# Copyright (C) 2013 Intel Corporation
diff --git a/Post/createStatistics.py b/Post/createStatistics.py
index 213927a..09d098e 100644
--- a/Post/createStatistics.py
+++ b/Post/createStatistics.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# SPDX-License-Identifier: MIT
# Create statistics. Update database.
#
diff --git a/Post/feed.py b/Post/feed.py
index 745ee23..5d57b54 100644
--- a/Post/feed.py
+++ b/Post/feed.py
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MIT
+#
# error-reporting-tool - URL definitions
#
# Copyright (C) 2013 Intel Corporation
@@ -25,7 +27,7 @@ class LatestEntriesFeed(Feed):
if self.mode == results_mode.SPECIAL_SUBMITTER and hasattr(settings,"SPECIAL_SUBMITTER"):
#Special submitter mode see settings.py to enable
name = settings.SPECIAL_SUBMITTER['name']
- queryset = BuildFailure.objects.order_by('-BUILD__DATE').filter(BUILD__NAME__istartswith=name)[:self.limit]
+ queryset = BuildFailure.objects.order_by('-BUILD__DATE').filter(BUILD__NAME__icontains=name)[:self.limit]
else:
queryset = BuildFailure.objects.order_by('-BUILD__DATE')[:self.limit]
diff --git a/Post/management/commands/culldb.py b/Post/management/commands/culldb.py
index 698537c..bd70ffc 100644
--- a/Post/management/commands/culldb.py
+++ b/Post/management/commands/culldb.py
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MIT
+#
# error-reporting-tool - culldb
#
# Copyright (C) 2015 Intel Corporation
diff --git a/Post/migrations/0006_buildfailure_referer.py b/Post/migrations/0006_buildfailure_referer.py
new file mode 100644
index 0000000..5fad048
--- /dev/null
+++ b/Post/migrations/0006_buildfailure_referer.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('Post', '0005_build_error_type'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='buildfailure',
+ name='REFERER',
+ field=models.CharField(default=b'NOT_VISITED', max_length=14, choices=[(b'NO_REFERER', b'no_referer'), (b'OTHER', b'other'), (b'NOT_VISITED', b'not_visited')]),
+ ),
+ ]
diff --git a/Post/models.py b/Post/models.py
index ddf2fc7..b7a913c 100644
--- a/Post/models.py
+++ b/Post/models.py
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MIT
+#
# error-reporting-tool - model definitions
#
# Copyright (C) 2013 Intel Corporation
@@ -13,6 +15,7 @@ import Levenshtein
class ErrorType(object):
RECIPE = 'recipe'
+ CHECK_LAYER = 'check-layer'
CORE = 'core'
BITBAKE_SELFTEST = 'bitbake-selftest'
OE_SELFTEST = 'oe-selftest'
@@ -24,6 +27,7 @@ class InvalidErrorType(Exception):
class Build(models.Model):
ERROR_TYPE_CHOICES = (
(ErrorType.RECIPE, 'Recipe'),
+ (ErrorType.CHECK_LAYER, 'check-layer'),
(ErrorType.CORE, 'Core'),
(ErrorType.BITBAKE_SELFTEST, 'Bitbake selftest'),
(ErrorType.OE_SELFTEST, 'OE selftest'),
@@ -59,6 +63,16 @@ class BuildFailure(models.Model):
ERROR_DETAILS = models.TextField(max_length=int(settings.MAX_UPLOAD_SIZE))
BUILD = models.ForeignKey(Build)
LEV_DISTANCE = models.IntegerField(blank=True, null=True)
+ REFERER_CHOICES = (
+ ('NO_REFERER', 'no_referer'),
+ ('OTHER', 'other'),
+ ('NOT_VISITED', 'not_visited')
+ )
+ REFERER = models.CharField(
+ max_length = 14,
+ choices = REFERER_CHOICES,
+ default = 'NOT_VISITED'
+ )
def get_similar_fails(self):
if self.LEV_DISTANCE is None:
diff --git a/Post/parser.py b/Post/parser.py
index 9639308..536e872 100644
--- a/Post/parser.py
+++ b/Post/parser.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# SPDX-License-Identifier: MIT
# Add errors to database from client
#
@@ -8,6 +9,7 @@
# Licensed under the MIT license, see COPYING.MIT for details
import json, re
+import bleach
from Post.models import Build, BuildFailure, ErrorType
from django.conf import settings
from django.utils import timezone
@@ -16,18 +18,7 @@ from django.core.urlresolvers import reverse
class Parser:
def __init__(self, data):
- self.data = data
-
- # returns true if the values contain '<' char
- # Ignore the failures field (which is an array anyway)
- def contains_tags (self, data):
- for key,val in data.items():
- if key == 'failures':
- continue
-
- if '<' in val:
- return True
- return False
+ self.data = data.decode('utf-8')
def parse(self, request):
build_fails_logged = []
@@ -37,8 +28,14 @@ class Parser:
except:
return { 'error' : 'Invalid json' }
- if self.contains_tags(jsondata) == True:
- return { 'error' : 'Invalid characters in json' }
+ # Bleach data going directly into the database so that
+ # displaying in any of the graphing doesn't introduce XSS
+ for key,val in jsondata.items():
+ if key == 'failures':
+ continue
+ if not isinstance(val, str):
+ continue
+ jsondata[key] = bleach.clean(val)
b = Build.objects.create()
try:
diff --git a/Post/purge.py b/Post/purge.py
new file mode 100644
index 0000000..dd58441
--- /dev/null
+++ b/Post/purge.py
@@ -0,0 +1,27 @@
+from datetime import datetime, timedelta
+from django.utils import timezone
+import os
+import sys
+
+def setup_django():
+ import django
+ # Get access to our Django model
+ newpath = os.path.abspath(os.path.dirname(__file__)) + '/..'
+ sys.path.append(newpath)
+ if not os.getenv('DJANGO_SETTINGS_MODULE'):
+ os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings'
+ django.setup()
+
+def main():
+ setup_django()
+ from Post.models import BuildFailure
+ delete_before = timezone.now()-timedelta(days=45)
+ query = "SELECT bf.id FROM Post_buildfailure bf LEFT JOIN Post_build b ON (bf.BUILD_id = b.id) WHERE bf.REFERER NOT IN ('OTHER','NO_REFERER') AND b.DATE < '{0}'".format(delete_before.date())
+ #print query
+ items = BuildFailure.objects.raw(query)
+ for item in items:
+ print "Deleting: ", item.id
+ item.delete()
+
+if __name__ == "__main__":
+ main()
diff --git a/Post/views.py b/Post/views.py
index 7f2cffb..3575c1d 100644
--- a/Post/views.py
+++ b/Post/views.py
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MIT
+#
# error-reporting-tool - view definitions
#
# Copyright (C) 2013 Intel Corporation
@@ -13,15 +15,16 @@ from django.shortcuts import HttpResponse, render
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import redirect
from Post.models import BuildFailure, Build, ErrorType
-from parser import Parser
+from Post.parser import Parser
from django.conf import settings
-from createStatistics import Statistics
+from Post.createStatistics import Statistics
from django.core.paginator import Paginator, EmptyPage
from django.core.exceptions import FieldError, ObjectDoesNotExist
from django.http import JsonResponse
from django.db.models import Q
import json
import urllib
+from urllib.parse import urlparse
class results_mode(object):
LATEST = 0
@@ -42,7 +45,6 @@ def common_context(request):
return ret
-
@csrf_exempt
def addData(request, return_json=False):
response = ''
@@ -63,12 +65,12 @@ def addData(request, return_json=False):
if return_json:
response = JsonResponse(result)
else:
- if not result.has_key('error'):
+ if not 'error' in result:
response = HttpResponse("Your entry can be found here: "+result['build_url'])
else:
response = HttpResponse(result['error'])
- if result.has_key('error'):
+ if 'error' in result:
response.status_code=500
else:
if return_json:
@@ -123,7 +125,7 @@ def search(request, mode=results_mode.LATEST, **kwargs):
items = BuildFailure.objects.all()
- if request.GET.has_key("limit"):
+ if "limit" in request.GET:
try:
n_limit = int(request.GET['limit'])
if n_limit > 0:
@@ -200,14 +202,14 @@ def search(request, mode=results_mode.LATEST, **kwargs):
],
}
- if request.GET.has_key("filter") and request.GET.has_key("type"):
+ if "filter" in request.GET and "type" in request.GET:
items = apply_filter(context, items, request.GET['type'], request.GET['filter'])
if mode == results_mode.SPECIAL_SUBMITTER and hasattr(settings,"SPECIAL_SUBMITTER"):
#Special submitter mode see settings.py to enable
name = settings.SPECIAL_SUBMITTER['name']
- items = items.filter(BUILD__NAME__istartswith=name)
+ items = items.filter(BUILD__NAME__icontains=name)
- elif mode == results_mode.SEARCH and request.GET.has_key("query"):
+ elif mode == results_mode.SEARCH and "query" in request.GET:
query = request.GET["query"]
items = items.filter(
@@ -253,14 +255,25 @@ def search(request, mode=results_mode.LATEST, **kwargs):
items = items.order_by()
return render(request, "latest-errors.html", context)
-
def details(request, fail_id):
try:
- build_failure = BuildFailure.objects.get(id=fail_id)
+ build_failure = BuildFailure.objects.get(id=fail_id)
except ObjectDoesNotExist:
- build_failure = None
-
- context = {'detail' : build_failure, 'error_types' : ErrorType }
+ build_failure = None
+ if build_failure:
+ try:
+ referer = urlparse(request.META['HTTP_REFERER'])
+ referer_hostname = referer.hostname
+ if referer.port:
+ referer_hostname += ":" + str(referer.port)
+ if referer_hostname != request.get_host():
+ build_failure.REFERER = 'OTHER'
+ except KeyError:
+ # There is no referer
+ build_failure.REFERER = 'NO_REFERER'
+ build_failure.save()
+
+ context = {'detail' : build_failure, 'error_types' : ErrorType, 'bugzilla_url' : settings.BUGZILLA_URL }
return render(request, "error-details.html", context)
diff --git a/README b/README
index f759d28..d56fdbd 100644
--- a/README
+++ b/README
@@ -48,7 +48,7 @@ The latest version can be checked out by git cloning:
git://git.yoctoproject.org/error-report-web
Contributions are welcome. Please send patches / pull requests to
-yocto@yoctoproject.org with '[error-report-web]' in the subject.
+yocto@lists.yoctoproject.org with '[error-report-web]' in the subject.
To manage the size of your database there is a convenience command:
diff --git a/manage.py b/manage.py
index 82cfa83..8edb2e4 100755
--- a/manage.py
+++ b/manage.py
@@ -1,4 +1,6 @@
#!/usr/bin/env python
+# SPDX-License-Identifier: MIT
+
import os
import sys
diff --git a/project/settings.py b/project/settings.py
index 3c6c87e..989b2c9 100644
--- a/project/settings.py
+++ b/project/settings.py
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MIT
+#
# Django settings for error-reporting-tool project.
# Based on settings.py from the Django project template
# Copyright (c) Django Software Foundation and individual contributors.
@@ -195,6 +197,8 @@ TEMPLATE_CONTEXT_PROCESSORS = (
AUTH_PROFILE_MODULE = 'registration.RegistrationProfile'
+BUGZILLA_URL = 'https://bugzilla.yoctoproject.org'
+
ACCOUNT_ACTIVATION_DAYS = 2
EMAIL_HOST = 'localhost'
DEFAULT_FROM_EMAIL = 'noreply@example.com'
diff --git a/project/urls.py b/project/urls.py
index 0e8f39c..c1ac55f 100644
--- a/project/urls.py
+++ b/project/urls.py
@@ -1,3 +1,5 @@
+# SPDX-License-Identifier: MIT
+#
# error-reporting-tool - URL definitions
#
# Copyright (C) 2013 Intel Corporation
@@ -22,7 +24,7 @@ urlpatterns = patterns('',
#url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
- #url(r'^admin/', include(admin.site.urls)),
+ url(r'^admin/', include(admin.site.urls)),
#url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^(?i)Errors/Latest/$', 'Post.views.search', { 'mode' : results_mode.LATEST }, name= "latest_errors"),
url(r'^(?i)Errors/Latest/feed$', LatestEntriesFeed(), name="errors_feed"),
diff --git a/project/wsgi.py b/project/wsgi.py
index 7d4fc73..8d3ba66 100644
--- a/project/wsgi.py
+++ b/project/wsgi.py
@@ -1,3 +1,7 @@
+#
+# SPDX-License-Identifier: MIT
+#
+
"""
WSGI config for errorsreport project.
diff --git a/requirements.txt b/requirements.txt
index 909d054..52633b4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
Django<1.9
python-Levenshtein==0.12.0
+bleach \ No newline at end of file
diff --git a/templates/error-details.html b/templates/error-details.html
index c30160d..35bf0aa 100644
--- a/templates/error-details.html
+++ b/templates/error-details.html
@@ -83,7 +83,7 @@
</dl>
<div>
- <a class="btn btn-block" target="_blank" href="https://bugzilla.yoctoproject.org/enter_bug.cgi?classification=__all" >Open a bug</a>
+ <a class="btn btn-block" target="_blank" href="{{bugzilla_url}}/enter_bug.cgi?classification=__all" >Open a bug</a>
</div>
</div>
</div>
diff --git a/templates/latest-errors.html b/templates/latest-errors.html
index 87e30d8..b9f081e 100644
--- a/templates/latest-errors.html
+++ b/templates/latest-errors.html
@@ -131,7 +131,7 @@
<td class="submitted_on"> <a href="{{details_url}}">{{ build_fail.BUILD.DATE|date:"d/m/y H:i"}}</a></td>
<td class="error_type"><a href="{{details_url}}">{{ build_fail.BUILD.get_ERROR_TYPE_display }}</a>
- <a class="filter" href="#" data-filter="{{build_fail.BUILD.get_ERROR_TYPE_display}}" data-type="error_type">
+ <a class="filter" href="#" data-filter="{{build_fail.BUILD.ERROR_TYPE}}" data-type="error_type">
<i class="icon-filter hover" title="Filter by {{build_fail.BUILD.get_ERROR_TYPE_display}}"></i>
</a>
</td>
diff --git a/test-data/test-send-error.py b/test-data/test-send-error.py
index 7070c18..1252855 100755
--- a/test-data/test-send-error.py
+++ b/test-data/test-send-error.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
-#
+# SPDX-License-Identifier: MIT
+
# test/example script for sending data to error-report-web
import urllib2