{"action":"created","issue":{"url":"https://api.github.com/repos/owncloud/client/issues/4845","repository_url":"https://api.github.com/repos/owncloud/client","labels_url":"https://api.github.com/repos/owncloud/client/issues/4845/labels{/name}","comments_url":"https://api.github.com/repos/owncloud/client/issues/4845/comments","events_url":"https://api.github.com/repos/owncloud/client/issues/4845/events","html_url":"https://github.com/owncloud/client/issues/4845","id":154932455,"number":4845,"title":"Adding ownCrypt : code reuse across clients, and best way to do it","user":{"login":"orion1024","id":6241740,"avatar_url":"https://avatars.githubusercontent.com/u/6241740?v=3","gravatar_id":"","url":"https://api.github.com/users/orion1024","html_url":"https://github.com/orion1024","followers_url":"https://api.github.com/users/orion1024/followers","following_url":"https://api.github.com/users/orion1024/following{/other_user}","gists_url":"https://api.github.com/users/orion1024/gists{/gist_id}","starred_url":"https://api.github.com/users/orion1024/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/orion1024/subscriptions","organizations_url":"https://api.github.com/users/orion1024/orgs","repos_url":"https://api.github.com/users/orion1024/repos","events_url":"https://api.github.com/users/orion1024/events{/privacy}","received_events_url":"https://api.github.com/users/orion1024/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/owncloud/client/labels/enhancement%20-%20needs%20design","name":"enhancement - needs design","color":"FF9900"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-05-15T21:48:49Z","updated_at":"2016-05-17T05:50:25Z","closed_at":null,"body":"I'm working on the structure of ownCrypt code, which aims to add client-side encryption.\r\n\r\nI'm currently pondering how to best design the code so that it can be easily reused across all clients : desktop, Android and iOS.\r\n\r\nI came up with some ideas, explained below, but I have hit a point where I think some insight from the teams would be very valuable. This time not only the desktop team, but also (and especially) from the mobile teams as well.\r\n@owncloud/android-developers @owncloud/ios-developers @owncloud/desktop-developers \r\n\r\nThis is how I approached the topic. Sorry if it's a bit lengthy, but i think a broader picture is needed to understand where I come from.\r\n\r\n1. Need to reuse code => separate _client-specific_ code from _pure ownCrypt_ code\r\n\r\n2. for pure ownCrypt code : build a library that can be reused across all clients. According to [this](http://www.skyscanner.net/blogs/developing-mobile-cross-platform-library-part-1-exploring) and [this](http://www.skyscanner.net/blogs/developing-mobile-cross-platform-library-part-2-c), the best option seems to be a C++ library, which is convenient since the desktop code already uses that language. \r\n**I would love to hear the mobile team opinions on these articles ; if they could confirm this is something feasible for the clients as they are today.**\r\n\r\n3. for client-specific code : it consists of 2 things as far as the sync logic is concerned (also, [here is a graph that explains how it would play out for the desktop client](https://cloud.airmail.fr/index.php/s/J6YZHmp1PtfHhva))\r\n\r\nA)\r\n\r\nClasses that calls ownCrypt public interfaces. For instance if I want to get a file : `ownCryptManager.getFILE(\"/foo/bar.pdf\");` . This call is supposed to handle all the decryption transparently, and returns to the sync client the plain-text file.\r\nInternally, ownCrypt will of course need to do more than just a GET : fetching the encryption key at the very least. Below a very simplified version of what needs to happen :\r\n```\r\nGETFILE(\"/foo/bar.pdf\");    // download encrypted file\r\nGETFILE(\"/.encryption-keys\");    // download encrypted keys\r\nmykey = DECRYPT_KEY(\".encryption-keys\", \"/foo/bar.pdf\");     // get the encryption key for foo/bar\r\nDECRYPT_FILE(\"/foo/bar.pdf\", mykey)     // decrypt the file\r\n```\r\nThis logic **needs to be in the library** : having to reproduce it across all 3 clients would be a nightmare. BUT the first 2 `GETFILE ` calls are client-specific.\r\nSo I would need B to maintain client-specific and ownCrypt code properly separated.\r\n\r\nB)\r\n\r\nFeeding the ownCrypt library with server primitives. In the example above, the `GETFILE ` method should be provided by the sync client. The easiest way to do that is to declare in the library an `AbstractServerInterface` class, that will specify all the methods that ownCrypt needs to do its work.\r\nSuch as : GETFILE, PUTFILE, LSDIR, MKDIR, DELETE, and so on. The library will use only the Abstract class.\r\nSo `GETFILE` would actually be `AbstractServerInterface::GETFILE` in the example above.\r\n\r\nAnd then each client can implement this interface in the way they see fit.\r\n\r\n\r\n\r\n\r\n4- **Last step, and this is where I'm stuck at the moment : whether to use a synchronous or asynchronous flow.** This question is relevant for calls to ownCrypt library (`ownCryptManager.getFILE(\"/foo/bar.pdf\");`) and for ownCrypt calls to the server interface (`AbstractServerInterface::GETFILE`)\r\n\r\nDesktop sync client is asynchronous (except for csync code)\r\nIOS sync client seems asynchronous (not sure, I don't know enough about IOS platform)\r\nAndroid client seems synchronous (same, I'm not sure)\r\n\r\nI'm currently leaning toward synchronous flow : it would make the library easier to code and maintain.\r\nI know I can make it fit in the desktop client asynchronous flow (this is already done with csync).\r\n**But I don't know how easy it is, or even if it's possible for the mobile clients ?**\r\n\r\nAsynchronous flow seems harder to implement, especially if we need additional wrapper classes for mobile clients. Using Qt across all clients could make that easier, but how good is Qt support on mobile platforms, and is that a good idea to begin with ?"},"comment":{"url":"https://api.github.com/repos/owncloud/client/issues/comments/219625610","html_url":"https://github.com/owncloud/client/issues/4845#issuecomment-219625610","issue_url":"https://api.github.com/repos/owncloud/client/issues/4845","id":219625610,"user":{"login":"rullzer","id":45821,"avatar_url":"https://avatars.githubusercontent.com/u/45821?v=3","gravatar_id":"","url":"https://api.github.com/users/rullzer","html_url":"https://github.com/rullzer","followers_url":"https://api.github.com/users/rullzer/followers","following_url":"https://api.github.com/users/rullzer/following{/other_user}","gists_url":"https://api.github.com/users/rullzer/gists{/gist_id}","starred_url":"https://api.github.com/users/rullzer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rullzer/subscriptions","organizations_url":"https://api.github.com/users/rullzer/orgs","repos_url":"https://api.github.com/users/rullzer/repos","events_url":"https://api.github.com/users/rullzer/events{/privacy}","received_events_url":"https://api.github.com/users/rullzer/received_events","type":"User","site_admin":false},"created_at":"2016-05-17T05:50:25Z","updated_at":"2016-05-17T05:50:25Z","body":"So I know it will be more work. But I think having native platform libraries is actually a better approach. This forces clear separation between the specification and the implementation.\r\n\r\nAlso while in theory write once and run on all sounds nice. In practice this will be a world of pain and and you'll end up with a lot of platform specific stuff anyways."}}