freeCodeCamp / chapter

A self-hosted event management tool for nonprofits

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Shared Profile Data & Auth Across Organizations

kognise opened this issue · comments

From a UX perspective, we probably want to make the experience for users who just want to RSVP to events as streamlined and possible. One thing that imo should be considered is user account management. With the current design, users have to create and manage separate accounts across all Chapter instances they're signed up to. This could get tedious.

I think we should have a conversation about possible solutions to this, I'm not very experienced with decentralization in general but I think we could implement some sort of SSO. This would also enable syncing user account details and interests across instances.

One network that solves this exceptionally well is Stack Exchange - we could look into how they do this. I haven't done a lot of research but I think they use something OpenID-related.

I'm open to learn new things!

https://blockstack.org/ Might be good for this. See how it is implemented in this project (Found on ProductHunt a while ago)

https://arcaneoffice.com/

@AntonioErdeljac BlockStack looks great, but it seems like users would have to create an account with them first. This might not be a very good experience, especially for users who are less technical.

But definitely something to consider.

https://auth0.com seems like a good alternative, at least for the MVP

Not very well-thought-out auth solution idea:

  • User signs up to a Chapter instance with their email/password
  • That instance gives them an id, like user@chapter.blah.com
  • When the user wants to log into a different instance, they just enter their id
  • They're redirected to a page on the Chapter instance they originally signed up on and then redirected back once once they enter their password

One glaring problem with this is that if the instance a user originally signed up on shuts down all their data goes poof across all instances. So obviously this isn't the perfect solution, but it's something we could work off of.

@mmiszy Auth0 is still very much centralized, and to solve the problems I mentioned freeCodeCamp would have to give out Auth0 creds which isn't a very good plan security-wise.

Things we can learn from:

  • Solid/BlockStack
  • Stack Exchange
  • Mastodon

I'm imagining Chapter as almost the "Mastodon of Meetup groups" - what do y'all think?

We could design the API so that employing a third-party SSO server is just a configuration change. Then it would be irrelevant which SSO provider is used or if Free Code Camp/Chapter deploys their own centralized SSO server in the future.

I believe the goal of the MVP should be to build a single working instance.

@mmiszy Agreed. I just wanted to bring this up now because it is definitely something we should consider in the long run.

Hopefully we'll spare users the need to create an account with a username and password. I'd rather an experience along these lines:

  1. Visit the site
  2. Decide to join up/register
  3. Have the option to create an account through email (sent an email link to create a user account) or a social provider (Twitter, GitHub, ...)

Critical for me, is that users can sign up without having to create a new password if they're already known to a trusted provider.

@bernhard-hofmann 100% agreed!!! I'm trying to brainstorm what the trusted entity is.

Github.com/amark/gun us a decentralized DB that has a decentralized user system. It wouldn’t matter what instance you signed up from, as user data is encrypted and can be shared between instances.

@Dletta Gun looks very interesting, I think this is a definite possibility for Chapter! I don't know enough about it yet to vouch for it, though.

@kognise, I have used it on a few hobby projects and the decentralized/ federated reddit clone notabug.io is using the technology to power it.

I also like the idea of not needing a login to attend an event, but spam sucks for chapters too

I recently joined DEV and their login system works through Twitter/Github.

Of course, this is not the easiest idea, but using an external media service could help us authenticate these users and not worry so much about possible spam from just being able to RVSP without an account.

Some form of auth -even if basic- is important.

DEV works great, but the difference between DEV and Chapter is that Chapter is supposed to be completely decentralized (anyone can spin up their own instance).

Edit: Sorry, I misread your comment. Yeah, I also believe that adding the possibility to log in with 3rd party providers such as GitHub, Facebook or Twitter is crucial for good UX.

Why not just use firebase for all the social auth? I think the onboarding process for both sides ie organisations and attendees should be seemless.

@Utkarshbhimte Firebase Auth is a great solution for auth in general, but it isn't decentralized and that's the problem we're trying to tackle here - decentralized auth.

+1 for having social auth available to reduce friction, even if after/during authorization you ask (the user or the identity provider) for the user's email address so, if worst comes to worst, you can contact everyone and tell them to start using either password resets or magic links.

