New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-User Environments - Authentication and ACLs/Policies #1276

Open
Azrael808 opened this Issue Dec 22, 2014 · 34 comments

Comments

Projects
None yet
8 participants
@Azrael808

Azrael808 commented Dec 22, 2014

Currently, there doesn't appear to be a way to set up TW5 in a multi-user environment; no user authentication and no way to restrict access to tiddlers (or bags of tiddlers).

After speaking with @Jermolene, I've been made aware of an ongoing effort to add this functionality to the project, but there's been little/no use case. Hopefully, I can bring the use case and some additional sysadmin-level help/knowledge to the project!

My use case is this: my team and I would like to use TW5 as a knowledge base, but one that we can invite external users to so they can benefit from the information stored within. We would like to at least be able to:

  • Have content that's completely private (i.e. just visible and editable by our team).
  • Have content that's been published (i.e. visible to all authenticated users), but is still only editable by our team.
  • Have content that can be contributed to by both our team and external users.

We would need to consider where user credentials are stored (LDAP?) as well.

I'm raising this ticket to get a discussion going around this topic, feel free to jump in and contribute if you're interested!

@tobibeer

This comment has been minimized.

Contributor

tobibeer commented Jan 1, 2015

This issue appears to be entirely centered around infrastructures CRUDing individual tiddlers. Currently, I see TiddlyWiki 5 talking to...

  1. a node.js server
  2. a TiddlyWeb server
  3. a google drive (via Google Apps Script in TiddlyDrive)

To which degree authentication layers and access controls can be implemented in either enviroment needs exploring. Any other server-side not mentioned?

Maybe @PoulStaugaard is interested in the necessary creating syncer module(s) that allow porting GieWiki to TiddlyWiki 5 and thus leverage Google App Engine as yet another tiddler store.

@RichShumaker

This comment has been minimized.

RichShumaker commented Jan 2, 2015

Another Rabbit Hole found. As I stated on the last GitHub thread.
I need a way to implement TW5 on a Raspberry Pi which would be a huge opportunity for TW5.
There are millions of RasPi's and having an easy way to add TW5 for a group using one would be very helpful.
TW5 is great for taking notes and keeping data stored so having it on a RasPi for a classroom would be very helpful for the students.
Since TiddlyWeb is based on Python and Python is the primary language on the RasPi I wonder if there might be a synergy for help on the RasPi side of things.

@Azrael808

This comment has been minimized.

Azrael808 commented Jan 12, 2015

If there's anything I can do to assist in the development of this feature, please let me know.

I have been working on spinning up TW5 as a node.js application in a Docker container, which makes it pretty easy for me to push this to Elastic Beanstalk if we want something that we can all work on. I am primarily a sysadmin, so I would be quite far out of my comfort zone trying to develop multi-user functionality myself, but I'm happy to lend a hand wherever; I just need to be pointed in the right direction!

@tobibeer

This comment has been minimized.

Contributor

tobibeer commented Jan 12, 2015

@Azrael808, could you perhaps publish an article somewhere on the details of what you have implemented, with a few screenshots / diagrams?

@Azrael808

This comment has been minimized.

Azrael808 commented Jan 12, 2015

@tobibeer - it's not particularly complex at the moment, just a single Docker container running TW5 on node.js. I've created a gist of the relevant files, which I hope is useful:

https://gist.github.com/Azrael808/8823aeb9608c23ec092d

Please let me know if you need additional info. :)

@tobibeer

This comment has been minimized.

Contributor

tobibeer commented Jan 12, 2015

The thing is, I'm not a *nix user atm, so the general concept of a "docker container" escapes me.

@Azrael808

This comment has been minimized.

Azrael808 commented Jan 12, 2015

@tobibeer ah, apologies... You can think of a container as a (very) lightweight virtual machine. It's not actually a VM, but an environment that's compartmentalised from the operating system at the kernel level.

