Hi our dear community,
I have tried to implement most of the functions for android-authenticator in
these
days(https://github.com/xwiki-contrib/android-authenticator/tree/feature-au….
But there are still a lot of detailed issues that need to be handled, like
security, volume, bad network state, cache and so on. I will try to deal
with these problems as soon as possible.
Here, this time, first I would like to discuss whether my implementation is
feasible enough, and second there are some other problems which need my
mentor and our community to help me. Thanks first of all.
1. *First introduce my design* and implementation of the synchronization and
authenticator.
1.1 *Synchronization:*
1.1.1Server->Client
There are two choices, including synchronizing all users or synchronizing
the users of selected groups. We use the same method for these two cases.
1) Add Update
Each time while calling the method SyncAdapter.onPerformSync, we get data
from server that has been modified since the last modified time. The data
that we get must be updated or added to the local contact2 database. Also
only these data need to be updated or added.
2) Delete
What data should be deleted from the local database? Because the server
does not return data that needs to be deleted, or maybe I don not know how
to query the deleted objects? :). Therefore now I just get all the user
IDs(HashMap<id,Ojbect>), traverse every user of the local database, find the
data that are not in the IDs map, and then delete it.
1.1.2 Detail:
For synchronizing all users:
1) Get all users as List<SearchResult> searchResults
2) Add Update: SearchResults include the last modified time. So according to
the time, we can filter what data should be updated or added. Then call the
function ContactManager.UpdateContacts to update local db.
3) Delete: searchResults already have user ids, so we can get the
IDs(HashMap<id,Ojbect>), then traverse the local database to find what data
should be deleted.
For synchronizing users of selected groups:
1) Get all selected group ids from local sharepreference xml, as
List<String> groupIds
2) Get the users’simple information(ObjectSummary) of each group one by one.
The ObjectSummary only has the user’id without the last modified time.
3) Add Update: According to the user ids, we get the last modified time for
each user, if before the given last sync time, continue; if after, we update
the user (but we need first get the detailed information of the user).
4) Delete: at second step, we get ObjectSummarys which include all the user
ids. So with these ids, we can find the data that should be deleted.
1.1.3 Client->Server
For this part, As we will first request and update the data in server while
editing the contact, Therefore, unnecessary synchronization mechanism is not
required. If the server’s response is that the editor has no permission, we
just return; if has been updated in the server, we will update the local
database at the same time.
1.2 *Authenticator:*
1.2.1 How to grant the permission for third party apps when they calling
getAuthToken? (Here, AuthToken is equal to Cookie.JessionId).
Basically, only 3 useful interfaces, like AddNewAccount, getAuthToken,
invalideAuthToken, are available for other third party android apps. The
most widely used is getAuthToken. How should we grant permission for
third-party apps? And when we grant? If adding XWiki account from one app,
then we can trust this app and grant the getAuthToken permission. But if
not, we should check the permission for every getAuthToken request of
third-party apps. So the checking logic code should be in the function
getAuthToken. But XWikiAuthenticator.getAuthToken will never be called if
AcountManager has cached the authtoken corresponding to AuthTokenType.
Therefore for first granting permission to third-party apps, the app should
not pass the same authTokenType when calling getAuthToken function. Or the
authToken value will be directly returned by AcountManager according to the
same AuthTokenType and the method getAuthToken will never be called. So
different apps should use the different AuthTokenType param to call the
function getAuthToken so that the <AuthTokenType, AuthToken> will not be
cached before granting permission for this app.
AuthTokenType=FULL_ACCESS+PackageName. So in XWikiAuthenticator.getAuthToken
function, if we check that the third-party app has not been granted, we
startActivity(GrantPermissionAcvivity) to grant permission for this package
by checking the user’s input password. And in addition the packageName can't
be forged because we can use the bundle option.getCallUID from binder to
verify the pakageName.
1.2.2 How to maintain authToken consistency for different third-party apps
with different AuthTokenType?
When will appear inconsistent? There are mainly two key cases, the authToken
is expired or the third-party app calls the invalideAuthToken function. Now,
I use the following solution to these problems.
1) When the authToken is expired, xwiki authenticator app will login again
and refresh all the cached authToken for every AuthTokenType.
2) When the third-party app calls the invalidAuthToken function, then
corresponding cache will be clear and getAuthToken will be called, then
XWikiHttp.login will be called to get a new token and refresh all the cached
authToken for every AuthTokenType.
3) So if any one finds the authToken has been expired, then login and
refresh all the cached authToken to maintain consistency. In addition, I
suggest that if the third-party app find the authToken is expired after a
period of time, then first call getAuthToken again. If the token is
different, then maybe authenticator has already update the token. If the
token is the same, just call invalidAuthToken and getAuthToken again.
2. *There are also some questions* that need help.
1) Is the above methods ok? How should I test effectively.? Or Maybe these
implementations exist more problems that I have overlooked?
2) Gradle or maven in Jenkins CI?
Now gradle is the default, great and perfect tool for building android app.
http://gradle.org/maven_vs_gradle/. And It's convenient for us to develop
android apps in android studio. Also it's very easy to integrate with
jenkins and maven repository, And I have already tried it and successfully
build my android apps in jenkins with
gradle.(https://github.com/xwiki-contrib/android-authenticator/blob/feature….
However If we use maven to build apps, it's not conducive to our
post-maintenance and integrated development for android developers. So could
I use gradle instead of maven to build our android apps? and can I use it in
the jenkins? or I have to use maven?
3) Should I create issues in JIRA? Should I include the JIRA issue when I
commit something ?
4) HttpClient or HttpUrlConnection? Or OkHttp/Volley library?
HttpClient(org.apache.http.client) has been deprecated and HttpUrlConnection
is a recommended way. So now I use this UrlConnection and write a simple
request library to communicate with server. Maybe I can use okhttp/volley
in the future as the way of http request to efficiently process data, but it
may increase the size of the application. But maybe it has more features
like cache, spy, connection pool and so on. The cache should be very useful
if large volume of users’ data have to be synchronized, Especially when
network is not very good and we request server again and again. Should I use
the okhttp library instead of my custom implementation of http library? Or
other serializable library like gson/xstream instead of the XmlPullParser?
5) Other ideas and contributions?
Maybe after completing this authenticator app, I could rewrite the
android-client app with android studio and update the application interfaces
and something out of date. Maybe I can do some translation in Chinese ?
Maybe I can update some document?
Or maybe I can solve some useful bugs in JIRA for XWiki platform or
extension? You know, now I'm not very familiar with such a huge code and
even do not know how to start after looking at some of the code. I still
need some time to explore. I think now maybe I should first well finish the
android-authenticator. :) And then be familiar with the entire code
architecture as soon as possible, and try to find and solve a small problem.
What do you think? Could anyone give me some tips?
Thanks,
Fitz Lee
--
View this message in context:
http://xwiki.475771.n2.nabble.com/Design-and-questions-about-Android-authen…
Sent from the XWiki- Dev mailing list archive at
Nabble.com.