Kinto / kinto.js

An Offline-First JavaScript Client for Kinto.
http://kintojs.readthedocs.io/
Other
319 stars 72 forks source link

Investigate local handling of permissions. #67

Open n1k0 opened 9 years ago

n1k0 commented 9 years ago

What should we provide as features/API for frontend developers regarding permissions in the client?

Thoughts? @leplatrem @Natim @almet

Natim commented 9 years ago

We should provide a share this record and share this collection feature. I think.

n1k0 commented 9 years ago

We should provide a share this record and share this collection feature. I think.

Indeed. Something like this would be convenient:

const db = new Kinto();
const tasks = db.collection("tasks");
tasks.share({scope: "public"}); // => https://…
tasks.share({scope: "<FxA_Token_Here>"}); // => https://…

If you guys have better ideas for the API, please shime in :)

Natim commented 9 years ago

I think we should stay closer to what the Kinto API provide in order to keep the same scope of functionality:

const db = new Kinto();
const tasks = db.collection("tasks");
tasks.permissions({"read": [Authenticated]}); // => https://…
tasks.permissions({"write": ["<kinto_user_id>"]}); // => https://…
Natim commented 9 years ago

There are three levels of permissions to handle here plus groups management.

We need Buckets permissions management:

const db = new Kinto("bills");
db.permissions({"read": [Authenticated]});

We need Collections permissions management:

const tasks = db.collection("tasks");
tasks.permissions({"write": ["<people_ids>"]});

We need Record permissions management:

tasks.recordPermissions("<record_id>", {"write": ["<people_ids>"]});
Natim commented 9 years ago

About group management, I have in mind something like:

const db = new Kinto("bills");
db.addGroup("readers", ["<peopleIds>"]);
db.addToGroup("readers", ["<peopleIds>"]);
db.removeFromGroup("readers", ["<peopleIds>"]);
db.deleteGroup("readers");
almet commented 9 years ago

I love how hoodie does it, they have .publish and .unpublish methods. We could probably use the same thing and pass it users or groups?

n1k0 commented 9 years ago

I'd rather use share/unshare here, as a synced collection is already published for the user.

almet commented 9 years ago

True. I prefer this naming :)

Natim commented 9 years ago

I think there are two different things:

The one things that is blocking us at the moment, if finding a way to get other users ids. (Note that we can also create them in URL tokens for them to access the data.)

ghost commented 8 years ago

I would like to +1 the need to handle (at minimum) item level permissions. I can handle container level permissions in my app requiring online access (only admins can do that anyway), but without being able to set item level permissions, I can't support offline at all.

To keep things simple, I would agree that just attaching the same permissions object that I would otherwise call the permissions API with seems easiest.

leplatrem commented 8 years ago

I think this can be closed since the permissions handling is now covered in kinto-client.js

n1k0 commented 8 years ago

We should probably expose the permissions in the record objects, but that would mean synchronizing them as well...

ghost commented 8 years ago

I would suggest you examine this from the perspective of your goals, rather than technical implementation.

My two cents. I know they are really hard issues to deal with. I have been struggling with the complexities of offline sync now for a while and it is really tough.

Natim commented 8 years ago

I know that PouchDB use IndexedDB when possible and fallback for other browser that doesn't support it yet. That's something we are opened to do. We do not have a usecase ourselves for now.

I know that kinto-client and kinto.js doesn't supports Safari because of missing fetch support as well.

Offline first and permissions are not really related IMHO.

Permissions are for server side records only, on client side you have permission on everything you've got locally.

When you want to add permission on records you want an acknowledgement that it has been done.

Can you explain me in which case your application won't be offline first if the permission is done directly with the server without an offline first approach?

ghost commented 8 years ago

Use Case #1 - User Experience between Read/Write I have synced a bunch of content locally. The content has synched locally because I have read access, but maybe not write access. I am working offline on some content. It would not be a very good user experience to allow someone to edit content they should not have permission to edit, and then later, when they reconnect and sync, show them a bunch of errors that they edited content they don't have permission to. While there is no real security on the client, and yes, permissions have to be enforced on the server, knowledge of permissions on the client so the user interface can assist in keeping users from doing the wrong this is preferred. Yes, the application needs to be written to accommodate for permission errors on sync anyway, but without supporting this in the user interface, these types of permissions errors are going to happen much more frequently, and user's are not going to be happy about it.

Use Case #2 - Authoring/Editing and Assigning Permissions Offline This is in my mind, a VERY common use case. I have just authored some content offline and need to set some permissions to it for my team. Permissions are most commonly applied when content is created, so the application user interface probably has the permissions UI close to the content editor. If permissions are not synched and cached on the client then a) I can't show that user which groups or other users have existing permissions on the content, and b) I can't allow them to set those permissions at the time they are editing the content.

I have to respectfully disagree that offline first and permissions are not related. If you are doing single consumer applications where the local content is largely personal and only for the current user, then I can agree with you... but if you are writing business applications where groups and item-level permissions are used to coordinate content across teams... they are absolutely related.

Do you think knowing what the permissions to an item are is confidential, or a security risk? I personally don't. If a user doesn't have the permissions to change permissions on the server, they won't be able to circumvent any security on the client. In my mind, permissions on all elements (buckets, groups, collections and items) should be synched to the client to give the application UI an opportunity to help ensure a good user experience that respects permissions, even if it is not real security.

I understand if you don't have a use case for this, but for my applications, which are business/team focused, if Kinto.js doesn't sync and store permissions for elements, then I have to do it myself . Writing the UI for an application without being able to see (and attempt to enforce) current permissions on that item (even offline) is simply not going to be acceptable to my users.

I understand if you do not have a current use case for support anything other than IndexedDB. Since Firebox supports it, that is probably your primary mandate, but please understand how limiting that is for the just about everyone else that does not have the privilege of dictating which browsers the user is using. For me at least, the inability to support iPhone and iPad for a hybrid mobile application or inability to support Cordova, is a non-starter.

As a small independent developer this is getting so exhausting. Outside the US, the numbers show that web application usage is actually still quite a bit higher than mobile, but inside the US, mobile apps rule - capturing an increasing market share of overall web traffic. Given the choice to use a web application interface vs a mobile interface, users and businesses, at least in the US, are showing a clear preference for mobile, and are making significant purchasing decisions because of it.

For people like me that really want to support open source and open standards, web applications need to evolve to be able to support rich and seamless offline experiences. Sadly, the state of offline in HTML5/CSS/JavaScript is as bad today as it was 3 years ago. Mobile operating systems are not adding capabilities to allow installing web applications as home screen apps, and even if they did, mobile browsers and the community as a whole are not making progress to allows those applications to work effectively offline.

I am no longer planning on using Kinto.js :( I am now at a crossroads where I either build the sync experience myself so it can meet my requirements, or I abandon hybrid mobile and go web only. Both decisions are probably going to put me out of business before I have even really got started. I am already having to build far too much myself, and adding the sync experience on top of everything else would probably make a severe challenge an insurmountable challenge. If I abandon hybrid mobile then I probably can't compete in the US markets with a web-based product alone.

I am sorry for the rant. Good luck with Kinto :) The need in the community is certainly real, and it has a lot of potential.

Natim commented 8 years ago

It would not be a very good user experience to allow someone to edit content they should not have permission to edit

That's true, but if the person wants to edit a record, it probably means she needs the permission to do it, so she can edit, have an error and later ask for the correct permission.

She can also not be allowed to edit, ask the permission, resync and then be able to edit but in that case we loose the offline-first benefit.

How would you solve this, does having the permission object locally helps you do decide in a UX point of view to show the edit button?

Would a warning before editing makes sense? "You apparently don't have the permission to edit this record, ask the permission before doing so"

Btw, this also means we can have unsolvable conflicts between a local records that has been updated with no permission to edit and a remote one, in that case (403) we should assume a SERVER_WINS policy.

Natim commented 8 years ago

I am no longer planning on using Kinto.js :(

Too bad, I think you've made your point and our collaboration would be of great value. Good luck with your projects.

Natim commented 8 years ago

@chrismbeckett Before you go, if you have mockups to share about this offline-first permission handling, it would be great to see what kind of informations are needed.

A question I have, if you want to give people permissions, it means you need to sync the list of user locally too right?

almet commented 8 years ago

You could get the permissions alongside the data you're retrieving from the server (e.g. downloading permissions and data), and then having the Kinto.js library tell you whan you're trying to e.g. add an item to a collection you don't have write access to.

I believe that's what this issue was all about: what kind of API should we have to handle this permissions management?

ghost commented 8 years ago

I think what you guys are doing is very cool, your whole team are a bunch of smart developers, and open-sourcing it and actively working with a community is amazing and very much appreciated. I really like how you push to understand the use cases behind every feature/issue submitted - a great technique.

After 2 years of struggling to fold in various open-source and cloud services into my stack the single biggest lessons I have learned are:

To address these issues, I put my application development on hold a few weeks ago, and am about to launch my own open-source project: Kato-js. Its a micro-services framework for NodeJS that provides an abstraction layer for pub/sub, remote procedure call, and data storage so I can write my services code and no longer be directly dependent on anything. I am currently hacking out providers for a variety of technologies including WAMP, Socket.io, Express, Redis, Firebase, MongoDB. I should have docs in Gitbook completed this week and the framework soft-launched over the weekend.

I am still considering using the Kinto server as a storage service, but if I do, I will be writing my own microservice layer around rather than calling the API directly from the client.

Regardless, I have learned a lot from digging into Kinto (client and server), and a big kudos to the Kinto team for building something valuable.

Natim commented 8 years ago

I was having to manage the information about groups in a custom collection.

This was fixed in https://github.com/Kinto/kinto/issues/469

Its a micro-services framework for NodeJS that provides an abstraction layer for pub/sub, remote procedure call, and data storage so I can write my services code and no longer be directly dependent on anything.

This make me think about a discussion I had the other day with developer of ZetaPush

Regardless, I have learned a lot from digging into Kinto (client and server), and a big kudos to the Kinto team for building something valuable.

Thanks :)

almet commented 8 years ago

I don't understand how #435 fixes this issue ? Can you elaborate?

Natim commented 8 years ago

It fixes this issue because it let you set permission using kinto.js by using the kinto_client permission api.