Between collecting (and verifying!) email address and allowing both email + password sign-in (passwords hashed via argon2i or sufficiently strong bcrypt) and social sign-in from multiple providers, with the ability to pick any/all per-chapter, that should give enough flexibility for chapter owners to decide what level of risk they want re: centralized login.

For those of y'all mentioning Mastodon, the last time I used it the authentication pieces, while decentralized, were not federated; I can't log into cybre.space with my mastodon.social or mastodon.network accounts (or vice versa).

You could build a federated auth system, such that each Chapter instance could serve as an OAuth/OIDC provider for third parties and a client for the same, but in order to do that you'd have to completely ignore the client authentication features built into OAuth 2, otherwise you'd end up with each instance needing to manually set up federated login client authentication with every other instance...which is a big enough hurdle that you'd just end up federating auth with a few bigger instances and in effect centralizing auth around those instances.

Wouldn't including federation as part of the MVP, add significant scope to the project?
It's a whole area of research that needs to be tried, tested, validated and scale and so on.

For an MVP, wouldn't using firebase or auth0 be better? they already allow for social login.

One last thing, implementing authentication is a difficult thing. It even has legal implications. If you keep any Personal Identifiable Information (Name, dob, etc), then some laws are going to start applying. When using third party services such as firebase or auth0, though the org hosting the instance of chapter would be custodians, at least that same org would trust the data is safe in a commercial auth provider.

+1 for GDPR consideration when road mapping where Chapter is headed

FWIW, I've already indicated these auth thoughts in #12 as part of the docs outline. It looks like most of us agree to have some sort of SSO system with social/github authorizations.

How about no password, no social login. You get the token mailed to you, like magic link in slack and that's how you login. I think it's good enough UX to start with.

Here is how we can make User Accounts login to any Chapter:

@Dletta thanks for notifying me of this!

Cross-posted from Discord:

  1. A new user shows up on any Chapter

  2. creates an account - internally in the browser a public/private keypair is generated (similar to what GitHub does for your SSH keys, except user doesn't need to know about it)

  3. This account's data and its keypair gets locally encrypted with a PBKDF2* combination of their password (this prevents brute force attacks by attackers)

  4. The encrypted account data is stored in the browser and can safely be backed up (associated by username) to many Chapter self-hosted instances without these instances being able to read private data (they cannot read the private key, etc. tho you can also have public data if desired)

  5. Now when that user shows up on any self-hosted Chapter instance, they can login by pulling by username key the encrypted blob from their browser or the replicated backups (I also have a method for easily & efficiently loading data from multiple sources [could build search on this too]).

  6. The password gets typed locally (password is never sent to any servers) and PBKDF2* function is calculated (prevents brute forcing), producing the derived AES256 key that can decrypt the private account data, and now we're logged in!

  7. Password changes are easy in this system (as long as user is already logged in, a new PBKDF2* salt+password is computed and re-encrypts the data)

  8. Password resets are also possible, but I usually DISALLOW the server from doing it, instead it is generated by 3 of 3 friends (or if no friends, could be the meetup organizer across 3 different meetups a user goes to), the system automatically generates a signed challenge from the password-reset-requesting user to these 3 people, who get notified and once approved, gets sent back to reset-requester and locally assembled into a backup decryption key to unlock the account.
    (Note: this does mean those 3 people could backdoor the account, but this is still safer than 1 server [and any worker managing the server] being able to backdoor any account, but yeah still good for these 3 people to be a friend or different meetup organizers)

* If you do not know what PBKDF2 is or how encryption works, I got you covered: We made these 1-min animated cartoon explainers that use cooking analogies to describe cryptographic security https://gun.eco/docs/Cartoon-Cryptography .

There you go! All the dirty details, but at the end of the day...

THE USER ONLY HAS TO KNOW A USERNAME/PASSWORD COMBO and that is it!

Their account is secure & portable on any Chapter.

Again, this system is already used in production on several sites, and we're even working with HackerNoon (code already committed, testing on dev/staging, but not launched as of time of this writing) on automatically using this login system for special author features.

If you want to read the follow-up Qs/discussions, check out this Discord link.

commented

How about no password, no social login. You get the token mailed to you, like magic link in slack and that's how you login. I think it's good enough UX to start with.

I've opened an issue about this

@amark this is all great, but how do users log in on other devices? Where is their profile information stored?

@nhsz great thinking! But either way, user data needs to be stored in a way that it's accessible across platforms ... I think

commented

Good point. Passwordless doesn't affect how we store user data, does it? 🤔

With any auth system you have to use the same email you used when you registered, so it should't be a problem, we just create a new user when someone enters a new email.

The first time you sign up, we create the user, then email you the link for login, like Slack does

@kognise @nhsz user logs in via regular username/password from any device. Sorry, I thought I emphasized this strongly.

The way we do it with GUN the ENCRYPTED blob is replicated & backed up across users's browsers/devices + Chapters (tho note: all Chapters DO NOT have to store all data, usually I'm only doing like a ~3 replication factor). GUN also automatically handles pulling/sourcing from multiple Chapters, so even if you're on a different/new Chapter it doesn't matter.

