Code Monkey home page Code Monkey logo

approval_frame's Introduction

About

Lots of websites have polls, usually as a little side bar. But most of those polls are based on plurality voting ๐Ÿ˜ก, an inferior voting method.

vote.electionscience.org is a replacement for those polls, using approval voting, which is suitable for embedding in other webpages via an iframe tag. The project, taken as a whole, will serve these approval-based webpolls, or the approval_polls package contained within it can be added to other Django-based servers to be used locally.

Development Setup

docker-compose up
docker-compose exec web python manage.py migrate
docker-compose exec web python manage.py test
docker-compose exec web python manage.py collectstatic
open http://localhost:8000

Local Steps (assumes a linux system)

  1. Install git. If you're new to git then the Pro Git book is useful.

  2. Clone this repository. git clone [email protected]:electionscience/vote.electionscience.org.git.

Configure your environment with .env file. You can copy the .env.dist file and fill in the required values.

  1. Before you run the Django server for the first time, you'll need to create the database tables:

    python manage.py syncdb

    This will ask you to create a superuser account, which is necessary if you want to use the Django admin interface. But also, you'll need a user account in order to create polls in the system, and it's easiest to do that here. (If you don't create an account here, you'll have to mess around copying urls from the server output to fake confirming an email address in order to create a user account later... so just do it now.)

  2. Start the Django server:

