When a user logs into a community auth site, that account is
automatically subscribed to receive updates from the system whenever any
changes are made to the user, such as name/email/ssh keys. However, when
a site imports a user without them being directly logging in, that
subscription is not set up, so any changes made are lost until the user
first logs in.
This commnit adds an endpoint to the auth system so that a site can
expliciltly request updates are sent about a user. This will create a
"fake login" on that site, which will enable the normal system to start
sending data. The access to the endpoint is protected with a hmac
authentication using the existing community auth key.
Require each view to declare which query parameters it wants, and filter
out any other parameters.
We have very few views that actually take query parameters, and random
additional query patterns will have no effect on the view. However, they
will break frontend caching (in making them look like different pages).
This will be extended into an implementation in the caching frontends as
well, btu it's needed in the backend to ensure that local testing will
have tbe same effect as the caches.
* Get rid of the django_markwhat dependency, and implement our own
classes to get more control. In passing also remove django-markdown,
because we never used that.
* Instead of trying to clean markdown with regexps, use the bleach
library (NEW DEPENDENCY) with special whitelisting of allowed tags
based off standard markdown. This means that one can input links or
formatting in HTML if one prefers, as long as it renders to the same
subset of tags that markdown allows.
* Replace javascript based client side preview with an actual call to a
preview URL that renders the exact result using the same function,
since the use of showdown on the client was increasingly starting to
differ from the server, and since that cannot be kept secure the same
way. Rewrite the client side javascript to work better with the now
longer interval between updates of the preview.
Long in planning, but never got around to it.
Suggestion to use bleach for escaping from David Fetter.
If an email is already added as a secondary address to one account,
don't allow creating a new account using that email, unless it's
removed. Otherwise we end up with the same email address attached to
multiple different accounts, which can cause big problems downstream.
This should never have been allowed of course, but was missed when
support for secondary emails was added.
Change the subject to use the title of the object instead of the id, and
include a link to the moderation page. There's surely more to be done,
but this is a decent start.
This allows organisation managers to add more than one email address to
an organisation, and use this for sending news from. Sending news is the
only thing that the email field is used for at this point. Adding an
email will trigger a validation email sent to the address with a token
to confirm it, so that we can actually trust the emails.
Remove the previous registered emails on organisations. These addresses
were never validated and thus cannot really be trusted, so it's better
to remove them cleanly than to migrate them into the new system and be
uncertain.
Finally, in passing, remove the phone field on organisations. We've
never used that for anything and there's not really any point in
collecting the data.
This includes a number of new features:
* Move some moderation functionality into shared places, so we don't
keep re-inventing the wheel.
* Implement three-state moderation, where the submitter can edit their
item and then explicitly say "i'm done, please moderate this now".
This is currently only implemented for News, but done in a reusable
way.
* Move moderation workflow to it's own set of URLs instead of
overloading it on the general admin interface. Admin interface remains
for editing things, but these are now separated out into separate
things.
* Do proper stylesheet clearing for moderation of markdown fields, using
a dynamic sandboxed iframe, so it's not ruined by the /admin/ css.
* Move moderation email notification into dedicated moderation code,
thereby simplifying the admin subclassing we did which was in some
places quite fragile.
* Reset date of news postings to the date of their approval, when
approved. This avoids some annoying ordering issues.
This allows each account to have more than one email address, of which
one is primary. Adding more addresses will trigger an email with a
verification link (of course). The field previously known as "email" is
now changed to be "primary email".
Change the profile form to allow freely changing between the added
addresses which one is the primary. Remove the functionality to directly
change the primary email -- instead one has to add a new address first
and then change to that one, which simplifies several things in the
handling.
With the new django, alerts are raised for everything with status 500,
not juse exceptions. This put a light on a number of places where we
were returning 500 server error code for things that are not actually
server errors. Some should be a regular 200 ok with an error message,
and others should be a permissions error.
This information can be useful when trying to debug issues with the
community auth and the wonders of distributed data...
No actual django model is created because django still doesn't support
multi-column primary keys. Thus no tool to use the data yet other than
psql.
The following security policy headers are set:
X-XSS-Protection: 1; mode=block -- always set
X-Frame-Options: DENY is set for all pages except for the documentation
pages, primarily because pgadmin4 loads them in an iframe which would
break.
Content-Security-Policy: <x>-src
Is set to allow the default of self only, then allowing scripts for
google analytics and fonts for google fonts. Images are allowed from everywhere.
frame-ancestors 'none' is set by the same rules as X-Frame-Options
This also adds a decorator for @script_sources to have a single view
allow extra sources, and this is used for recaptcha. A generic decorator
is also made for other types of exclusions, though we don't have any at
this point.
If the setting SECURITY_POLICY_REPORT_ONLY is set to True then the policy
will be report-only and not enforced (for testing), otherwise enforcing
mode is enabled.
The setting SECURITY_POLICY_REPORT_URI sets where to send security
policy reports, if any.
This was becoming illegible and also hard to maintain based on how
we changed up the look/feel of the entire site. That way, we have
two distinct categories for both types of objects, which makes it
easier for the user to understand what is what.
Also reworded the explanation for what is going on, both based on
the structural change and because it read like a literal interpretation
of the code.
In the normal workflow this would always happen, but if the user got to
the page without being logged in (probably most likely to happen if the
session timed out while waiting to proceed) we would crash on trying to
create an invalid consent record. Instead, force a re-login in this
case.
If a user gave consent to sharing community auth data in two parallel
sessions, one of them would crash with a unique violation. To avoid
that, use the django function for get_or_create(), and just throw away
the results if it turned out to be a get.
This adds a new model for CommunityAuthOrg representing the organisation
that runs the system that's being authenticated (e.g. PostgreSQL Europe
or PostgreSQL US). For this we just keep a name and a "is consent required" flag.
In the case where consent is required, we keep track on a per-user basis
of if they have given consent to sharing their data with this
organistion. If they haven't, we ask for it before completing the
redirect and actually sharing the data.
This is today only used for things coming out of the accounts system,
like new accounts and password resets. To make sure we don't
accidentally start using it for something else, change the name of the
parameter.
By default, Django expects URLs to end with a "/" but if it
accepts a request without a trailing slash, it will issue a
permanent redirect with the slash appended. While this is great,
it does mean an extra request to the server.
This patch adds a "/" to anchor tags that did not have one
already appended to it, thus helping to save time for a user
browsing .org as well as for the server.
The django version of password reset is broken in multiple way. What's
hurting us in particular is it cannot reset the password of a user where
the old password was generated by a deprecated hasher. Which, of course,
is exactly one of the cases where being able to reset the password is
important.
We still use the same infrastructure, and we use the actual django code
for *changing* the password -- this just replaces the token sender with
something that's a lot simpler and less broken.
render_to_response does not work on newer django, so it needs to be
replaced. And using a speicfic context actually overcomplicates things,
it's easier to just use a wrapper function. For those cases where we
don't need NavContext, just use render() (the new shortcut function from
django), which also removes the need to use RequestContext.
We don't want two different accounts to exist with the same email
address only differing in case. This had already happened for a few
which have been manually fixed, since it turns out we only enforced the
rule on new account creation, not when accounts changed email address or
when they were created using oauth. Also add database level constraints to
make sure this cannot happen again if some codepath is missed.
We want to use the noreply@ email address when sending out notifications
to addresses that have yet to be verified, since we can just ignore
bounces to those.
Previously when signing up for a new account in the middle of an
authentication process, the final redirection URL was lost and the user
was sent back to the /account/ page. Instead, we now redirect to the
proper URL (for sending back to the community auth client site) if it's
available in the session, both for successful signup and for
canceled logins.
In the event of a failed password attempt, we'd loose the "next url"
part in community auth, so once the correct password was entered an
error message about unknown redirect would show up.