One alternate method is to have a centralized location for storing basic not-extremely-critical user data (e.g. name, email, auth tokens, bio). This data could be keyed by email (or email hash) so even if this single source is compromised, users could create a new account and retain their admin/organizer/etc. status.

Process for logging in or signing up:

  • User visits collective and clicks auth button
  • User enters email
  • Collective sends email to the Chapter Identity Provider (ChIP)
  • ChIP generates a temporary token and sends it back to the collective
  • Collective emails the user with a magic link containing the temporary token
  • User clicks on link in email which logs them in by setting a cookie

When a user wants to view/edit their private profile data:

  • Collective checks if they have a valid token with ChIP and gets/sets the data
  • Collective loads the correct view or redirects if they aren't logged in

When a user wants to visit a public page:

  • Collective loads the page normally
  • The page lazy loads non-private profile data client side

Diagram

This involves a centralized data source, but ChIP could technically be eventually replaced with a better system hopefully without breaking the collectives. Furthermore, the only info stored isn't business-critical and event data is still stored on individual collectives.

Either way, this could work well for at least an MVP. What are your thoughts on this kind of centralized identity provider architecture?

it is a huge nightmare to manage multi self-hosted apps all with same-login this way. Centralization just isn't a good approach, unless all the accounts are on the same host, which most apps are that way, but doesn't seem like Chapter would work well that way.

@amark my interest has been piqued, a quick question. What if the user is on a device they have never used before. For example like in a cyber cafe or they decide to use their buddies computer, how would they login in this case? Also take a case where they want to join a new chapter from said never before used device how would this be?

@mojo706 If he/she is connected to an instance that is also connected to other instances, it will reach out to the network of instances to ask whether this user has been seen before. Then fetch the blob and return it to the new device, where it can be decrypted with the password.

@mojo706, that's all that gundb is doing. Automatically replicates everything between users's browsers and chapters.

Really need to look on GUN, it's fantastic.

It doesn't matter if you accessing a known chapter from cyber cafe, or if you accessing new chapter. Your auth data is encrypted and stored on all chapters hosts (or I should say instances cuz everything is client javascript). Which isn't exactly true I think, because you can configure GUN what are the "main" peers, so every other instance will sync from them.
If new chapter is just created it will automatically sync everything needed.

@amark, I'm close, right? ;)

@amark With GunDB, how would this scenario work? A user signs up to chapter at chapter.foo.com, sets their profile information, etc. They turn off their computer after a good day of work, and head to a coffee shop with a different computer and sign in to chapter.bar.com with the same credentials.

I don't know if this weeds anything out, but Quincy's proposed vision statement may provide more clarity on possible options.

@kognise, that's basically the same question as the @mojo706's which I and @Dletta responded clearly. Sorry if it's not clear enough, there's pretty good docs on the https://gun.eco which don't take to much time to read and get the idea. Distributed decentralized in-browser/client-side (or everywhere javascript can run) graph database system.

@kognise Unless instances are somehow (websocket, webRTC) connected, login would not be universally available to those users. If they are connected to each other however it is available through replication even over multiple hops of nodes

@mojo706 @Dletta @tunnckoCore nice! spot on!

Yeah, I really love @QuincyLarson 's vision @allella mentions at #47 (comment) , however it will be extremely difficult to achieve with only Postgres (note: I love Postgres, it is probably the best database out there) due to the Master-Slave setups, and while I may be biased, I can confidently state that GUN is currently the only decentralized protocol that is production-ready enough (already has millions of monthly active users) to support this, as I am intimately familiar with this space/industry and various protocols limitations (including GUN's).