The Dockerfile is used to build the container; each step in the file is executed in turn to build an image. The final line in that file (CMD) is what's executed when you run that particular container. In this case, it's a custom startup script (also in that gist) I quickly wrote to fire up TW5.

I am running this particular container locally atm, but because Elastic Beanstalk supports Docker now, it would be easy enough to get this running in the cloud. 😄

@Azrael808

This comment has been minimized.

Azrael808 commented Jan 12, 2015

Is the #tiddlywiki IRC channel used by many people here? It might be a good place to chat if we want to collaborate closely.

@tobibeer

This comment has been minimized.

Contributor

tobibeer commented Jan 12, 2015

IRC — I'm never there, but that's just me

@Azrael808

This comment has been minimized.

Azrael808 commented Jan 12, 2015

@tobibeer heh, no matter; I'm used to jumping into them because many of the tools/products I use often have one. 😄

WRT the multi-user stuff, something I was trying to figure out is if TW5 should maintain an internal list of users, or if this should be delegated to something like LDAP? I'm all for not re-inventing the wheel, so using an LDAP server makes sense to me. However, I could envision a situation where a less-techie individual might want to spin up a TW5 instance that supported multiple users.

Again, if it helps, I'm working on spinning up a directory server in EC2, which I'd be happy to test TW5 against once the necessary changes have been made.

@Azrael808

This comment has been minimized.

Azrael808 commented Feb 12, 2015

Update: over the past month or so, I have been working to automate the instantiation of one of the scenarios described in this thread. Specifically:

                     +------------------------------+
                     |         EC2 Instance         |
+--------------+     |   +-----+   +-------------+  |
|Client Browser| ----+-->|Nginx|-->|TW5 on NodeJS|  |
+--------------+     |   +-----+   +-------------+  |
                     |      |                       |
                     +------+-----------------------+
                            |
                    User Authentication
                         via LDAP
                            |     +------------------------------+
                            |     |         EC2 Instance         |
                            |     |     +--------------------+   |
                            +-----+---->|389 Directory Server|   |
                                  |     +--------------------+   |
                                  +------------------------------+

This was after a couple of conversations with @Jermolene about the best way(s) to implement a multi-user system for TW5. The above example hands off the authentication process to Nginx, which currently passes an Authorization header back to TW5 with each successfully authenticated request.

IDK enough about the process of coding a layer of access control in TW5 to know if the above information is enough for TiddlyWiki? Specifically, the Authorization header, which appears to simply be the user credentials encoded in base64.

I'm going to white-label my Chef cookbooks/recipes and get them up here on Github; @RichShumaker you might find these useful for instantiating a TW5 instance on a Pi. I actually have access to a couple at home, so I might give them a go.

@pmario

This comment has been minimized.

Contributor

pmario commented Feb 12, 2015

Interesting approach.

@Azrael808

This comment has been minimized.

Azrael808 commented Feb 18, 2015

Here's the Chef cookbook I promised: https://github.com/Azrael808/chef-tiddlywiki5

It still needs a bit of work, but I'll be sure to keep updating it as and when needed.

@sukima

This comment has been minimized.

Contributor

sukima commented Feb 18, 2015

