If you clicked on logout in the admin site then clicked on the "Login"
button and logged in, you were redirected to the logout page because we
weren't detecting that the redirection should not be applied.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
* Tweak message when one or more (but not all) security question answers
have been changed so that it's clear that all are required
* Ensure success message gets shown upon saving
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
* Require all three answers to be correct (previously only two had to
be)
* Give the user three attempts instead of just two
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We use django-axes to lock out IP addresses after a set number of
attempts at logging in, and separately we use django-reversion to
record change history. As part of the history tracking, the default
behaviour of django-reversion is to wrap all POST requests in
"with transaction.atomic()", with the result that if an exception is
raised any changes get rolled back; unfortunately when authentication
fails for the final time, axes updates the database and then raises
PermissionDenied - with the result that the database changes are rolled
back, and the user's IP is not locked out, in fact it can never be
locked out. To work around this, disable the atomic mode on
ReversionMiddleware using a subclass. (I don't like having to do this,
but this is the quickest solution for now.)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Simplify things a bit. We lose the digg-style pagination but the new
behaviour is good enough and improves maintainability.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
When running a task (e.g. importing other distribution data), the web
frontend polls to get task output every second. In the view handling
this request we check to see if the underlying Celery task is finished
by getting the AsyncResult and then calling result.ready().
Unfortunately that latter call seems to be failing some of the time in
the development Docker setup that I am using, throwing a
ConnectionResetError. Because the polling is regular it doesn't really
matter if this fails as there'll be another chance on the next poll, so
just allow the call to fail silently. (It pains me to put in workarounds
like this but at the moment I can't determine the real cause of the
issue, and this stops the stream of ultimately useless error report
emails that I'm getting as an admin of the development instance).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Calling communicate() blocks the process; but since we're writing the
output directly to a file and not sending any input we don't actually
need to call communicate(), just poll() (so that we can check
the returncode attribute). Subjectively this does appear to improve
performance although it has not fixed the ConnectionResetError issues.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If an update task's output contains a single quote for example (') then
this will be escaped to an HTML entity before it gets sent as a
response. However, that means that the length of the data in the response
will be greater than the length of the original data, resulting in
characters getting missed out when we read the next chunk - so we
can't use the escaped length to set the next position to read from. The
easiest thing to do is have the Django view send us the actual position
we're at and then we don't have to try to calculate it on the JS side.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
There's no particular reason these fields should be read-only (unlike
the fields picked up from Recipe, they aren't derived from the recipe
itself.)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Strengthen things a little where shell=True is still being used.
(For the most part input that passes through here would already be
sanitised, but let's be careful anyway).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
I have been seeing repeated emailed errors from Django reporting
"ConnectionResetError: [Errno 104] Connection reset by peer" in the call
to get task status i.e:
File "/opt/layerindex/layerindex/views.py" in task_log_view
1572. if result.ready():
Digging around this seems to be some sort of known bug:
https://github.com/celery/celery/issues/4817https://github.com/celery/celery/issues/4980
The workaround suggested is to disable the broker heartbeat, so try
that in order to avoid the errors.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Once we get to the package definitions we don't want to be gathering
field values (or we'll just get the last package's summary value for the
overall summary for example).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Record the configure script options when importing recipe / package
information so we can display them.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Allow passing a list to run_update_command() instead of a string which
will run the command directly instead of within the shell.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
There's a little more to patch handling in spec files than "patchX:"
fields - the patch actually has to be applied in the %prep section as
well, though this can take one of several forms (%autosetup / %autopatch
which apply all patches, individual %patchX directives, or even direct
application (rare). There's also the matter of the striplevel (-p option
to the patch command). Add fields to record whether or not a patch is
applied and the striplevel.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
I came across several spec files in Clear Linux that has a PNG file in
the description value. No idea how that got there, but avoid choking and
ignore the garbage description if this happens.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We don't actually need this for anything at the moment, but it would be
useful if we get to the point where we need to access imported files
within the application after the import process (e.g. to compare
patches).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If a source points to a local file, get the sha256sum of it and save it
into the field we just added.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Allow us to record a checksum for local sources (and potentially remote
ones if it is recorded in the recipe). This just adds the field, but
doesn't populate it.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Make it easier to import different versions of the other distro by not
requiring you to manually create the layer and branch.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If for some reason we do not find any spec files in the specified
directory, error out instead of marking all packages as deleted. (This
can happen if the wrong directory is specified.)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
* Make patch / user fields non-editable for existing records (patch
mostly because the list is huge for a drop-down)
* User must be a superuser or the dispositioner to edit
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add the ability to mark each patch with a disposition indicating whether
the patch is interesting or not.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Editing on this page is done by clicking through to another page, so
it should be a DetailView rather than an UpdateView and shouldn't have a
form class set.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
For the purposes of creating a dump suitable for importing into a fresh
database during initial setup, add a script that creates a dump of an
existing database with the complete structure but without any data that
involves users (or anything else we don't want).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If you specified only the layer index URL and not the full API URL i.e.
https://layers.openembedded.org then we put an extra slash in the URL
which resulted in the request being redirected to the main page which
breaks the request.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
In order to have registration/password reset emails working properly we
need to have both the site domain and email host/port set correctly.
Email host/port is easy to set (environment variable read into the
configuration). However, to set the site info, create a simple script
that we can call to do so.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
It's best practice for security reasons to use shell=False and pass
command line arguments as a list; it also avoids some pain with
escaping, so let's use it everywhere we can (in fact we're only left
with one place in layerindex/tasks.py where we now pass shell=True).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Indentation, spacing, and wrapping of a long import line.
Signed-off-by: Amber Elliot <amber.n.elliot@intel.com>
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add user security questions upon registration as extra authentication
for password reset. Three unique security questions must be chosen and
answered. Answers are then stored in the database with the same hashing
algorithm as the users's password.
On password reset, users get two chances to get two out of three
security questions answered correctly. After a second failure their
account is locked and email is sent to the admin. The same template is
shown for the axes lockout. Super user cannot reset their password until
they set security questions.
Users can update their security questions or add them if they weren't
originally set (in the case of super user) in Edit Profile.
Signed-off-by: Amber Elliot <amber.n.elliot@intel.com>
This involves changing how registration templates are referenced
and how the activation email is sent on user's email address change.
Signed-off-by: Amber Elliot <amber.n.elliot@intel.com>
This allows users to see the site ID in the admin page.
Signed-off-by: Amber Elliot <amber.n.elliot@intel.com>
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Patches often need to be applied in a specific order. For OE recipes we
were always storing the Patch objects correct order as they are
refreshed every time the recipe itself is refreshed, however for other
distro comparisons, import_otherdistro.py attempts to preserve existing
records, adds new ones and then deletes whatever is left over, which may
result in the order getting messed up over time. To avoid this issue,
record the order next to the patch and set the model meta-info to use
this to sort Patch queries by default.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Best practices state that you should use a mechanism that ensures files
get closed in case of any error, so let's do that.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Errors deleting bitbake.sock and bitbake.lock have been observed when
shutting down tinfoil at the end of some of these scripts. Move the code
used in the main layer index update script to a function in utils.py and
use it everywhere in order to avoid the issue.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Add links to the same recipe in other branches in the recipe detail page
(and RRS recipe detail page) so that you can see which versions are
available in other branches and drill down to the detail if you want to.
Implements [YOCTO #13019].
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If someone adds you as a maintainer of a layer as a matter of courtesy
it would be nice if you get an email.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Some controls on the Submit / Edit Layer page were getting the wrong
width and any "feedback" elements were being pulled to the right because
of the size of their parent divs. Instead of pulling in the size of the
form control, act on the div to fix the problem. Additionally the
help text should now be allowed to expand to the full width of the
parent div since that is now sensible.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Send the current URL path as a parameter to the login URL so that after
successfully logging in, you come back to where you were beforehand.
Also hide the login/user drop-down on the login page since it's
superfluous.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Use a parameter to pass the current page to the Edit Profile URL so that
saving or cancelling returns you to that same page.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We were using uitablefilter.js to provide live filtering of table rows
based upon a search field value, but it turns out this module really
isn't necessary - we can accomplish the same thing using simple jQuery
code. While we're at it, enable the search field on the layers list page
to work in conjunction with with the drop-down layer type selection, fix
pasting into the search field and refreshing with a search specified.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If you're searching for items that are of status "unknown/not available"
in the other distro packages, you're usually doing so to find things
that haven't been dispositioned. Originally I had included them here
because the "available" status correctly excludes items with the
"distro-specific" status and "unknown/not available" seemed like it
should be the inverse, but usage seems to require that it not be.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If a user goes to Edit Profile and changes their email address,
deactivate their account temporarily and make them go through the
registration process to confirm that the new email address is in fact
valid and theirs.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
On top of the CAPTCHA, prevent more than 10 name change attempts for the
same user with the Edit Profile page so that username enumeration is
made even more difficult.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Users may want to change their usernames for a number of different
reasons, but at the moment we require them to contact an admin to do
that. Provided we validate the new username correctly and add a CAPTCHA
to make automated enumeration difficult, we can add username to the Edit
Profile form and then users can do that any time they wish.
While we're doing this, show a message when the profile is successfully
updated.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Make it possible for users to delete their own account and all associated
information from the database, should they decide they no longer wish to
use it.
(I checked the implications of doing this on our model structure -
anything with a foreign key to user is safe to delete with the exception
of RRS MaintenancePlan.admin which I needed to change on_delete for so
that it doesn't get deleted with the user).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Extend and override the default views so we can extend and override the
default forms to add a CAPTCHA field. This should prevent the automated
account creation requests we've been seeing on layers.openembedded.org
(luckily failing anyway due to bad domain names), but in any case this
also improves security by making it harder to do user enumeration.
For the registration page in particular, because Django's forms logic
tries to be helpful by showing all errors at once, we need to change it
so that if there's an error for the CAPTCHA then you only see that error
and no other - in particular you won't see "that username already
exists" if that is the case.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This was copy-pasted from the DistroSearchView and I clearly forgot to
replace the reference here.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
It's been reported to me that it's possible in a custom setup to have a
bitbake repo that intentionally doesn't have a master branch, so pick
up the bitbake branch from the master Branch record if it exists and the
bitbake_branch field is set.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
nvd3 and its python/django wrappers appear to be no longer actively
maintained, and at least the wrappers were a bit clunky to use. Looking
around for a suitable replacement, Chart.js seems capable, has no
additional dependencies and is fairly simple to use. As a bonus we get
to drop a few Python dependencies from our list.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
It's not too common but there are instances where people have copied
.inc files into their own layer and modified them, and if you are using
such a layer that could result in unexpected behaviour. In order to get
a handle on when this is being done, collect data about all .inc files
and show duplicates in the Duplicates screen.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Split out the code used in the recipe search views to its own function
and use that same function in three different places rather than having
a copy of largely the same code. Also take the opportunity to add some
comments.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
On layers.openembedded.org we're seeing requests from some search engine
crawlers requesting the CSV export URL with an invalid branch for the
layer. I couldn't see the referer anywhere in the logs but I suspect it
has to do with some recent cleanup work I did in the database where I
deleted some invalid LayerBranch records - they were probably following
links in a cached version of the webpage. In any event we want to return
404 in this situation rather than an internal server error.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
In order to show bbappends on the recipe detail page we are doing a
regex query to find any whose names match up with the recipe. In the
layer index instance at layers.openembedded.org viewing the recipe
detail page for any recipe whose name contains ++ (e.g. libsigc++-2.0 in
meta-oe) results in an invalid regex and causes a database error. Escape
any + signs in the name used within the regex in order to fix this.
(I wasn't actually able to reproduce this on my own setup despite also
using MariaDB, but I did find that the unescaped query was not correctly
matching records so it needed to be fixed anyway.)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
When you make changes to the infrastructure it can be useful to test
that email sending is working, since for that to work that involves the
code, Celery, RabbitMQ and SMTP being functional. However, up until now
to run a test you needed to submit a fake layer which is a bit annoying.
Add an explicit "Test email" option to the Tools drop-down for staff
users to allow them to send an email to themselves.
Note: the page will come back when the Celery job has been created, it
does not check and report on the job status - you need to look on the
server side to see that.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Sometimes we get massively long lines from the update script
(particularly if there's an error) so ensure that long lines get
wrapped.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If we want to be able to read in patch information on python2-based
branches (e.g. fido) then we need to use codecs.open() instead of open()
here since python2's open() did not support the encoding parameter.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If you update a python2-based branch then the python2-compatible version
of bitbake will be checked out, but we are calling into bitbake's
bb.utils directly here from python 3 and thus you get an error about
commands.getstatusoutput being missing (since that is not available in
python 3 and the old version of bitbake refers to it). To fix this,
check out origin/master in the bitbake repo right before we call the
code in question.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
When we print a warning about the value of a CharField being truncated,
print out the string representation of the object so we have a chance of
finding the offending object.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Enable searching on vcs_url on LayerItem and layer name and vcs_url on
LayerBranch. This makes it easier to find the layers/branches in a
particular repository (e.g. meta-openembedded).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
I've come across at least one layer that is now hosted on gitlab.com, so
add support in the layer submission/edit form and import_layer.py for
automatically determining the other fields for gitlab.com URLs.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We don't want to allow any other arguments to be injected into these
commands, so disable the shell and pass the parameters in the form of a
list to prevent that.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Sometimes layers get created on master and then the master branch is
removed in favour of a release branch. In that case it can be useful to
switch the existing layerbranch record rather than having to create a
blank one and copy everything over.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
The code in recipeparse.setup_layer() was trying to log a warning in the
case where LAYERRECOMMENDS not being satisfied, however there is no
actual logger object in this context. Pass it in via a parameter and
update all callers to pass it.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
In c26604146a I made a fix to change where
the bitbake code writes out bitbake.lock and other files it creates
during parsing, but didn't adequately test it and it turns out our
call to delete the temp directory races against bitbake deleting
bitbake.lock and bitbake.sock. For now the simplest way to deal with
this is to ignore the errors since we don't care about these files,
we just want the temp dir gone.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Our setup when parsing recipes is a little unusual in that we have no
bblayers.conf, thus findTopdir() which is used to find where to put
bitbake.lock (and bitbake-cookerdaemon.log as of the recent bitbake
commit 1620dbc48ffb2a882371cf9174a7b12648befc8a) defaults to the
parent's parent of where bitbake.conf can be found, which is the meta/
subdirectory of the OE-Core repo, thus that's where we now find
bitbake-cookerdaemon.log gets written out. We really don't want to be
writing anything into the metadata repositories so create a fake
conf/bblayers.conf in our temp directory to make findTipdir() pick that
instead.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This isn't a visual thing, this select element must remain hidden, so it
seems a bit more appropriate to me to specify the style directly on the
element rather than using a CSS class to do it.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
For situations where the user launches a distro comparison update
process and then shortly afterwards realises it is operating with the
wrong configuration (or is otherwise broken) and is going to take a long
time to finish, add a button to the task page to stop the task. This was
tricky to get working, since the default behaviour of Celery's revoke()
would either terminate both the Celery task process along with the update
process (leaving us with no log saved to the database) or worse not even
kill the update process, depending on the signal sent. To avoid this,
send SIGUSR2, trap it in the task process and kill the child process,
returning gracefully. To make that possible I had to rewrite runcmd() to
use subprocess.Popen() instead of subprocess.check_call() as otherwise
we can't get the child's PID.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If a distro comparison update task fails (returning a non-zero value to
indicate as such) we were not able to see this easily from the frontend.
Show success/failure in the form of a label on the task page and general
update list/detail, and if the task fails while we're watching then make
the progress bar go red as well. Also make a distinction between the
process failing (retcode > 0) and being terminated (retcode < 0, e.g.
process was killed).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Provide a mechanism for distro comparison update tasks to display
progress. In practice this means the update command needs to write the
progress percentage to a file and then the log view (which is polled by
the frontend) reads this file. Originally I was going to use a FIFO for
this but that turned out to be a but unreliable; I also tried to use
Celery's state mechanism to pass it back but I simply could not get it
to work. The file-based mechanism is good enough though.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We were refreshing the page constantly in order to show output while
a task was running, which basically worked but is horrible. Instead,
write the task output to a file and then use AJAX calls to request
whatever output has been written to the file since the last call
and call this roughly every second. Put the output in a scrollable <pre>
element instead of making it the length of the page, and auto-scroll
to the end (unless the user grabs the scrollbar and pulls it upwards -
it may not be immediately obvious that you can do this if there is a lot
of output since you have to pull it up when the scrolling animation is
not running, but it is possible).
An alternative would be to have used some kind of long-lived HTTP
session or a websocket, but those come with their own set of problems
so I elected to use this much simpler method.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
In a bunch of places we needed to get the branch we were supposed to
be checking out (which is actual_branch if that is set, otherwise the
normal branch name). Add a function to do that.
Additionally, instead of showing the normal branch name next to the
"last update" date, use the result of this new function.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Use a more modern version of Bootstrap and take the opportunity to
upgrade jQuery to the latest version at the same time. This provides
better browser compatibility, moves to MIT license, allows us to make
the site more responsive for different devices in future, and provides
theming capabilities for custom installs among other improvements.
(I chose to upgrade to v3 for now rather than straight to v4 as it was
easier to do this gradually.)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We were missing some import statements here, so clearly I didn't test
this as I thought I had.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Now the logic is:
Use options.layer_type if specified, and guess if not. Default to 'M'.
Note choices=['A', 'B', 'S', 'D', 'M', ''], the '' is for default='', we can't
use default='M' here, otherwise we don't know whether the 'M' is specified by
user or is the default value, we don't guess if it is specified by user,
otherwise, guess.
Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
If a user doesn't have publish rights and the type of the layer isn't
already "Base" then disallow selecting the Base layer type. Some
submitters are selecting this type for their own layers, but it's pretty
much reserved for openembedded-core and meta-oe (so that they appear at
the top of the layer list).
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
We do not want to be prompting the user for a password during layer
updates or upstream checks, e.g. in the case where a repo requires
authentication, or on github where any fetch of a nonexistent repo
apparently triggers authentication.
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>