python manage.py runserver

  1. Change the domain name of the site example.com to yourdomainname in the admin panel (https://localhost:8000/admin) so that the activation emails have the correct url.

  2. Finally, see how it looks. In your favorite browser, go to the link:

<your domain name>:<port>

If you're running the server locally then this would be

http://localhost:8000/

There won't be any polls yet, but you can login with the superuser account you created, or register a new one. Then you should be able to create polls, vote in them, and see the results.

Contributing

  1. If you're new to Python, Google's Python tutorial gives a basic introduction to the language. There are several other tutorials available on the web.
  2. If you're new to Django, the tutorial on Django's documentation page is very comprehensive. In fact, through a happy coincidence, it uses a poll application as an example. This project is heavily based on that tutorial.
  3. If you're new to git, as mentioned above, the Pro Git book is very useful.
  4. In order to contribute, please follow the fork-and-pull-request model as documented here. Also, do check out the coding style guidelines outlined in the next section.

All contributions are welcome.

Coding Style

We use Trunk.io to enforce a consistent coding style. You can install it by running npm install -g @trunk/cli and then running trunk check in the root of the project.

Testing the code

  1. Whenever new code is written and features are added, there is a possibility that existing functionality may break. So just to be on the safer side, it is good to make sure that all is well - by running:

    python manage.py test

  2. Apart from adding new test cases to cover new functionality, it is always a good practice to keep a check of the code coverage with the tool coverage to make sure that the code is still well tested. Read more about this here !

Deploying in production

This repo is deployed in production on fly.io from Felix Sargent's account.

Deployment is as easy as running fly deploy from the root of the project, if you have it configured.

Ideally, this automatically deploys on push to the Github main branch!

approval_frame's People

Contributors

asavageiv avatar ashimaathri avatar balajisubr avatar brianjr0428 avatar clchen28 avatar faxn avatar fsargent avatar kushankr avatar kyleneideck avatar madhurimurali91 avatar mudlock avatar nigelkibodeaux avatar rupalkhilari avatar sourcery-ai[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

approval_frame's Issues

Polls in iframes on cross-domain pages fail CSRF check when 3rd-party cookies are blocked

This Django bug outlines the issue fairly thoroughly: https://code.djangoproject.com/ticket/17157. In short, when you create a poll and put the embedding code it provides (<iframe src="http://localhost:8000/approval_polls/2" width="250"></iframe>) on a page on another domain, browsers that disallow third party cookies can't vote. They see a Django 403 page with the message "CSRF verification failed. Request aborted."

Both IE and Safari (including iOS) block third party cookies by default. Firefox was apparently going to start blocking all third party cookies from sites the user hasn't visited themselves - http://blog.mozilla.org/privacy/2013/02/25/firefox-getting-smarter-about-third-party-cookies/ - but in Firefox 30 the default is still to accept all cookies.

I found a few possible fixes, but nothing ideal.

It can be fixed in IE by sending a P3P header, but then "you're essentially making legally binding claims about how you handle user data".

We could disable Django's CSRF protection and check the referer header instead. This would work in (up-to-date) browsers but CSRF attacks would be easier in other applications where users can trigger HTTP requests for each other. There have also been referer-spoofing bugs in older browsers: http://seclists.org/fulldisclosure/2013/Jul/60. Although, couldn't that be worked around by checking user agents against a list of known-vulnerable browsers? There are a few other problems with this approach listed on the OWASP CSRF Cheat Sheet.

There's also a header called Origin that's designed for this case, but browser support isn't really there yet.

Another idea is to tie the CSRF token to the user's IP instead of to a cookie. For example, you could hash the IP with a secret key and use that as the token.

There are a bunch of workarounds that make pseudo-cookies at http://samy.pl/evercookie/. Using any of those would be a bit of a hack, but the ETag header looks promising.

I had a look at some other online polls to see if they had a solution but they all seemed to have no CSRF protection at all.

Add a free/libre/open license!!

This code is all-rights-reserved by legal default until you add a license. Furthermore, you have to handle all sorts of challenges when accepting code from others if the licensing isn't clear. If you have a LICENSE file here, then others who adjust the code in a repository that has the same file can at least be assumed to stick to the same license.

I would consider GNU AGPLv3+ (+ means include the "or later" clause) as the most community-centered freedom-respecting license. The only concern is that if you want to push adoption of this software by other websites which may be proprietary and where they would integrate this into their site, then you may want a more permissive license. GPLv3+ would be fine because it would be equally usable for even proprietary sites and the copyleft (i.e. share-alike / pass-on-the-freedoms) effect would only take place if someone distributes the code and not when they just use it on a site. You could slightly improve license-compatibility with GPLv2+ but that would lose the patent clauses and such. Otherwise, Apache v2 would be a decent option, or MIT to be most permissive. While I'd probably go with AGPLv3+ or maybe GPLv3+, any of these would be better than the really unacceptable state of having no license.

Limit poll to specific e-mails set by poll administrator

The administrator of a poll limits the respondents to only those with specific e-mails. Accounts not attached to the listed e-mails cannot participate in the poll. This feature should be able to be turned on or off by the poll administrator.

Implement Score Voting

Approval is nice, but wouldn't score be even better?

Bonus: Configurable range (including negative numbers) by question (instead of any particular fixed ranged)

Allow registered users to update their ballot

If a poll has been marked as type 2 (only registered users can vote), it would be nice to allow the user to update his/her ballot anytime before the closing date of the poll is reached (to be implemented in #15) . Currently, with this setting, the user is only allowed to enter their ballot once, after which he/she is not allowed to vote in that poll again.

Fix tests

Tests fail with status - FAILED (errors=10, skipped=1, expected failures=1)
The error in most cases appears to be NoReverseMatch: u'approval_polls' is not a registered namespace

Blog the installation

This is a good issue for somebody new to the project. All you have to do is install the project and set up a poll... but you have to write it up in a blog post. This will improve both our documentation and our outreach. Also, you'll get to see the poll results on some issue that interests you!

Integrating social authentication

It'd be nice to integrate social authentication that would allow users with Google/Facebook/Twitter accounts to login, (and probably vote) without requiring them to create an account on the polls application. This may be a good resource.

Display text before poll options

Immediately before the options, display text "Choose as many options as you wish." This will reinforce the concept of approval voting.

Permit write-in option

Participants, when viewing the selection options within a poll, can add an additional option by typing it in and select that option if they choose. This feature should be able to be turned on or off by the poll administrator.

Better Error Response When New Question Is Blank

Currently, if you submit a new question with blank question text, the http response is just "You have to ask a question!"; no proper html markup, no styling, no links to continue (you have to go back).

Should return a proper page instead.

Adding a local_settings.py file

Would it be a good idea to import our local settings from a local_settings.py file into the main settings.py ? I find it very useful while developing (specifically the EMAIL_* related settings for registration which shouldn't be committed into settings.py)

We could do either 1 or 2 depending on what is agreeable.

  1. Overwriting variables - import variables from local_settings.py into settings.py at the end which would overwrite the values. (http://stackoverflow.com/questions/4909958/django-local-settings). I prefer this since it is straightforward.
  2. Extending variables - import settings into local_settings.py so that the variables in the settings file could be extended (https://gist.github.com/burnash/e60351e2696f4d17a466)

Also, adding local_settings.py to .gitignore. This way we could also switch DEBUG=True in the local_settings.py file.

Please let me know your views.

Thanks!

Add an account information page for a user

The username at the bottom of the panel could link to the user's account information - which includes some useful statistics about the user:

  1. Member since (date)
  2. Last login (date)
  3. Total number of polls created (and a link to them).
  4. Change username and/or email.
  5. Change password. (Adding this requirement to another ticket)
  6. Opt in/out for newsletter subscription. (After #33 is implemented)

... and any other information that might be useful.

Sending email asynchronously

Noticed that django by default (django.core.mail) waits for the email to be sent before navigating to the 'email sent' confirmation page. As a result, the application blocks for 2-3 minutes until the email is sent. Perhaps we should look into queuing the mail request or using another thread so that the user is not forced to wait on a specific page (registration, password reset) while the email is being sent. This post on stackoverflow outlines a couple of options.

Thanks!

Upgrade Django

We started this project with Django 1.5. 1.7 is available now; we should upgrade and make sure everything still works.

Show how many people have voted

Currently, the poll results only display the results in terms of votes and ballots, perhaps it could explicitly mention the number of people voted in the poll.

Allow More Than 8 Options In a Question

Currently the new question form is hard-coded to 8 candidate options.

Make it so you can have arbitrarily more than that.

(I'm thinking a button and a bit of javascript to add another text box.)

Test failure

I am running into the following issue while running the test suite. Seems like the DetailView and ResultsView are not handling the case with the future published date for a poll.

 Creating test database for alias 'default'...
  .....F..........
 ======================================================================
 FAIL: test_detail_view_with_a_future_poll (approval_polls.tests.PollDetailTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/rupal/dev/volunteer/forks/electology/approval_frame/approval_polls/tests.py", line 106, in test_detail_view_with_a_future_poll
    self.assertEqual(response.status_code, 404)
AssertionError: 200 != 404                                                                                                                                              

----------------------------------------------------------------------                                                                                                  
Ran 17 tests in 0.958s                                                                                                                                                  

FAILED (failures=1)
Destroying test database for alias 'default'...

Fix the master branch

Currently the first step of installation as given in the README python manage.py syncdb fails. Either the README or the branch needs to be fixed.

The error is

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 354, in execute
    django.setup()
  File "/usr/local/lib/python2.7/dist-packages/django/__init__.py", line 21, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/usr/local/lib/python2.7/dist-packages/django/apps/registry.py", line 85, in populate
    app_config = AppConfig.create(entry)
  File "/usr/local/lib/python2.7/dist-packages/django/apps/config.py", line 87, in create
    module = import_module(entry)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
ImportError: No module named registration

Long Questions Scroll the Main Page

8 questions per page, but if any of them wrap to a second line, it scrolls in the current frame size.

(I think there's some CSS that will automatically put '...' if an item exceeds a maximum size.)

Display datetimes in the user's system timezone

The default TIME_ZONE as set in the settings file is 'America/Los_Angeles' resulting in all dates and times being rendered in this particular timezone (irrespective of the user's timezone) . (Thanks @kushankr for pointing this out!) . Thus the dates and times displayed in the home page can be quite confusing to the user.

We would like all dates and times to be rendered in the user's timezone automatically without having the user select his/her timezone during registration. As extensively discussed in #75 we might need to use some client side Javascript library (like jstz) to help us set the app TIME_ZONE to the user's system timezone. Also, as recommended widely - setting TIME_ZONE='UTC' in settings.py. In addition, also add the appropriate timezone abbreviation (PST, IST, EST) whenever displaying datetimes.

Leading option has different color

Allow the poll to be configured to display the option with the leading number of votes in a different color.
This option could be added to the 'Poll Settings' panel while creating a new poll.

Collect Ballot Data for Correlations and Auditing

Only the total number of ballots cast on a question and the total number of approvals of each choice are kept.

Collect the choices approved by each ballot instead.

(models.py has a starting point commented out)

New base template/styling used inconsistently

We started using a new base template (currently called public_base); major identifiable difference is the CES logo being at the bottom of the screen instead of the top.

But it's being used inconsistently.

-Is there a reason we need two templates? Or can we combine them into one? (If one, let's go with the name 'base'.)

-Is there any reason we can't move the attending css in public_base in with the rest of the css?

hAKathon Broke Tests!

We were working quickly; changes to graphical elements broke several tests for viewing poll results.

Allow for Some Kind of Authentication to prevent Ballot Stuffing

Currently, nothing limits anyone from voting as many times as they want on anything.

Restrict that. (Configurable by poll.) Some possibilities (implement any or all):

Just a friendly cookie: "Hey, you already voted on this."
User accounts (verify by email?)
reCaptcha
OpenAuth
Question ids just increment. How about adding a secret key to get in (equiv. to gDocs "anyone who knows the url"?)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.