@kognise or also think about it as the websocket/webRTC/multicast/etc. connections form a DHT across browsers & Chapters, kinda like BitTorrent.

My concern is: if the organization has their own logging system, let's say Rotary International, you sign in to their site, if you go to their Chapter.rotary.org, would need to log in with different credentials? Or is their tools to Integrate them? @amark

@xarielx exactly, this is inevitable with centralized tech stack. Why I was explaining/offering how to do it differently, to make login be owned by the user, now they can reuse that login on any chapter and sync their (encrypted) data across them when needed.

@amark @xarielx We should not have any data leave the organization's central server. They should have full control of their data. We do not want a Disqus style "comment section that follows you from page to page" like situation, as then it just becomes another centralized platform that organizations will be skeptical of.

After we ship the MVP, we can consider adding some sort of discovery network that people can opt into. I imagine it would involve organizations voluntarily exposing endpoints to a "registry" of sorts that syncs users, organizations, events and other data.

I've added this to the roadmap.

@QuincyLarson any data leave the organization's central server.

@amark, I always thought that's one of the reasons going decentralized is hard - because laws & policies. This world has too much regulations.

@QuincyLarson We do not want a Disqus style "comment section that follows you from page to page" like situation, as then it just becomes another centralized platform that organizations will be skeptical of.

It's exactly like that, except that it won't be in a centralized place.

Want to add some points,

Password resets should be as frictionless as possible

(like github, facebook, whatever)

  1. Indicate you want password reset (obviously if you have NOT created an account with a 3rd party provider aka facebook/google/etc)
  2. fill in your email, to prevent "fishing" , the software should never answer "we don't know this email", but "if this email is registered an email will be sent to you with information how to reset your password"
  3. User received email with a link (includes a token int the url that is only time-limited validity),
  4. User clicks on the link and gets redirected to a password reset page
  5. Important: after successful password reset, all other previous tokens sent out for to reset passwords will be immediately invalidated on the server,

Ad5.) Sometimes emails can be slow and ppl use the password reset button as a "happy switch" in frustration, You cannot used the older reset-emails to reset your password.

Different provider account should identify the same user via same email

If someone logs in via a provider (maybe he created an account first, but is slow in remembering the password, and just "oh I will use my facebook account today", we can detect its the same person because we receive the "email address" info via the provider and we identify users solely by their email.

GDPR

GDPR was a big deal in our company last year, since the fines are stupendously hefty. But this only affect servers/companies on European soil.
I am not a lawyer but what it boils down to my tech team was:

  1. If a user request his/her info to be deleted, this needs to happen within 24h and it needs to be scrubbed completely (for chapter this means: all blogspot, evidence of participating in meetups etc)
  2. prove that the user data is secure enough (only VERY limited nr of people have access to DB where user info is stored).

Someone needs to talk to a lawyer about this, the legal paperwork is freely downloadable from the EC website, but at least we can put a proper legal disclaimer to indemnify FCC. (I think this is already covered by Apache 2 license)

SSO

I don't think there should be an SSO, this is just a single server, maybe hosting several chapters, prolly the closest thing to SSO is to have a user paspoort their identity to other chapters (within the same server instance). Its also easier to manage token wise since most likely different chapters would most likely be hosted on different subdomains. aka berlin.codeangels.de and hamburg.codeangels.de

Oh just to add auth0 has a free tire

  • 7000 free active users
  • unlimited logins

I think this would cover most uses cases of chapter, so I think its a good option use auth0 in MVP.
Also auth0 has some good standing so it would put at rest any worries ppl might with regard to privacy

@jacobbogers thanks for the points.

In many cases, like for GDPR, we can hopefully leverage FCC prior experience hosting people all over the world.

FCC auth is a single domain, as best I can tell, so I'm not sure their experience there will inform a solution for Chapter.

Also, the desire to not have to register a new account for every Chapter instance you encouter will surely have more debate, but for now it would seem the focus is on an MVP solution that doesn't entirely paint things into a cornr.

Do you see a near-term MVP solution that lends itself to the future problem of people wanting to access multiple servers. As much as I'd like to not sign up 5 times for 5 different Chapters, it seems I have 5 Slack accounts and 3 Basecamp accounts, so it's not entirely out of the ordinary to just register a new account if you're part of the minority that needs multiple accounts on the same service.

@allella hello
When I was speaking of a chapter I am talking about an entrance in the table chapters, (within the same docker instance), that's as far as I would take "SSO" (maybe that is already the intent for the MVP, correct me if I am wrong)

PS: maybe the chapter table could be renamed to franchise, because it is sharing the same name with the overall product)))

Near future user sharing

My idea of federating the the different "chapters" (as in the product) to enable cross user posting and rsvp without explicit signon , I was thinking of if PKI infrastructure could work, where chapters (the product) can opt to join into this federation.

FCC, creates a root CA and issues "sub" CA's to federated chapters who opt in to the federation

The individual federated chapters sign their user info with the specific key issued by FCC to them.

Other Chapters can verify the user (info + signature) has been signed by a key issued by FCC so they can accept the user to post/comments/RSVP

Just spitballing but I was thinking along these lines.

Thanks again for the notes. My feeling is this is all well beyond the MVP, but it's good to have ideas about what's possible.

Quincy has a vision about how this product will work so that will likely steer to what degree each "Organization" (a deployment / instance of Chapter) are concerned with other organizations.

You can see a situation where tightly coupling organizations will run into a wall if one organization is using an old version and others are using new versions and the syncing depends on everybody running the latest code. This could quickly break down and/or get real complicated if it's not built on a protocol that doesn't change.

Even if the organizations don't syndicate anything, it would seem 3rd party tools could be built to hit the APIs to fill in the gaps. For instance, in Greenville, SC we have an app that aggregates all the tech meetups from Meetup.com and Eventbrite and shows and shares the same through and API.

I'm expecting an organization and/or chapters within to be able to expose their events through the Chapter APIs so we can automate this promoting of events. This has nothing to do with user accounts, but it's a use case I'm expecting that involves pulling event data from the APIs of many Chapter organizations (FCC, Women Who Code, a local Chapter organization, etc).

We changed the "chapter" table from a more generic "groups" table to match it with our terminology I'm not sure "franchise" does much pro or con vs "chapter", but so I'd personally vote to leave it as is.
#47 (comment)

Still think Gun Db is a viable choice as it is a protocol first, which could be used to sync the data the instances wishes, out to other instances.

@allella you are welcome,

Thanks for the update on the table rename chapter -> groups, I did not know it was renamed.

My main contributing point for this MVP was Password resets should be as frictionless as possible part (The rest of my comments was more about on ongoing discussion on federation etc.)

I can make a PR -draft- for the authentication flow.

This issue is on the roadmap, which means we will get to it after our MVP. I will close this issue for now so we can focus on resolving our non-roadmap issues first.

For those who missed it. Here are the Nov 15th meeting decisions on an MVP for authentication, which is just a Google login integration to start.

Quincy put this conversation on the roadmap for after an MVP.

This conversation was continued at #305

Also, the use of "SSO" above is likely not in the context most were thinking.

The ability for a user to authenticate using their Google account is apparently using OAuth 2.0, and SSO / SAML is a different enterprise use case.

Chat from today's Chapter meeting.

Mihir Somani 2:29 PM
You mentioned that one of the benefits of using OAuth with social media is that it allows users to share the information about chapters/events easily since we already have the "details" of the social account.
But, I believe for this reason, we need to add support for Facebook OAuth as well since Google doesn't really have any popular social media platforms.
Quincy Larson 2:30 PM
Mihir thanks for your feedback. We may add Facebook auth in the future but Google Auth is the natural option because it has integrated calendar, and people are much more willing to create new gmail accounts than new Facebook accounts.
Saritta Hines 2:32 PM
I think using Facebook with OAuth has a negative connotation associated with it..as far as sharing data etc...Twitter would be a better option imo than FB
Mihir Soman 2:33 PM
I believe it's better to have both. passport.js is an amazing library which lets us add OAuth policies very easily and smoothly.

The main problem with having multiple auth options is people forget which one they used, and they often have different email addresses associated with different social media accounts. Passport is smart, but it isn't psychic.

The correct number of authentication options to offer is 1. freeCodeCamp made the mistake of offering many, and ever since then we get emails from angry people saying we lost their data when in fact they just accidentally signed in using a different social auth provider and created a duplicate account.