I can imagine that (assuming that the nginx layer providing a Authorization is enough to validate the user's access to) then the node.js code for TW5 could easily filter out tiddlers which do or do not have a published metadata flag. It could also block POST or PUT requests to tiddlers that are filtered out.

Obviously this doesn't offer any kind of role base access control but it's enough to have a do or do not level of visibility to the data on a per tiddler basis.

PS: Love the ASCII Art @Azrael808

@Jermolene

This comment has been minimized.

Owner

Jermolene commented Feb 19, 2015

Hi @Azrael808 this is very, very cool.

IDK enough about the process of coding a layer of access control in TW5 to know if the above information is enough for TiddlyWiki? Specifically, the Authorization header, which appears to simply be the user credentials encoded in base64.

As @sukima implies, ideally TW5 would be able to extract a human readable username from the headers (and perhaps a displayname), and get a list of the groups/roles the user is assigned to. Do you think that would be possible?

But in terms of getting things working with what we've got for the simple initial scenario, presumably we could just store the authorization header values for each of your team members.

To set it up, we'll need two wiki folders: team and published. The tiddlywiki.info file for the team wiki folder would have an includeWikis field referencing the published wiki. There would also be a new authorizedUsers property containing an array of the authorization header values for the team members.

The HTTP server mechanism would be modified to perform security checks on each tiddler access according to the settings of the original wiki folder containing the tiddler. It would also handle assigning new tiddlers to the correct wiki folder. (All of this would be done by implementing the existing "bag" semantics of TiddlyWeb).

Then, we'd need a way for team members to move unpublished tiddlers into the published wiki.

I'm going to give the cookbook a try. New territory for me so I may ask lots of stupid questions over at https://github.com/Azrael808/chef-tiddlywiki5

@Azrael808

This comment has been minimized.

Azrael808 commented Feb 19, 2015

Thanks for the ASCII art love @sukima !

@Jermolene I will have a think about how we can expose the groups a user is a member of... I did realise this today that the only info TW5 would have access to in the above scenario is the user ID and their password. Maybe there's a way to have the group memberships extracted and added to header info... I'll do some digging.

Please, feel free to bother me... It'll be cool to flesh that TW5 cookbook out as and when people report issues/raise feature requests! One major thing I've noticed when testing the cookbook is that if you want to try the LDAP stuff, you'll want to have something already setup for the Nginx module to bind to... I am considering adding a recipe to the cookbook to spin up a test instance of 389 server, as that might help people who don't have access to such a thing.

@Jermolene

This comment has been minimized.

Owner

Jermolene commented Feb 19, 2015

One major thing I've noticed when testing the cookbook is that if you want to try the LDAP stuff, you'll want to have something already setup for the Nginx module to bind to... I am considering adding a recipe to the cookbook to spin up a test instance of 389 server, as that might help people who don't have access to such a thing.

Ah, that would be me - I don't have an LDAP server handy, so it would indeed be awesome if you were able to add a recipe that sets up a test instance with a couple of accounts.

@RichShumaker

This comment has been minimized.

RichShumaker commented Feb 19, 2015

I am interested in testing on my Raspberry Pi. I can easily set up Nginx and node.js on the RasPi and I can get TiddlyWiki 5 running as well(I have used LAMP not Nginx so hopefully I won't hit too many speed bumps).

From there I will be lost as to the next thing to set up. If you have any suggestions on things to read up on or places to learn about setting this up I would greatly appreciate that. Thank you very much for creating this.

Here are my 'user' ideas(I have not done much development just talked to developers)

  1. Dual keys for the server side and client side with a handshake before sending data.
  2. Perform the authorization as a separate TiddlyWiki 5 with encrypted data(that way if they ping the TW5 directly they see nothing without the password) - Once the original decryption key is created then it creates a 'cookie' in the browser until the next session.
    2a. A variant on this idea is a TW5 inside a TW5 something like a transclusion
  3. Obviously you have discussed this but I am not sure how to implement - User Levels so you can protect Tiddlers and TW's from unauthorized users - Read, Write, Delete(linux 777 style?)
  4. Create a 'protected' class or tiddler and those 'protected' tiddlers do not render - This is similar to Number 2 except it is all still the same TW with Tiddlers but TW knows not to show the 'special' tiddlers to the average person only to admins with the proper rights.
  5. Most systems have 2 sides, a user side and an admin side - Again this is similar to Number 2 as you would have 2 TiddlyWiki's or maybe just 2 views of the same TW. Again I am not sure how you would 'define' the Tiddlers. I can think of 2 or 3 ways using TAGS, field names & field values, and special Tiddler Names.

All of the ideas are spackle I am throwing at the wall to see if any stick. They are 'brainstorming' ideas as I don't do much code I am an advanced NOOB.

Your work on this is greatly appreciated and as I said earlier thank you very much for working on this.

Rich Shumaker

@Azrael808

This comment has been minimized.

Azrael808 commented Feb 23, 2015

@Jermolene et voila: https://github.com/Azrael808/chef-tiddlywiki5/tree/ldap_server

Hopefully that should get you a local installation with a directory server in the background... There's only one user atm:

Username: testuser
Password: Testing1234

@RichShumaker it sounds like you're on track to having this running on a Pi. Given that all Nginx is doing in my basic Chef recipe is acting as a proxy, any webserver will do (as you've noted). If you have any more questions though, please throw them my way: I'm a sysadmin first and foremost, so this is my area of expertise. 😄

@Azrael808

This comment has been minimized.

Azrael808 commented Feb 25, 2015

While researching form-based authentication in Nginx, I have happened across this post:

http://puyb.net/2012/12/authentication-for-nginx/

TL;DR - the author is using Nginx to host a bunch of web resources, with a single NodeJS application being used to handle authentication for them all.

This is quite a similar scenario to the one we have here for TW5; maybe a fork of his NodeJS application could be used to not only handle the LDAP auth, but pull out group membership information also and add that information to a cookie... Although, that could potentially be abused quite easily. Here's the Git repo for the authentication app as it stands currently:

https://github.com/Puyb/nginx-auth

Anyway, would love to get some thoughts/feedback on this; trying to keep as much of the authentication-level stuff out of TW5 as possible; maybe this is the solution?

@tobibeer

This comment has been minimized.

Contributor

tobibeer commented Feb 25, 2015

Fwiw, authentication seems one major issue where the "everything is a tiddler" approach seems fundamentally inappropriate... unless perhaps we could stuff them into local storage and read them from there as well.

@Azrael808

This comment has been minimized.

Azrael808 commented Feb 25, 2015

FYI: I have struggled today to modify the NodeJS auth application I linked to previously; I tried integrating this: https://www.npmjs.com/package/ldapauth

However, I found the examples difficult to understand and I couldn't tell what I was supposed to be replacing/augmenting within the nginx-auth application!

IDK if anybody here fancies giving this a go? In the mean time, I'm going to work on adding a backend storage recipe to my cookbook; using the CouchDB plugin.

@RichShumaker

This comment has been minimized.

RichShumaker commented Feb 25, 2015

Could a TW instance be created under node.js that is encrypted and is used for Users and Passwords?
The encryption is to keep people from directly linking to the user names and passwords and getting plain text data back. Also it is it's own separate TW as you don't want it 'included' in everyones TW.
The idea is to use TW as the back end database.
Then we could use TW ability to add and remove as the front end for the user management.
Also we could use either Tagging or Fields as the permissions to modify on a TW or Tiddler level.

Maybe when any TW loads there needs to be a check on this "User Password TW" to see if it is implemented. If that mechanism is not implemented it is ignored.

And unfortunately I do not have the technical expertise to create this.

Rich Shumaker

@Azrael808

This comment has been minimized.

Azrael808 commented Feb 26, 2015

@RichShumaker that would probably work well for an isolated TW5 installation, assuming all your points are accurate - I don't have enough knowledge about TW5 presently to say otherwise! 😄

The use case I was aiming for requires the use of an external directory service for user data because it's likely I'll be combining the TW5 installation with other applications/services, which will need something like LDAP/Active Directory for user management.

@RichShumaker

This comment has been minimized.

RichShumaker commented Feb 26, 2015

@Azrael808 That makes perfect sense and I understand why it wouldn't work in your environment. TW5 would have to be seen as an existing Db for whatever application you were using and TW5 does not have the 'hooks' that you get with most databases as it is not really a database.

@Jermolene

This comment has been minimized.

Owner

Jermolene commented Mar 15, 2015

@Azrael808 I'm finally trying https://github.com/Azrael808/chef-tiddlywiki5/tree/ldap_server, apologies for the delay.

I've got right to the end, where I can connect to http://tiddlywiki5.example.com/index.html, and see the text "It works!", but I can't figure out how to connect to the TiddlyWiki instance. Also, I wasn't sure how to safely stop the VM in VirtualBox; is there a polite shutdown?

Many thanks for your help.

@Azrael808

This comment has been minimized.

Azrael808 commented Mar 16, 2015

Hey @Jermolene I think I neglected to include an all important Vagrantfile setting: https://github.com/Azrael808/chef-tiddlywiki5/blob/ldap_auth/Vagrantfile#L41

Now you should be able to run vagrant up and have the VM present it's Nginx installation over port 8080: browsing to http://localhost:8080 should bring up the TW5 instance.

WRT managing Vagrant VMs:

vagrant halt - issues an ACPI soft-off, causing the machine to gracefully shut down.
vagrant suspend - pauses the VM.

@Jermolene

This comment has been minimized.

Owner

Jermolene commented Mar 16, 2015

Excellent, thanks @Azrael808.

I patched that line into the Vagrantfile of my fork, and then ran vagrant up. Visiting http://tiddlywiki5.com:8080 is now giving me a working instance, yay!

However, it's not saving changes, I think because the tiddlywiki.info file in the root of the wiki folder doesn't include the two plugins that are needed: "tiddlywiki/tiddlyweb" and "tiddlywiki/filesystem". See https://github.com/Jermolene/TiddlyWiki5/blob/master/editions/server/tiddlywiki.info for an example. I can patch that temporarily by SSH-ing into the vagrant instance.

How do I experiment with using the LDAP authentication?

@Jermolene

This comment has been minimized.

Owner

Jermolene commented Mar 16, 2015

@Azrael808 I edited /srv/tw5/shared/wiki/tiddlywiki.info via nano over SSH, and then did vagrant halt and vagrant up. I expected the TW5 instance to restart with the plugins I had added to tiddlywiki.info, but there was no change; just the $:/core plugin was loaded.

@Azrael808

This comment has been minimized.

Azrael808 commented Mar 16, 2015

Hah, I've been a complete fool and given you the wrong branch to work from...

https://github.com/Azrael808/chef-tiddlywiki5/tree/ldap_server

That should set you up nicely! 😄

@Azrael808

This comment has been minimized.

Azrael808 commented Mar 17, 2015

@Jermolene - I'm intrigued as to why those plugins you mentioned aren't installed by default. The recipe is pulling the code directly from your Github repo:

https://github.com/Azrael808/chef-tiddlywiki5/blob/ldap_server/recipes/nodejs.rb#L25

Maybe the issue lies in how the TW5 instance is being initialised?

https://github.com/Azrael808/chef-tiddlywiki5/blob/ldap_server/recipes/nodejs.rb#L30

Or with how the NodeJS application is started:

https://github.com/Azrael808/chef-tiddlywiki5/blob/ldap_server/recipes/nodejs.rb#L33

Any thoughts?

@tgrosinger

This comment has been minimized.

Contributor

tgrosinger commented Oct 27, 2015

@Azrael808 @Jermolene
It's been a while. What are you two up to in regards to this ticket? Any updates I could hear about before embarking down this path myself? I too am very interested in a multi-user story, especially the ability to have read-only tiddlers which I can edit while authenticated, but others can only view.

Thanks.

@BramChen

This comment has been minimized.

Contributor

BramChen commented Dec 10, 2015

Hi @Azrael808

Maybe the issue lies in how the TW5 instance is being initialised?

https://github.com/Azrael808/chef-tiddlywiki5/blob/ldap_server/recipes/nodejs.rb#L30

You need specify the server edition to be initialized by using command --init server, like this:

 migration_command "node tiddlywiki.js #{node['tiddlywiki5']['tw5_path']}/shared/wiki/ --init server"
@pmario

This comment has been minimized.

Contributor

pmario commented May 17, 2017

@Jermolene .. imo should be labeled "discussion" and "feature request"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment