sfu-natlang / lensingwikipedia

Lensing Wikipedia is an interface to visually browse through human history as represented in Wikipedia. This the source code that runs the website:
http://lensingwikipedia.cs.sfu.ca
Other
11 stars 4 forks source link

User accounts and saving queries #125

Closed avacariu closed 9 years ago

avacariu commented 9 years ago

The site currently has no user accounts, and it could be useful for users to be able to create an account to manage their settings, save/load queries and keep track of sessions.

Use cases

  1. User creates some queries and wants to save them so he can close the browser and come back to them later. If the queries are simple, the user can recreate them, but if they're more complicated the user would currently have to write down the constraints.
  2. User wants to create a new query, but would like to save the current query so she can compare the two later. It would be inconvenient (and likely slower) to require two separate windows/tabs to be opened for the two queries.
  3. User has created several related queries that they'd like to save so she can reference them later. This could be considered a "session".
  4. User has created an interesting set of queries (or session) that they'd like to share with another user. The receiver might have an account on the site or he might not.

    What's done so far

I've already implemented saving and loading queries in the query-management branch (although there are some issues). It can currently save the constraints and load them, but all the watchers are lost. With further work on the query module, this can definitely be made more robust.

I've implemented user accounts with email/password and account data several times so I can repurpose a lot of my existing code to create the these features.

What would need to be done

Any ideas / suggestions?

theq629 commented 9 years ago

How big can we expect the saved data to be?

avacariu commented 9 years ago

It should be pretty small. We'd only be saving the set of constraints.

theq629 commented 9 years ago

Is there any chance of storing it all in cookies to avoid more complex storage?

avacariu commented 9 years ago

I'm not sure that using cookies is going to be any less complex. It would just move all of the logic into the frontend.

Options for data storage on frontend:

It's certainly doable, but I'm not sure how reliable it would be. If the browser crashes, or the user accidentally closes the browser, would we lose all the data? We'd also need a bunch of code to manage relations between serialized JSON objects.

anoopsarkar commented 9 years ago

Having user accounts would be very useful to do an evaluation of some sort. If users can sign up and use the site, we could learn a lot about various design decisions in the interface and/or visualization.

theq629 commented 9 years ago

Well, if it's just for user convenience then I feel like cookies or web storage would be all right -- I don't think any query is currently hard enough to recreate that occasional crashes would be an issue, and it would surely at least save us having to keep track of separate users. But if tracking users for evaluation purposes is a main goal then we'd definitely need something else.

avacariu commented 9 years ago

Alright, I'll start working on it, then. I'll update when I have something basic working.

Current TODO

anoopsarkar commented 9 years ago

write up the design of the implementation of user accounts in this issue. will the account backend be in python? On Dec 29, 2014 11:32 AM, "Andrei Vacariu" notifications@github.com wrote:

Alright, I'll start working on it, then. I'll update when I have something basic working. Current TODO

  • Serve existing index.html
  • Modify index.html files to have a common base and extend it in the domains directory
  • Add user accounts

— Reply to this email directly or view it on GitHub https://github.com/sfu-natlang/lensingwikipedia/issues/125#issuecomment-68293778 .

avacariu commented 9 years ago

Yeah, it'll be in Python using the Flask framework, with session management done by Flask-Login, database connections using Flask-SQLAlchemy, and forms + CSRF protection handled by WTForms. I've got some similar code in my watchermelon repo (that includes both those plugins). I've got some different user accounts based on Google Oauth2 in my isitup repo.

Password hashing and checking will use the relevant functions in werkzeug.security.

In terms of the account tables, they'll have basically the same columns as listed in app/models.py, namely: id, name, email, salted password hash, and role. We can add more if we need to. SQLAlchemy lets you specify relationships and I'll add those in once all other stuff is done. There's an example of that in the models.py in isitup.

There'll be an account registration page asking for name/email/password, and it'll create an account object based on that and save it to the DB using SQLAlchemy.

In terms of logging in, there's going to be a login form. Once it's submitted, the backend will look up the email address in the DB and check the hash with the password. An example of this check is available here. If it's correct, Flask-Login provides a login_user() function which is used to set up the session for the user. After that, the logged in user is available in the current_user variable. There's also a logout_user() for logging out the user.

The login() and logout() views / functions in app/views.py are fairly self explanatory and are all you really need.

Flask-Login also provides a @login_required decorator to help with security, but it's pretty easy to check permissions on the current_user object. Passwords can be changed using another simple form once the user's logged in.

Verifying email addresses and resetting forgotten passwords would require access to a mail server or at least postfix/sendmail, so I'd leave that for last. I've implemented this for servokey.com, and it'll require 2 extra tables and views (the verified email address view is only a few lines to look up the string in the URL and update the status on User object; no frontend code).

KonceptGeek commented 9 years ago

Maybe before the work on user accounts can be started, we should merge the branches as doing it later could become hard due to conflicts. What do you guys think?

avacariu commented 9 years ago

I can implement the user accounts with a stub for where the index.html file would be, but it definitely would be nice to have everything merged for when I start serving index.html.

anoopsarkar commented 9 years ago

yes, let's do it this way: Max will merge to master first all of his changes including the storyline view, then Jasneet will push his cluster view and then Andrei will push the smoothed timeline view. Each is a new "tab" in the interface so they are fairly independent of each other. Jasneet's code also runs an index update like the backend cluster command. On Dec 29, 2014 8:06 PM, "Andrei Vacariu" notifications@github.com wrote:

I can implement the user accounts with a stub for where the index.html file would be, but it definitely would be nice to have everything merged for when I start serving index.html.

— Reply to this email directly or view it on GitHub https://github.com/sfu-natlang/lensingwikipedia/issues/125#issuecomment-68328462 .

theq629 commented 9 years ago

Does it seems like the current queries.js interface will work well enough for restoring queries (especially the recreating watchers thing), or do we need to consider any major changes there?

avacariu commented 9 years ago

It mostly works for restoring constraints, but watchers can't be recreated by queries.js. Check out this commit: 57169144197f6ec7c8e43c4dcbe4e2ae7582ee14

I think restoring watchers is doable without modifying the interface, but it would require changes from users of the interface. I think the best way would be for users of queries.js to recreate their own watchers based on the existing constraints, rather than the current method of creating a new one when setupX() is called. The queries.js code wouldn't be able to do this because of all the closures.

anoopsarkar commented 9 years ago

user accounts can be treated largely orthogonal to saving queries, IMO.

perhaps a change in queries.js could be considered first which would eventually fit in better with a user account to save those queries along with other information about user browsing. On Jan 2, 2015 12:15 PM, "Andrei Vacariu" notifications@github.com wrote:

It mostly works for restoring constraints, but watchers can't be recreated by queries.js. Check out this commit: 5716914 https://github.com/sfu-natlang/lensingwikipedia/commit/57169144197f6ec7c8e43c4dcbe4e2ae7582ee14

I think restoring watchers is doable without modifying the interface, but it would require changes from users of the interface. I think the best way would be for users of queries.js to recreate their own watchers based on the existing constraints, rather than the current method of creating a new one when setupX() is called. The queries.js code wouldn't be able to do this because of all the closures.

— Reply to this email directly or view it on GitHub https://github.com/sfu-natlang/lensingwikipedia/issues/125#issuecomment-68558252 .

avacariu commented 9 years ago

Since we're scrapping this idea, I'll close the issue. Check for references to this issue for ideas that supersede this one.