├── .gitignore
├── LICENCE.txt
├── README.md
├── app
├── .gitignore
├── build.gradle
├── example.iml
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── io
│ │ └── oauth
│ │ └── dev
│ │ └── oauthiotest
│ │ ├── ChooseProviderDialog.java
│ │ ├── ImageDownloader.java
│ │ ├── InfosFragment.java
│ │ ├── InputDialog.java
│ │ ├── MainActivity.java
│ │ ├── SigninFragment.java
│ │ └── SignupFragment.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── drawable
│ ├── hdivider.xml
│ ├── logo_fb.png
│ ├── logo_gh.png
│ ├── logo_google.png
│ ├── logo_lin.png
│ ├── logo_tw.png
│ └── oauthio_text.png
│ ├── layout
│ ├── activity_main.xml
│ ├── dialog_input.xml
│ ├── dialog_providers.xml
│ ├── fragment_infos.xml
│ ├── fragment_signin.xml
│ └── fragment_signup.xml
│ ├── menu
│ └── menu_main.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── oauthio
├── .gitignore
├── build.gradle
├── oauthio.iml
├── proguard-rules.pro
└── src
└── main
├── AndroidManifest.xml
├── java
└── io
│ └── oauth
│ ├── OAuth.java
│ ├── OAuthCallback.java
│ ├── OAuthData.java
│ ├── OAuthDialog.java
│ ├── OAuthRequest.java
│ ├── OAuthUser.java
│ ├── OAuthUserCallback.java
│ ├── OAuthUsers.java
│ └── http
│ ├── OAuthJSONCallback.java
│ └── OAuthJSONRequest.java
└── res
└── values
└── strings.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /.gradle
2 | /.idea
3 | /.navigation
4 | /build
5 | /gradle
6 | /*.gradle
7 | /gradlew
8 | /gradlew.bat
9 | /*.iml
10 | /*.properties
11 | .DS_Store
12 |
--------------------------------------------------------------------------------
/LICENCE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | This project contains annotations derived from JCIP-ANNOTATIONS
179 | Copyright (c) 2005 Brian Goetz and Tim Peierls.
180 | See http://www.jcip.net and the Creative Commons Attribution License
181 | (http://creativecommons.org/licenses/by/2.5)
182 |
183 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OAuth.io Android SDK
2 |
3 | This is the official android sdk for [OAuth.io](https://oauth.io) !
4 |
5 | The OAuth.io android sdk allows you to use OAuth for your android application, and connect any OAuth provider [available on OAuth.io](https://oauth.io/providers).
6 |
7 | The full documentation is available at [docs.oauth.io](http://docs.oauth.io/?Android)
8 |
9 | The `example` folder contains a full app using the user management and sync with providers.
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | android {
3 | compileSdkVersion 21
4 | buildToolsVersion "21.1.2"
5 |
6 | defaultConfig {
7 | applicationId "io.oauth.dev.oauthiotest"
8 | minSdkVersion 15
9 | targetSdkVersion 21
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | sourceSets {
20 | oauthio {
21 | //manifest.srcFile 'AndroidManifest.xml'
22 | java.srcDirs = ['src']
23 | //res.srcDirs = ['res']
24 | }
25 | }
26 | }
27 |
28 | dependencies {
29 | compile fileTree(include: ['*.jar'], dir: 'libs')
30 | compile 'com.android.support:appcompat-v7:21.0.3'
31 | compile project(':oauthio')
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/app/example.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/bumpmann/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/io/oauth/dev/oauthiotest/ChooseProviderDialog.java:
--------------------------------------------------------------------------------
1 | package io.oauth.dev.oauthiotest;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.view.View;
6 | import android.widget.Button;
7 | import android.widget.ImageView;
8 |
9 | import java.util.Hashtable;
10 | import java.util.Iterator;
11 | import java.util.List;
12 | import java.util.Map;
13 |
14 | public class ChooseProviderDialog {
15 | private Dialog dialog;
16 | private View.OnClickListener clickListener;
17 | public String selected;
18 |
19 | private Map imgLogo = new Hashtable<>();
20 |
21 | public ChooseProviderDialog(Context ctx) {
22 | dialog = new Dialog(ctx);
23 | dialog.setContentView(R.layout.dialog_providers);
24 |
25 | View.OnClickListener providerOnClick = new View.OnClickListener() {
26 | @Override
27 | public void onClick(View v) {
28 | dialog.dismiss();
29 | selected = v.getTag().toString();
30 | if (clickListener != null)
31 | clickListener.onClick(v);
32 | }
33 | };
34 |
35 | imgLogo.put("facebook", (ImageView) dialog.findViewById(R.id.imageLogoFb));
36 | imgLogo.put("twitter", (ImageView) dialog.findViewById(R.id.imageLogoTw));
37 | imgLogo.put("google", (ImageView) dialog.findViewById(R.id.imageLogoGoogle));
38 | imgLogo.put("linkedin", (ImageView) dialog.findViewById(R.id.imageLogoLin));
39 | imgLogo.put("github", (ImageView) dialog.findViewById(R.id.imageLogoGh));
40 | ((Button) dialog.findViewById(R.id.cancelButton)).setOnClickListener(providerOnClick);
41 |
42 | Iterator it = imgLogo.values().iterator();
43 | while (it.hasNext()) {
44 | ImageView iv = (ImageView) it.next();
45 | iv.setOnClickListener(providerOnClick);
46 | }
47 | }
48 |
49 | public void setTitle(String title) {
50 | dialog.setTitle(title);
51 | }
52 |
53 | public void enableProviders(List providers) {
54 | Iterator it = providers.iterator();
55 | while (it.hasNext()) {
56 | imgLogo.get(it.next()).setVisibility(View.VISIBLE);
57 | }
58 | }
59 |
60 | public void enableProvider(String provider) {
61 | imgLogo.get(provider).setVisibility(View.VISIBLE);
62 | }
63 |
64 | public void setOnClickListener(View.OnClickListener listener) {
65 | clickListener = listener;
66 | }
67 |
68 | public void show() {
69 | dialog.show();
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/src/main/java/io/oauth/dev/oauthiotest/ImageDownloader.java:
--------------------------------------------------------------------------------
1 | package io.oauth.dev.oauthiotest;
2 |
3 |
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.os.AsyncTask;
7 | import android.widget.ImageView;
8 |
9 | import java.io.InputStream;
10 | import java.net.HttpURLConnection;
11 | import java.net.URL;
12 | import java.net.URLConnection;
13 |
14 | public class ImageDownloader {
15 | private ImageView iv;
16 | private String _url;
17 |
18 | public ImageDownloader(ImageView iview, String url) {
19 | iv = iview;
20 | _url = url;
21 |
22 | new ImageDownload().execute();
23 | }
24 |
25 | public class ImageDownload extends AsyncTask {
26 |
27 | protected Bitmap doInBackground(Void... params) {
28 | try {
29 | InputStream inputStream = null;
30 | URL url = new URL(_url);
31 | URLConnection conn = url.openConnection();
32 |
33 | HttpURLConnection httpConn = (HttpURLConnection) conn;
34 | httpConn.setRequestMethod("GET");
35 | httpConn.connect();
36 |
37 | if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
38 | inputStream = httpConn.getInputStream();
39 | BitmapFactory.Options bmOptions = new BitmapFactory.Options();
40 | bmOptions.inSampleSize = 1;
41 | Bitmap bm = BitmapFactory.decodeStream(inputStream, null, bmOptions);
42 | inputStream.close();
43 | return bm;
44 | }
45 | } catch (Exception e1) {
46 | System.err.println("exception while loading avatar: " + e1.getMessage());
47 | }
48 |
49 | return null;
50 | }
51 |
52 | protected void onPostExecute(Bitmap bm) {
53 | if (bm != null)
54 | iv.setImageBitmap(bm);
55 | }
56 |
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/io/oauth/dev/oauthiotest/InfosFragment.java:
--------------------------------------------------------------------------------
1 | package io.oauth.dev.oauthiotest;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ArrayAdapter;
9 | import android.widget.Button;
10 | import android.widget.ImageView;
11 | import android.widget.ListView;
12 | import android.widget.TextView;
13 |
14 | import java.util.ArrayList;
15 | import java.util.Iterator;
16 |
17 | import io.oauth.OAuth;
18 | import io.oauth.OAuthCallback;
19 | import io.oauth.OAuthData;
20 | import io.oauth.OAuthUser;
21 | import io.oauth.OAuthUserCallback;
22 | import io.oauth.OAuthUsers;
23 |
24 | public class InfosFragment extends Fragment implements OAuthCallback {
25 |
26 | private View rootView;
27 | private MainActivity activity;
28 | private OAuth oauth;
29 | private OAuthUsers users;
30 |
31 | public InfosFragment() { }
32 |
33 | @Override
34 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
35 | Bundle savedInstanceState) {
36 | activity = ((MainActivity) getActivity());
37 | oauth = activity.oauth;
38 | users = activity.users;
39 | activity.SetLogged(true);
40 |
41 | rootView = inflater.inflate(R.layout.fragment_infos, container, false);
42 |
43 | TextView txtFullname = (TextView) rootView.findViewById(R.id.textFullname);
44 | TextView txtEmail = (TextView) rootView.findViewById(R.id.textEmail);
45 |
46 | final OAuthUser id = users.getIdentity();
47 | txtFullname.setText(id.data.get("firstname") + " " + id.data.get("lastname"));
48 | txtEmail.setText(id.data.get("email"));
49 |
50 | Iterator prov = id.providers.iterator();
51 | ImageView synclogo;
52 | while (prov.hasNext()) {
53 | synclogo = (ImageView) rootView.findViewWithTag((String) prov.next());
54 | if (synclogo != null)
55 | synclogo.setVisibility(View.VISIBLE);
56 | }
57 |
58 | ListView listview = (ListView) rootView.findViewById(R.id.listView);
59 | ArrayList list = new ArrayList();
60 | Iterator it = id.data.keySet().iterator();
61 | while (it.hasNext()) {
62 | String key = (String) it.next();
63 | if (key != "id")
64 | list.add(key + ": " + id.data.get(key));
65 | }
66 | ArrayAdapter adapter = new ArrayAdapter<>(activity, android.R.layout.simple_list_item_1, list);
67 | listview.setAdapter(adapter);
68 |
69 | Button syncBtn = (Button) rootView.findViewById(R.id.syncBtn);
70 | syncBtn.setOnClickListener(new View.OnClickListener() {
71 | @Override
72 | public void onClick(View v) {
73 | final ChooseProviderDialog dlg = new ChooseProviderDialog(activity);
74 | dlg.setTitle("Sync with a provider");
75 | if (id.providers.indexOf("facebook") == -1) dlg.enableProvider("facebook");
76 | if (id.providers.indexOf("twitter") == -1) dlg.enableProvider("twitter");
77 | if (id.providers.indexOf("google") == -1) dlg.enableProvider("google");
78 | if (id.providers.indexOf("linkedin") == -1) dlg.enableProvider("linkedin");
79 | if (id.providers.indexOf("github") == -1) dlg.enableProvider("github");
80 | dlg.setOnClickListener(new View.OnClickListener() {
81 | @Override
82 | public void onClick(View v) {
83 | if ( ! dlg.selected.equals(""))
84 | oauth.popup(dlg.selected, InfosFragment.this);
85 | }
86 | });
87 | dlg.show();
88 | }
89 | });
90 |
91 | Button remBtn = (Button) rootView.findViewById(R.id.remBtn);
92 | remBtn.setOnClickListener(new View.OnClickListener() {
93 | @Override
94 | public void onClick(View v) {
95 | final ChooseProviderDialog dlg = new ChooseProviderDialog(activity);
96 | dlg.setTitle("Remove a linked provider");
97 | dlg.enableProviders(id.providers);
98 | dlg.setOnClickListener(new View.OnClickListener() {
99 | @Override
100 | public void onClick(View v) {
101 | if ( ! dlg.selected.equals("")) {
102 | id.removeProvider(dlg.selected, new OAuthUserCallback() {
103 | @Override
104 | public void onFinished() {
105 | ImageView logo = (ImageView) rootView.findViewWithTag(dlg.selected);
106 | logo.setVisibility(View.GONE);
107 | }
108 |
109 | @Override
110 | public void onError(String message) {
111 | activity.displayError(message);
112 | }
113 | });
114 | }
115 | }
116 | });
117 | dlg.show();
118 | }
119 | });
120 |
121 | ImageView avatar = (ImageView) rootView.findViewById(R.id.imageProfile);
122 | ImageDownloader imgdl = new ImageDownloader(avatar, id.data.get("avatar"));
123 |
124 | return rootView;
125 | }
126 |
127 | @Override
128 | public void onFinished(final OAuthData data) {
129 | if (data.status.equals("error"))
130 | activity.displayError(data.error);
131 | else
132 | users.getIdentity().addProvider(data, new OAuthUserCallback() {
133 | @Override
134 | public void onFinished() {
135 | ImageView logo = (ImageView) rootView.findViewWithTag(data.provider);
136 | logo.setVisibility(View.VISIBLE);
137 | }
138 |
139 | @Override
140 | public void onError(String message) {
141 | activity.displayError(message);
142 | }
143 | });
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/app/src/main/java/io/oauth/dev/oauthiotest/InputDialog.java:
--------------------------------------------------------------------------------
1 | package io.oauth.dev.oauthiotest;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.view.View;
6 | import android.widget.Button;
7 | import android.widget.EditText;
8 | import android.widget.ImageView;
9 |
10 | import java.util.Hashtable;
11 | import java.util.Iterator;
12 | import java.util.List;
13 | import java.util.Map;
14 |
15 | public class InputDialog {
16 | private Dialog dialog;
17 | private View.OnClickListener clickListener;
18 | public String value;
19 |
20 | private Map imgLogo = new Hashtable<>();
21 |
22 | public InputDialog(Context ctx) {
23 | dialog = new Dialog(ctx);
24 | dialog.setContentView(R.layout.dialog_input);
25 |
26 | Button btn = (Button) dialog.findViewById(R.id.button);
27 | btn.setOnClickListener(new View.OnClickListener() {
28 | @Override
29 | public void onClick(View v) {
30 | EditText editEmail = (EditText) dialog.findViewById(R.id.editEmail);
31 | value = editEmail.getText().toString();
32 | dialog.dismiss();
33 | if (clickListener != null)
34 | clickListener.onClick(v);
35 | }
36 | });
37 | }
38 |
39 | public void setTitle(String title) {
40 | dialog.setTitle(title);
41 | }
42 |
43 | public void setOnClickListener(View.OnClickListener listener) {
44 | clickListener = listener;
45 | }
46 |
47 | public void show() {
48 | dialog.show();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/io/oauth/dev/oauthiotest/MainActivity.java:
--------------------------------------------------------------------------------
1 | package io.oauth.dev.oauthiotest;
2 |
3 | import android.app.AlertDialog;
4 | import android.support.v4.app.FragmentActivity;
5 | import android.support.v4.app.Fragment;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.widget.Button;
9 |
10 | import io.oauth.OAuth;
11 | import io.oauth.OAuthUsers;
12 |
13 |
14 | public class MainActivity extends FragmentActivity {
15 |
16 | private Boolean isLogged = false;
17 | public OAuth oauth;
18 | public OAuthUsers users;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 |
24 | oauth = new OAuth(this);
25 | oauth.initialize("-HAiwR_DX9C0xT72AGcRaIcCFBo");
26 | users = new OAuthUsers(oauth);
27 |
28 | setContentView(R.layout.activity_main);
29 | if (savedInstanceState == null) {
30 | SetFragment(new SigninFragment());
31 | }
32 | }
33 |
34 | public void SetFragment(Fragment fragment) {
35 | getSupportFragmentManager().beginTransaction()
36 | .replace(R.id.container, fragment)
37 | .commit();
38 | }
39 |
40 | public void onSigninClick(View v) {
41 | SetFragment(new SigninFragment());
42 | }
43 |
44 | public void onSignupClick(View v) {
45 | if (isLogged)
46 | SetFragment(new SigninFragment());
47 | else
48 | SetFragment(new SignupFragment());
49 | }
50 |
51 | public void displayError(String message) {
52 | AlertDialog.Builder alert = new AlertDialog.Builder(this);
53 | alert.setMessage(message);
54 | alert.setTitle("Error");
55 | alert.show();
56 | }
57 |
58 | public void SetLogged(Boolean _isLogged) {
59 | isLogged = _isLogged;
60 | if (isLogged) {
61 | Button b = (Button) findViewById(R.id.mainbtn1);
62 | b.setVisibility(View.INVISIBLE);
63 | b = (Button) findViewById(R.id.mainbtn2);
64 | b.setText(getString(R.string.logout));
65 | } else {
66 | Button b = (Button) findViewById(R.id.mainbtn1);
67 | b.setVisibility(View.VISIBLE);
68 | b = (Button) findViewById(R.id.mainbtn2);
69 | b.setText(R.string.signup);
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/app/src/main/java/io/oauth/dev/oauthiotest/SigninFragment.java:
--------------------------------------------------------------------------------
1 | package io.oauth.dev.oauthiotest;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 | import android.widget.ImageView;
11 |
12 | import org.json.JSONObject;
13 |
14 | import java.util.Hashtable;
15 |
16 | import io.oauth.OAuth;
17 | import io.oauth.OAuthCallback;
18 | import io.oauth.OAuthData;
19 | import io.oauth.OAuthUserCallback;
20 | import io.oauth.OAuthUsers;
21 | import io.oauth.http.OAuthJSONCallback;
22 | import io.oauth.http.OAuthJSONRequest;
23 |
24 | public class SigninFragment extends Fragment implements OAuthCallback {
25 |
26 | private View rootView;
27 | private MainActivity activity;
28 | private OAuth oauth;
29 | private OAuthUsers users;
30 |
31 | public SigninFragment() { }
32 |
33 | @Override
34 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
35 | Bundle savedInstanceState) {
36 | activity = ((MainActivity) getActivity());
37 | oauth = activity.oauth;
38 | users = activity.users;
39 |
40 | rootView = inflater.inflate(R.layout.fragment_signin, container, false);
41 | Button bt_login = (Button) rootView.findViewById(R.id.loginbtn);
42 |
43 | bt_login.setOnClickListener( new View.OnClickListener() {
44 | @Override
45 | public void onClick(View view) {
46 | onLoginClick();
47 | }
48 | });
49 |
50 | View.OnClickListener providerOnClick = new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | onProviderClick(v.getTag().toString());
54 | }
55 | };
56 |
57 | ((ImageView) rootView.findViewById(R.id.imageLogoFb)).setOnClickListener(providerOnClick);
58 | ((ImageView) rootView.findViewById(R.id.imageLogoTw)).setOnClickListener(providerOnClick);
59 | ((ImageView) rootView.findViewById(R.id.imageLogoGoogle)).setOnClickListener(providerOnClick);
60 | ((ImageView) rootView.findViewById(R.id.imageLogoLin)).setOnClickListener(providerOnClick);
61 | ((ImageView) rootView.findViewById(R.id.imageLogoGh)).setOnClickListener(providerOnClick);
62 |
63 | activity.SetLogged(false);
64 |
65 | return rootView;
66 | }
67 |
68 | private void onLoginClick() {
69 | String email = ((EditText) rootView.findViewById(R.id.editEmail)).getText().toString();
70 | String password = ((EditText) rootView.findViewById(R.id.editPassword)).getText().toString();
71 | users.signin(email, password, new UserCallback(null));
72 | }
73 |
74 | private void onProviderClick(String provider) {
75 | oauth.popup(provider, SigninFragment.this);
76 | }
77 |
78 | @Override
79 | public void onFinished(OAuthData data) {
80 | if (data.status.equals("error"))
81 | activity.displayError(data.error);
82 | else
83 | users.signin(data, new UserCallback(data));
84 | }
85 |
86 | private class UserCallback implements OAuthUserCallback {
87 |
88 | public OAuthData data;
89 | public UserCallback(OAuthData _data) { data = _data; }
90 |
91 | @Override
92 | public void onFinished() {
93 | activity.SetFragment(new InfosFragment());
94 | }
95 |
96 | @Override
97 | public void onError(String message) {
98 | if (message.equals("Missing email")) {
99 | final InputDialog dlg = new InputDialog(activity);
100 | dlg.setTitle("Please setup your email to create your account.");
101 | dlg.setOnClickListener(new View.OnClickListener() {
102 | @Override
103 | public void onClick(View v) {
104 | Hashtable infos = new Hashtable();
105 | infos.put("email", dlg.value);
106 | users.signup(data, infos, new UserCallback(data));
107 | }
108 | });
109 | dlg.show();
110 | }
111 | else
112 | activity.displayError(message);
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/app/src/main/java/io/oauth/dev/oauthiotest/SignupFragment.java:
--------------------------------------------------------------------------------
1 | package io.oauth.dev.oauthiotest;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.os.Bundle;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 | import android.widget.ImageView;
11 |
12 | import java.util.HashMap;
13 | import java.util.Hashtable;
14 |
15 | import io.oauth.OAuth;
16 | import io.oauth.OAuthCallback;
17 | import io.oauth.OAuthData;
18 | import io.oauth.OAuthUserCallback;
19 | import io.oauth.OAuthUsers;
20 |
21 | public class SignupFragment extends Fragment implements OAuthCallback {
22 | private View rootView;
23 | private MainActivity activity;
24 | private OAuth oauth;
25 | private OAuthUsers users;
26 |
27 | public SignupFragment() { }
28 |
29 | @Override
30 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
31 | Bundle savedInstanceState) {
32 | activity = ((MainActivity) getActivity());
33 | oauth = activity.oauth;
34 | users = activity.users;
35 | activity.SetLogged(false);
36 |
37 | rootView = inflater.inflate(R.layout.fragment_signup, container, false);
38 | Button bt_create = (Button) rootView.findViewById(R.id.createbtn);
39 |
40 | bt_create.setOnClickListener(new View.OnClickListener() {
41 | @Override
42 | public void onClick(View view) { onCreateClick();
43 | }
44 | });
45 |
46 | View.OnClickListener providerOnClick = new View.OnClickListener() {
47 | @Override
48 | public void onClick(View v) {
49 | onProviderClick(v.getTag().toString());
50 | }
51 | };
52 |
53 | ((ImageView) rootView.findViewById(R.id.imageLogoFb)).setOnClickListener(providerOnClick);
54 | ((ImageView) rootView.findViewById(R.id.imageLogoTw)).setOnClickListener(providerOnClick);
55 | ((ImageView) rootView.findViewById(R.id.imageLogoGoogle)).setOnClickListener(providerOnClick);
56 | ((ImageView) rootView.findViewById(R.id.imageLogoLin)).setOnClickListener(providerOnClick);
57 | ((ImageView) rootView.findViewById(R.id.imageLogoGh)).setOnClickListener(providerOnClick);
58 |
59 | return rootView;
60 | }
61 |
62 | private void onCreateClick() {
63 | Hashtable infos = new Hashtable<>();
64 | infos.put("firstname", ((EditText) rootView.findViewById(R.id.editFirstname)).getText().toString());
65 | infos.put("lastname", ((EditText) rootView.findViewById(R.id.editLastname)).getText().toString());
66 | infos.put("email", ((EditText) rootView.findViewById(R.id.editEmail)).getText().toString());
67 | infos.put("password", ((EditText) rootView.findViewById(R.id.editPassword)).getText().toString());
68 |
69 | users.signup(infos, new UserCallback(null));
70 | }
71 |
72 | private void onProviderClick(String provider) {
73 | oauth.popup(provider, SignupFragment.this);
74 | }
75 |
76 | @Override
77 | public void onFinished(OAuthData data) {
78 | if (data.status.equals("error"))
79 | activity.displayError(data.error);
80 | else {
81 | Hashtable infos = new Hashtable<>();
82 | infos.put("firstname", ((EditText) rootView.findViewById(R.id.editFirstname)).getText().toString());
83 | infos.put("lastname", ((EditText) rootView.findViewById(R.id.editLastname)).getText().toString());
84 | infos.put("email", ((EditText) rootView.findViewById(R.id.editEmail)).getText().toString());
85 | users.signup(data, infos, new UserCallback(data));
86 | }
87 | }
88 |
89 | private class UserCallback implements OAuthUserCallback {
90 |
91 | public OAuthData data;
92 | public UserCallback(OAuthData _data) { data = _data; }
93 |
94 | @Override
95 | public void onFinished() {
96 | activity.SetFragment(new InfosFragment());
97 | }
98 |
99 | @Override
100 | public void onError(String message) {
101 | if (data != null && message.equals("Missing email")) {
102 | final InputDialog dlg = new InputDialog(activity);
103 | dlg.setTitle("Please setup your email");
104 | dlg.setOnClickListener(new View.OnClickListener() {
105 | @Override
106 | public void onClick(View v) {
107 | Hashtable infos = new Hashtable();
108 | infos.put("email", dlg.value);
109 | infos.put("firstname", ((EditText) rootView.findViewById(R.id.editFirstname)).getText().toString());
110 | infos.put("lastname", ((EditText) rootView.findViewById(R.id.editLastname)).getText().toString());
111 | users.signup(data, infos, new UserCallback(data));
112 | }
113 | });
114 | dlg.show();
115 | }
116 | else
117 | activity.displayError(message);
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/hdivider.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo_fb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable/logo_fb.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo_gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable/logo_gh.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo_google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable/logo_google.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo_lin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable/logo_lin.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo_tw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable/logo_tw.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/oauthio_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/oauth-io/oauth-android/51b4f2eccb062397a4c2ad4bf63f7acc64e19f02/app/src/main/res/drawable/oauthio_text.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
16 |
17 |
29 |
30 |
42 |
43 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_input.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_providers.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
15 |
16 |
25 |
26 |
35 |
36 |
45 |
46 |
55 |
56 |
64 |
65 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_infos.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
19 |
20 |
24 |
25 |
34 |
35 |
45 |
46 |
47 |
56 |
57 |
67 |
68 |
76 |
77 |
85 |
86 |
94 |
95 |
103 |
104 |
112 |
113 |
118 |
119 |
124 |
125 |
126 |
127 |
128 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_signin.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
15 |
16 |
26 |
27 |
28 |
29 |
38 |
39 |
49 |
50 |
56 |
57 |
63 |
64 |
70 |
71 |
77 |
78 |
84 |
85 |
86 |
87 |
88 |
97 |
98 |
108 |
109 |
119 |
120 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_signup.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
10 |
11 |
20 |
21 |
31 |
32 |
33 |
34 |
43 |
44 |
54 |
55 |
61 |
62 |
68 |
69 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
93 |
102 |
103 |
113 |
114 |
124 |
125 |
135 |
136 |
146 |
147 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | OAuthioTest
5 | Settings
6 | Signin
7 | Signup
8 | Sign in with
9 | Or with your email address
10 | Sign-in
11 | Sign-up
12 | Sign up with
13 | LOG IN
14 | Password
15 | Email
16 | Firstname
17 | Lastname
18 | CREATE ACCOUNT
19 | LOGOUT
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/oauthio/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/oauthio/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 21
5 | buildToolsVersion "21.1.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 15
9 | targetSdkVersion 21
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | compile fileTree(dir: 'libs', include: ['*.jar'])
23 | compile 'com.android.support:appcompat-v7:21.0.3'
24 | }
25 |
--------------------------------------------------------------------------------
/oauthio/oauthio.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/oauthio/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/bumpmann/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/oauthio/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuth.java:
--------------------------------------------------------------------------------
1 | package io.oauth;
2 | import java.io.UnsupportedEncodingException;
3 | import java.net.URLEncoder;
4 | import java.security.MessageDigest;
5 | import java.security.NoSuchAlgorithmException;
6 | import java.util.Date;
7 |
8 | import org.json.JSONException;
9 | import org.json.JSONObject;
10 |
11 | import android.content.Context;
12 | import android.util.Base64;
13 |
14 | public class OAuth {
15 |
16 | private String _key = "";
17 | private String oauthd_url = "https://oauth.io";
18 | private Context mContext = null;
19 |
20 | /**
21 | * Constructor
22 | */
23 | public OAuth(Context context)
24 | {
25 | mContext = context;
26 | }
27 |
28 | /**
29 | * Initialize the oauthd/oauth.io key
30 | *
31 | * @param key The public key to use
32 | */
33 | public void initialize(String key)
34 | {
35 | _key = key;
36 | }
37 |
38 | /**
39 | * @return The public key used
40 | */
41 | public String getPublicKey()
42 | {
43 | return _key;
44 | }
45 |
46 | /**
47 | * Set a oauthd URL. By default, this is set to https://oauth.io
48 | *
49 | * @param url The oauth daemon url to set. You can download oauthd at
50 | * https://github.com/oauth-io/oauthd
51 | */
52 | public void setOAuthdURL(String url)
53 | {
54 | oauthd_url = url;
55 | }
56 |
57 | /**
58 | * @return The current oauth daemon URL
59 | */
60 | public String getOAuthdURL()
61 | {
62 | return oauthd_url;
63 | }
64 |
65 | /**
66 | * Display a full screen authorization webview
67 | *
68 | * @param provider The provider's name. e.g. facebook, google, twitter...
69 | * @param callback An OAuthCallback implementing onFinished
70 | */
71 | public void popup (String provider, OAuthCallback callback)
72 | {
73 | JSONObject opts = new JSONObject();
74 | this.popup(provider, opts, callback);
75 | }
76 |
77 | /**
78 | * Display a full screen authorization webview
79 | *
80 | * @param provider The provider's name. e.g. facebook, google, twitter...
81 | * @param opts A JSONObject containing additional options.
82 | * It can contain an "authorize" JSONObject with additional query parameters
83 | * to pass to the authorize url.
84 | * @param callback An OAuthCallback implementing onFinished
85 | */
86 | public void popup (String provider, JSONObject opts, OAuthCallback callback)
87 | {
88 | if (_key == "") {
89 | OAuthData data = new OAuthData(this);
90 | data.status = "error";
91 | data.error = "Oauth must be initialized with a valid key";
92 | callback.onFinished(data);
93 | return;
94 | }
95 |
96 | if (opts.has("state") == false) {
97 | try {
98 | opts.putOpt("state", create_hash());
99 | opts.putOpt("state_type", "client");
100 | } catch (JSONException e) {
101 | }
102 | }
103 |
104 | String url = oauthd_url + "/auth/" + provider + "?mobile=true&k=" + _key;
105 | try {
106 | url += "&redirect_uri=" + URLEncoder.encode("http://localhost", "UTF-8");
107 | if (opts != null)
108 | url += "&opts=" + URLEncoder.encode(opts.toString(), "UTF-8");
109 | } catch (UnsupportedEncodingException e) {
110 | }
111 |
112 | OAuthDialog dial = new OAuthDialog(mContext, this, url);
113 | dial.setOAuthCallback(callback);
114 | dial.getData().provider = provider;
115 | dial.show();
116 | }
117 |
118 |
119 | /*
120 | ** Convert byte in String
121 | **
122 | */
123 | private String byteArrayToHexString(byte[] b) {
124 | String result = "";
125 | for (int i=0; i < b.length; i++)
126 | result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 );
127 | return result;
128 | }
129 |
130 |
131 | /*
132 | ** Encrypte byte in SHA1
133 | **
134 | */
135 | private String toSHA1(byte[] convertme) {
136 | MessageDigest md = null;
137 | try {
138 | md = MessageDigest.getInstance("SHA-1");
139 | }
140 | catch(NoSuchAlgorithmException e) {
141 | e.printStackTrace();
142 | }
143 | return byteArrayToHexString(md.digest(convertme));
144 | }
145 |
146 |
147 | /*
148 | ** Create the good hash for the request
149 | **
150 | */
151 | private String create_hash()
152 | {
153 | String hash = String.valueOf(new Date().getTime());
154 | hash += ':' + Math.floor(Math.random()*9999999);
155 | hash = toSHA1(hash.getBytes());
156 | hash = Base64.encodeToString(hash.getBytes(), Base64.DEFAULT);
157 | return hash.replaceAll("/+/g", "-").replaceAll("///g", "_").replaceAll("/=+$/", "");
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuthCallback.java:
--------------------------------------------------------------------------------
1 | package io.oauth;
2 |
3 | /**
4 | * The onFinished is called when the authorize dialog closes.
5 | */
6 | public interface OAuthCallback {
7 |
8 | /**
9 | * Called when the authorize dialog closes.
10 | *
11 | * @param data The authorize result: tokens, expiration, error message...
12 | */
13 | public abstract void onFinished(OAuthData data);
14 | }
15 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuthData.java:
--------------------------------------------------------------------------------
1 | package io.oauth;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.net.URLEncoder;
5 | import java.util.Hashtable;
6 | import java.util.Iterator;
7 |
8 | import org.json.JSONObject;
9 |
10 | import io.oauth.http.OAuthJSONCallback;
11 | import io.oauth.http.OAuthJSONRequest;
12 |
13 | /**
14 | * Class with all the information of the authentication
15 | */
16 | public class OAuthData {
17 |
18 | private OAuth _oauth;
19 |
20 | public String provider; /** name of the provider */
21 | public String state; /** state send */
22 | public String token; /** token received */
23 | public String secret; /** secret received (only in oauth1) */
24 | public String status; /** status of the request (succes, error, ....) */
25 | public String expires_in; /** if the token expires */
26 | public String error; /** error encountered */
27 | public JSONObject request; /** API request description */
28 |
29 | public OAuthData(OAuth o)
30 | {
31 | _oauth = o;
32 | }
33 |
34 | /**
35 | * Inject the authorization informations to an http request by providing an
36 | * OAuthRequest implementation. If the authorization method of the provider is OAuth 1,
37 | * the request will be proxified by oauth.io / oauthd. If it is OAuth 2, the request
38 | * is direct, using the API request description received beside the token.
39 | *
40 | * @param url The url can be absolute or relative to the provider's API base url.
41 | * @param setters OAuthRequest implementation to your http request.
42 | */
43 | public void http(String url, OAuthRequest setters) {
44 | if ("".equals(url)) return;
45 | setters.setOAuthData(this);
46 | try {
47 | if (token != null && secret != null) {
48 | if (request == null || ! request.has("url")) {
49 | setters.onError("The provider does have an API request description");
50 | return;
51 | }
52 | if (url.charAt(0) != '/')
53 | url = "/" + url;
54 | url = _oauth.getOAuthdURL() + "/request/" + provider + url;
55 | String oauthio_header = "k=" + _oauth.getPublicKey() + "&oauthv=1"
56 | + "&oauth_token=" + URLEncoder.encode(token, "UTF-8")
57 | + "&oauth_token_secret=" + URLEncoder.encode(secret, "UTF-8");
58 | setters.onSetURL(url);
59 | setters.onSetHeader("oauthio", oauthio_header);
60 | setters.onReady();
61 | }
62 | else if (token != null) {
63 | if ( ! url.matches("[a-z]{2,16}://.*"))
64 | {
65 | if (request == null || ! request.has("url")) {
66 | setters.onError("The provider does have an API request description");
67 | return;
68 | }
69 | if (url.charAt(0) != '/')
70 | url = "/" + url;
71 | url = request.getString("url") + url;
72 | }
73 |
74 | String qs = "";
75 | if (request.has("query")) {
76 | JSONObject query = request.getJSONObject("query");
77 | Iterator> keys = query.keys();
78 | while (keys.hasNext()) {
79 | String key = (String)keys.next();
80 | String val = (String)query.get(key);
81 | if (val.equals("{{token}}"))
82 | val = token;
83 | qs += "&" + URLEncoder.encode(key, "UTF-8") + "=" + URLEncoder.encode(val, "UTF-8");
84 | }
85 | }
86 |
87 | if (qs.length() > 0 && url.indexOf("?") == -1)
88 | qs = "?" + qs.substring(1);
89 | url += qs;
90 |
91 | setters.onSetURL(url);
92 |
93 | if (request.has("headers")) {
94 | JSONObject headers = request.getJSONObject("headers");
95 | Iterator> keys = headers.keys();
96 | while (keys.hasNext()) {
97 | String key = (String)keys.next();
98 | String val = (String)headers.get(key);
99 | if (val.equals("{{token}}"))
100 | val = token;
101 | setters.onSetHeader(key, val);
102 | }
103 | }
104 | setters.onReady();
105 | }
106 | else
107 | setters.onReady();
108 | }
109 | catch (Exception e) { setters.onError(e.getMessage()); }
110 | }
111 |
112 | public void http(final OAuthJSONRequest jsonRequest, final OAuthJSONCallback jsonCallback) {
113 | http(jsonRequest.httpReq.url, new OAuthRequest() {
114 | @Override
115 | public void onSetURL(String url) {
116 | jsonRequest.httpReq.url = url;
117 | }
118 |
119 | @Override
120 | public void onSetHeader(String header, String value) {
121 | if (jsonRequest.httpReq.headers == null)
122 | jsonRequest.httpReq.headers = new Hashtable();
123 | jsonRequest.httpReq.headers.put(header, value);
124 | }
125 |
126 | @Override
127 | public void onReady() {
128 | jsonRequest.execute(jsonCallback);
129 | }
130 |
131 | @Override
132 | public void onError(String message) {
133 | jsonCallback.onError(message);
134 | }
135 | });
136 | }
137 |
138 | public void me(OAuthJSONCallback callback) {
139 | String url = _oauth.getOAuthdURL() + "/auth/" + provider + "/me";
140 |
141 | String oauthio_header = "k=" + _oauth.getPublicKey();
142 | try {
143 | //url = "http://httpbin.org/get?" + URLEncoder.encode(url, "UTF-8");
144 | if (token != null && secret != null)
145 | oauthio_header += "&oauthv=1"
146 | + "&oauth_token=" + URLEncoder.encode(token, "UTF-8")
147 | + "&oauth_token_secret=" + URLEncoder.encode(secret, "UTF-8");
148 | else
149 | oauthio_header += "&access_token=" + URLEncoder.encode(token, "UTF-8");
150 | } catch (UnsupportedEncodingException e) {
151 | e.printStackTrace();
152 | }
153 |
154 | Hashtable headers = new Hashtable<>();
155 | headers.put("oauthio", oauthio_header);
156 |
157 | new OAuthJSONRequest().http(OAuthJSONRequest.HTTP_GET, url, null, headers, callback);
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuthDialog.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package io.oauth;
5 |
6 | import java.io.UnsupportedEncodingException;
7 | import java.net.URLDecoder;
8 |
9 | import org.json.JSONException;
10 | import org.json.JSONObject;
11 |
12 | import android.annotation.SuppressLint;
13 | import android.app.Dialog;
14 | import android.app.ProgressDialog;
15 | import android.content.Context;
16 | import android.graphics.Bitmap;
17 | import android.os.Bundle;
18 | import android.view.Display;
19 | import android.view.ViewGroup;
20 | import android.view.Window;
21 | import android.webkit.CookieManager;
22 | import android.webkit.CookieSyncManager;
23 | import android.webkit.WebChromeClient;
24 | import android.webkit.WebView;
25 | import android.webkit.WebViewClient;
26 | import android.widget.FrameLayout;
27 | import android.widget.LinearLayout;
28 |
29 | /**
30 | * A full screen OAuth dialog which contains a webview. This takes an authorize url
31 | * and returns a filled OAuthData in the OAuthCallback.onFinished method.
32 | */
33 | public class OAuthDialog extends Dialog {
34 |
35 | private ProgressDialog mProgress;
36 | private LinearLayout mLayout;
37 | private WebView mWebView;
38 | private OAuthData mdata;
39 | private OAuthCallback mListener;
40 | private String mUrl;
41 | private static final FrameLayout.LayoutParams MATCH = new FrameLayout.LayoutParams(
42 | ViewGroup.LayoutParams.MATCH_PARENT,
43 | ViewGroup.LayoutParams.MATCH_PARENT);
44 |
45 | /**
46 | * @param context
47 | * @param o The OAuth object which calls this dialog
48 | * @param url The authorize url
49 | */
50 | public OAuthDialog(Context context, OAuth o, String url) {
51 | super(context, android.R.style.Theme);
52 | mdata = new OAuthData(o);
53 | mUrl = url;
54 | }
55 |
56 | /**
57 | *
58 | * @return The used OAuthData
59 | */
60 | public OAuthData getData() {
61 | return mdata;
62 | }
63 |
64 | @SuppressWarnings("deprecation")
65 | @SuppressLint("SetJavaScriptEnabled")
66 | @Override
67 | /**
68 | * When the dialog is created, we add the webview and load the authorize url.
69 | */
70 | protected void onCreate(Bundle savedInstanceState) {
71 | super.onCreate(savedInstanceState);
72 |
73 | requestWindowFeature(Window.FEATURE_NO_TITLE);
74 |
75 | mProgress = new ProgressDialog(getContext());
76 | mProgress.requestWindowFeature(Window.FEATURE_NO_TITLE);
77 | mProgress.setMessage("Loading...");
78 |
79 | mLayout = new LinearLayout(getContext());
80 | mLayout.setOrientation(LinearLayout.VERTICAL);
81 |
82 | mWebView = new WebView(getContext());
83 | mWebView.setVerticalScrollBarEnabled(false);
84 | mWebView.setHorizontalScrollBarEnabled(false);
85 | mWebView.getSettings().setJavaScriptEnabled(true);
86 | mWebView.getSettings().setSupportZoom(false);
87 | mWebView.setLayoutParams(MATCH);
88 |
89 | mWebView.setWebViewClient(new OAuthWebViewClient());
90 | mWebView.setWebChromeClient(new WebChromeClient());
91 |
92 | mWebView.loadUrl(mUrl);
93 | mLayout.addView(mWebView);
94 |
95 | Display display = getWindow().getWindowManager().getDefaultDisplay();
96 | addContentView(mLayout, new FrameLayout.LayoutParams(display.getWidth() - 20, display.getHeight() - 20));
97 | CookieSyncManager.createInstance(getContext());
98 | CookieManager cookieManager = CookieManager.getInstance();
99 | cookieManager.removeAllCookie();
100 |
101 | }
102 |
103 | /**
104 | * Set the callback when the authorization ends.
105 | *
106 | * @param callback
107 | */
108 | public void setOAuthCallback(OAuthCallback callback) {
109 | mListener = callback;
110 | }
111 |
112 |
113 | private class OAuthWebViewClient extends WebViewClient {
114 |
115 | /*
116 | ** Manage if the url should be load or not, and get the result of the request
117 | **
118 | */
119 | @Override
120 | public boolean shouldOverrideUrlLoading(WebView view, String url)
121 | {
122 | String urldecode = null;
123 | try {
124 | urldecode = URLDecoder.decode(url, "UTF-8");
125 | } catch (UnsupportedEncodingException e) {
126 | mdata.status = "error";
127 | mdata.error = e.getMessage();
128 | }
129 | if ( ! urldecode.contains("#oauthio="))
130 | return false;
131 |
132 | int index = urldecode.indexOf("=");
133 | String json = urldecode.substring(0, index + 1);
134 | json = urldecode.replace(json, "");
135 | JSONObject jsonObj = null;
136 | try {
137 | jsonObj = new JSONObject(json);
138 | } catch (JSONException e) {
139 | mdata.status = "error";
140 | mdata.error = e.getMessage();
141 | }
142 | try {
143 | mdata.status = jsonObj.getString("status");
144 | if (mdata.status.contains("success"))
145 | {
146 | mdata.provider = jsonObj.getString("provider");
147 | mdata.state = jsonObj.getString("state");
148 | JSONObject data = jsonObj.getJSONObject("data");
149 | if (data.has("access_token"))
150 | mdata.token = data.getString("access_token");
151 | else if (data.has("oauth_token"))
152 | mdata.token = data.getString("oauth_token");
153 | if (data.has("oauth_token_secret"))
154 | mdata.secret = data.getString("oauth_token_secret");
155 | if (data.has("expires_in"))
156 | mdata.expires_in = data.getString("expires_in");
157 | if (data.has("request"))
158 | mdata.request = data.getJSONObject("request");
159 | }
160 | if (mdata.status.contains("error"))
161 | {
162 | mdata.error = jsonObj.getString("message");
163 | }
164 | } catch (JSONException e) {
165 | mdata.status = "error";
166 | mdata.error = e.getMessage();
167 | }
168 | mListener.onFinished(mdata);
169 | OAuthDialog.this.dismiss();
170 | return true;
171 | }
172 |
173 |
174 | /*
175 | ** Catch the error if an error occurs
176 | **
177 | */
178 | @Override
179 | public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
180 | {
181 | super.onReceivedError(view, errorCode, description, failingUrl);
182 | mdata.status = "error";
183 | mdata.error = description;
184 | mListener.onFinished(mdata);
185 | OAuthDialog.this.dismiss();
186 | }
187 |
188 |
189 | /*
190 | ** Display a dialog when the page start
191 | **
192 | */
193 | @Override
194 | public void onPageStarted(WebView view, String url, Bitmap favicon)
195 | {
196 | super.onPageStarted(view, url, favicon);
197 | mProgress.show();
198 | }
199 |
200 |
201 | /*
202 | ** Remove the dialog when the page finish loading
203 | **
204 | */
205 | @Override
206 | public void onPageFinished(WebView view, String url)
207 | {
208 | super.onPageFinished(view, url);
209 | mProgress.dismiss();
210 | }
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuthRequest.java:
--------------------------------------------------------------------------------
1 | package io.oauth;
2 |
3 | import io.oauth.OAuthData;
4 |
5 | /**
6 | * The OAuthRequest class contains abstract method you can implement to set your
7 | * http request's url and add headers to inject your oauth tokens.
8 | */
9 | public abstract class OAuthRequest {
10 | private OAuthData _oauth_data;
11 | protected Object data;
12 |
13 | public OAuthRequest() {
14 | }
15 | public OAuthRequest(Object _data) {
16 | data = _data;
17 | }
18 |
19 | /**
20 | * This method is called once the final url is returned.
21 | *
22 | * @param url The url to set to your http request
23 | */
24 | public abstract void onSetURL(String url);
25 |
26 | /**
27 | * This method is called for each header to add to the request.
28 | *
29 | * @param header The header's name to add
30 | * @param value The header's value to set
31 | */
32 | public abstract void onSetHeader(String header, String value);
33 |
34 | /**
35 | * This method is called if every other callback are successfully called
36 | */
37 | public void onReady() {}
38 |
39 | /**
40 | * This method is called if an error occured
41 | *
42 | * @param message The error's description
43 | */
44 | public void onError(String message) {}
45 |
46 | public void setOAuthData(OAuthData oauth_data) {
47 | _oauth_data = oauth_data;
48 | }
49 |
50 | public OAuthData getOAuthData() {
51 | return _oauth_data;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuthUser.java:
--------------------------------------------------------------------------------
1 | package io.oauth;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONException;
5 | import org.json.JSONObject;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Hashtable;
9 | import java.util.Iterator;
10 | import java.util.List;
11 | import java.util.Map;
12 |
13 | import io.oauth.http.OAuthJSONCallback;
14 | import io.oauth.http.OAuthJSONRequest;
15 |
16 | /**
17 | * An authenticated user
18 | */
19 | public class OAuthUser {
20 |
21 | private OAuth _oauth;
22 |
23 | public String token; /** The user' token */
24 | public List providers; /** List of providers linked to this account */
25 | public Map data; /** The raw user infos */
26 |
27 | public OAuthUser(OAuth o)
28 | {
29 | _oauth = o;
30 | providers = new ArrayList<>();
31 | data = new Hashtable<>();
32 | }
33 |
34 | public boolean isLogged() {
35 | return ! token.isEmpty();
36 | }
37 |
38 | public void refreshIdentity(final OAuthUserCallback callback) {
39 | if (token.isEmpty()) {
40 | callback.onFinished();
41 | return;
42 | }
43 |
44 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/user?k=" + _oauth.getPublicKey() + "&token=" + token;
45 |
46 | new OAuthJSONRequest().get(url, new OAuthJSONCallback() {
47 | @Override
48 | public void onFinished(JSONObject _data) {
49 | try {
50 | token = _data.getString("token");
51 | if(_data.has("user")) {
52 | JSONObject userObj = _data.getJSONObject("user");
53 | Iterator it = userObj.keys();
54 | while (it.hasNext()) {
55 | String key = it.next();
56 | data.put(key, userObj.get(key).toString());
57 | }
58 | }
59 | if(_data.has("providers")) {
60 | JSONArray providersArray = _data.getJSONArray("providers");
61 | for (int i = 0; i < providersArray.length(); i++) {
62 | providers.add(providersArray.getString(i));
63 | }
64 | }
65 | } catch (JSONException e) {
66 | callback.onError(e.getMessage());
67 | return;
68 | }
69 | callback.onFinished();
70 | }
71 |
72 | @Override
73 | public void onError(String message) {
74 | callback.onError(message);
75 | }
76 | });
77 | }
78 |
79 | public void saveIdentity(final OAuthUserCallback callback) {
80 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/user?k=" + _oauth.getPublicKey() + "&token=" + token;
81 |
82 | JSONObject postdata = new JSONObject();
83 | try {
84 | Iterator it = data.keySet().iterator();
85 | while (it.hasNext()) {
86 | String key = (String) it.next();
87 | postdata.put(key, data.get(key));
88 | }
89 | } catch (JSONException e) {
90 | callback.onError(e.getMessage());
91 | return;
92 | }
93 |
94 | new OAuthJSONRequest().get(url, new OAuthJSONCallback() {
95 | @Override
96 | public void onFinished(JSONObject data) {
97 | callback.onFinished();
98 | }
99 |
100 | @Override
101 | public void onError(String message) {
102 | callback.onError(message);
103 | }
104 | });
105 | }
106 |
107 | public boolean hasProvider(String provider) {
108 | return providers.indexOf(provider) != -1;
109 | }
110 |
111 | public void getProviders(final OAuthUserCallback callback) {
112 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/user/providers?k=" + _oauth.getPublicKey() + "&token=" + token;
113 |
114 | new OAuthJSONRequest().get(url, new OAuthJSONCallback() {
115 | @Override
116 | public void onFinished(JSONObject data) {
117 | providers.clear();
118 | JSONArray items = data.optJSONArray("items");
119 | for (int i = 0; i < items.length(); i++) {
120 | providers.add(items.optString(i));
121 | }
122 | callback.onFinished();
123 | }
124 |
125 | @Override
126 | public void onError(String message) {
127 | callback.onError(message);
128 | }
129 | });
130 | }
131 |
132 | public void addProvider(final OAuthData oauth_data, final OAuthUserCallback callback) {
133 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/user/providers?k=" + _oauth.getPublicKey() + "&token=" + token;
134 |
135 | JSONObject postdata = new JSONObject();
136 | try {
137 | if (oauth_data.token != null && oauth_data.secret != null) {
138 | postdata.put("oauth_token", oauth_data.token);
139 | postdata.put("oauth_token_secret", oauth_data.secret);
140 | }
141 | else if (oauth_data.token != null) {
142 | postdata.put("access_token", oauth_data.token);
143 | }
144 | postdata.put("provider", oauth_data.provider);
145 | } catch (JSONException e) {
146 | callback.onError(e.getMessage());
147 | return;
148 | }
149 | new OAuthJSONRequest().post(url, postdata, new OAuthJSONCallback() {
150 | @Override
151 | public void onFinished(JSONObject _data) {
152 | providers.add(oauth_data.provider);
153 | callback.onFinished();
154 | }
155 |
156 | @Override
157 | public void onError(String message) {
158 | callback.onError(message);
159 | }
160 | });
161 | }
162 |
163 | public void removeProvider(final String provider, final OAuthUserCallback callback) {
164 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/user/providers/" + provider + "?k=" + _oauth.getPublicKey() + "&token=" + token;
165 |
166 | new OAuthJSONRequest().del(url, new OAuthJSONCallback() {
167 | @Override
168 | public void onFinished(JSONObject _data) {
169 | providers.remove(provider); // check if it removes by ref or equality
170 | callback.onFinished();
171 | }
172 |
173 | @Override
174 | public void onError(String message) {
175 | callback.onError(message);
176 | }
177 | });
178 | }
179 |
180 | public void logout(final OAuthUserCallback callback) {
181 | if (token.isEmpty()) {
182 | callback.onFinished();
183 | return;
184 | }
185 |
186 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/user/logout?k=" + _oauth.getPublicKey() + "&token=" + token;
187 |
188 | new OAuthJSONRequest().post(url, new JSONObject(), new OAuthJSONCallback() {
189 | @Override
190 | public void onFinished(JSONObject _data) {
191 | token = "";
192 | providers.clear();
193 | data.clear();
194 | callback.onFinished();
195 | }
196 |
197 | @Override
198 | public void onError(String message) {
199 | callback.onError(message);
200 | }
201 | });
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuthUserCallback.java:
--------------------------------------------------------------------------------
1 | package io.oauth;
2 |
3 | /**
4 | * The onFinished is called when a user method is finished.
5 | */
6 | public interface OAuthUserCallback {
7 |
8 | /**
9 | * Called when a user method got a result.
10 | */
11 | public abstract void onFinished();
12 |
13 | /**
14 | * Called when the method fails
15 | *
16 | * @param message The error message
17 | */
18 | public abstract void onError(String message);
19 | }
20 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/OAuthUsers.java:
--------------------------------------------------------------------------------
1 | package io.oauth;
2 |
3 | import org.json.JSONArray;
4 | import org.json.JSONException;
5 | import org.json.JSONObject;
6 |
7 | import java.util.Hashtable;
8 | import java.util.Iterator;
9 | import java.util.Map;
10 |
11 | import io.oauth.http.OAuthJSONCallback;
12 | import io.oauth.http.OAuthJSONRequest;
13 |
14 | /**
15 | * Methods related to the user authentication
16 | */
17 | public class OAuthUsers {
18 |
19 | private OAuth _oauth;
20 |
21 | public OAuthUser authUser;
22 |
23 | public OAuthUsers(OAuth o)
24 | {
25 | _oauth = o;
26 | }
27 |
28 | public void signin(OAuthData oauth_data, OAuthUserCallback callback) {
29 | JSONObject postdata = new JSONObject();
30 | try {
31 | if (oauth_data.token != null && oauth_data.secret != null) {
32 | postdata.put("oauth_token", oauth_data.token);
33 | postdata.put("oauth_token_secret", oauth_data.secret);
34 | }
35 | else if (oauth_data.token != null) {
36 | postdata.put("access_token", oauth_data.token);
37 | }
38 | postdata.put("provider", oauth_data.provider);
39 | _signin(postdata, callback);
40 |
41 | } catch (JSONException e) {
42 | callback.onError(e.getMessage());
43 | }
44 | }
45 |
46 | public void signin(String email, String password, OAuthUserCallback callback) {
47 | JSONObject postdata = new JSONObject();
48 | try {
49 | postdata.put("email", email);
50 | postdata.put("password", password);
51 | _signin(postdata, callback);
52 |
53 | } catch (JSONException e) {
54 | callback.onError(e.getMessage());
55 | }
56 | }
57 |
58 | private void _signin(JSONObject postdata, final OAuthUserCallback callback) {
59 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/signin?k=" + _oauth.getPublicKey();
60 | new OAuthJSONRequest().post(url, postdata, new OAuthJSONCallback() {
61 | @Override
62 | public void onFinished(JSONObject data) {
63 | OAuthUser parsedUser = new OAuthUser(_oauth);
64 | try {
65 | parsedUser.token = data.getString("token");
66 | if(data.has("user")) {
67 | JSONObject userObj = data.getJSONObject("user");
68 | Iterator it = userObj.keys();
69 | while (it.hasNext()) {
70 | String key = it.next();
71 | parsedUser.data.put(key, userObj.get(key).toString());
72 | }
73 | }
74 | if(data.has("providers")) {
75 | JSONArray providersArray = data.getJSONArray("providers");
76 | for (int i = 0; i < providersArray.length(); i++) {
77 | parsedUser.providers.add(providersArray.getString(i));
78 | }
79 | }
80 | } catch (JSONException e) {
81 | callback.onError(e.getMessage());
82 | return;
83 | }
84 | authUser = parsedUser;
85 | callback.onFinished();
86 | }
87 |
88 | @Override
89 | public void onError(String message) {
90 | callback.onError(message);
91 | }
92 |
93 | @Override
94 | public void onErrorData(String message, JSONObject data) {
95 | if (data.has("email"))
96 | onError("Missing email");
97 | else
98 | onError(message);
99 | }
100 | });
101 | }
102 |
103 | public void signup(OAuthData oauth_data, OAuthUserCallback callback) {
104 | signup(oauth_data, null, callback);
105 | }
106 |
107 | public void signup(OAuthData oauth_data, Map data, OAuthUserCallback callback) {
108 | if (data != null)
109 | data = new Hashtable<>(data);
110 | else
111 | data = new Hashtable();
112 |
113 | if (oauth_data.token != null && oauth_data.secret != null) {
114 | data.put("oauth_token", oauth_data.token);
115 | data.put("oauth_token_secret", oauth_data.secret);
116 | }
117 | else if (oauth_data.token != null) {
118 | data.put("access_token", oauth_data.token);
119 | }
120 | data.put("provider", oauth_data.provider);
121 | signup(data, callback);
122 | }
123 |
124 | public void signup(Map data, final OAuthUserCallback callback) {
125 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/signup?k=" + _oauth.getPublicKey();
126 |
127 | if ( ! data.containsKey("provider") && (! data.containsKey("email")
128 | || ! data.containsKey("password")
129 | || ! data.containsKey("firstname")
130 | || ! data.containsKey("lastname")
131 | )) {
132 | callback.onError("Missing email/password/firstname/lastname");
133 | return;
134 | }
135 |
136 | JSONObject postdata = new JSONObject(data);
137 |
138 | new OAuthJSONRequest().post(url, postdata, new OAuthJSONCallback() {
139 | @Override
140 | public void onFinished(JSONObject data) {
141 | OAuthUser parsedUser = new OAuthUser(_oauth);
142 | try {
143 | parsedUser.token = data.getString("token");
144 | if (data.has("user")) {
145 | JSONObject userObj = data.getJSONObject("user");
146 | Iterator it = userObj.keys();
147 | while (it.hasNext()) {
148 | String key = it.next();
149 | parsedUser.data.put(key, userObj.get(key).toString());
150 | }
151 | }
152 | if (data.has("providers")) {
153 | JSONArray providersArray = data.getJSONArray("providers");
154 | for (int i = 0; i < providersArray.length(); i++) {
155 | parsedUser.providers.add(providersArray.getString(i));
156 | }
157 | }
158 | } catch (JSONException e) {
159 | callback.onError(e.getMessage());
160 | return;
161 | }
162 | authUser = parsedUser;
163 | callback.onFinished();
164 | }
165 |
166 | @Override
167 | public void onError(String message) {
168 | callback.onError(message);
169 | }
170 | });
171 | }
172 |
173 | public void resetPassword(String email, final OAuthUserCallback callback) {
174 | String url = _oauth.getOAuthdURL() + "/api/usermanagement/password/reset?k=" + _oauth.getPublicKey();
175 | JSONObject postdata = new JSONObject();
176 | try {
177 | postdata.put("email", email);
178 | new OAuthJSONRequest().post(url, postdata, new OAuthJSONCallback() {
179 | @Override
180 | public void onFinished(JSONObject data) {
181 | callback.onFinished();
182 | }
183 |
184 | @Override
185 | public void onError(String message) {
186 | callback.onError(message);
187 | }
188 |
189 | });
190 | } catch (JSONException e) {
191 | callback.onError(e.getMessage());
192 | }
193 | }
194 |
195 | public OAuthUser getIdentity() {
196 | return authUser;
197 | }
198 |
199 | public boolean isLogged() {
200 | return authUser != null && authUser.isLogged();
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/http/OAuthJSONCallback.java:
--------------------------------------------------------------------------------
1 | package io.oauth.http;
2 |
3 | import org.json.JSONObject;
4 |
5 | /**
6 | * Callback when an http json request finishes
7 | */
8 | public abstract class OAuthJSONCallback {
9 |
10 | /**
11 | * Called when the request succeeded
12 | *
13 | * @param data The json data
14 | */
15 | public abstract void onFinished(JSONObject data);
16 |
17 | /**
18 | * Called when the request fails
19 | *
20 | * @param message The error message
21 | */
22 | public abstract void onError(String message);
23 |
24 | /**
25 | * Called when the request fails with attached data
26 | * This fallback on the method onError.
27 | *
28 | * @param message The error message
29 | * @param data The attached data
30 | */
31 | public void onErrorData(String message, JSONObject data) {
32 | onError(message);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/oauthio/src/main/java/io/oauth/http/OAuthJSONRequest.java:
--------------------------------------------------------------------------------
1 | package io.oauth.http;
2 |
3 | import android.os.AsyncTask;
4 |
5 | import org.apache.http.HttpEntity;
6 | import org.apache.http.HttpResponse;
7 | import org.apache.http.client.methods.HttpDelete;
8 | import org.apache.http.client.methods.HttpGet;
9 | import org.apache.http.client.methods.HttpPost;
10 | import org.apache.http.client.methods.HttpPut;
11 | import org.apache.http.client.methods.HttpUriRequest;
12 | import org.apache.http.entity.StringEntity;
13 | import org.apache.http.impl.client.DefaultHttpClient;
14 | import org.apache.http.params.BasicHttpParams;
15 | import org.json.JSONArray;
16 | import org.json.JSONObject;
17 |
18 | import java.io.BufferedReader;
19 | import java.io.InputStream;
20 | import java.io.InputStreamReader;
21 | import java.util.Iterator;
22 | import java.util.Map;
23 |
24 | /**
25 | * Call an http service that provides JSON
26 | */
27 | public class OAuthJSONRequest {
28 |
29 | public final static int HTTP_GET = 1;
30 | public final static int HTTP_POST = 2;
31 | public final static int HTTP_PUT = 3;
32 | public final static int HTTP_DELETE = 4;
33 |
34 | public HttpRequestData httpReq = null;
35 |
36 | public OAuthJSONRequest() {}
37 |
38 | public OAuthJSONRequest(int method, String url) {
39 | http(method, url, null, null, false, null);
40 | }
41 |
42 | public OAuthJSONRequest(int method, String url, String body) {
43 | http(method, url, body, null, false, null);
44 | }
45 |
46 | public OAuthJSONRequest(int method, String url, String body, Map headers) {
47 | http(method, url, body, headers, false, null);
48 | }
49 |
50 | public void get(String url, OAuthJSONCallback callback) {
51 | http(HTTP_GET, url, callback);
52 | }
53 |
54 | public void del(String url, OAuthJSONCallback callback) {
55 | http(HTTP_DELETE, url, callback);
56 | }
57 |
58 | public void post(String url, JSONObject body, OAuthJSONCallback callback) {
59 | http(HTTP_POST, url, body.toString(), callback);
60 | }
61 |
62 | public void post(String url, String body, OAuthJSONCallback callback) {
63 | http(HTTP_POST, url, body, callback);
64 | }
65 |
66 | public void put(String url, JSONObject body, OAuthJSONCallback callback) {
67 | http(HTTP_PUT, url, body.toString(), callback);
68 | }
69 |
70 | public void put(String url, String body, OAuthJSONCallback callback) {
71 | http(HTTP_PUT, url, body, callback);
72 | }
73 |
74 | public void http(int method, String url, OAuthJSONCallback callback) {
75 | http(method, url, null, null, true, callback);
76 | }
77 |
78 | public void http(int method, String url, String body, OAuthJSONCallback callback) {
79 | http(method, url, body, null, true, callback);
80 | }
81 |
82 | public void http(int method, String url, String body, Map headers,
83 | OAuthJSONCallback callback) {
84 | http(method, url, body, headers, true, callback);
85 | }
86 |
87 | public void http(int method, String url, String body, Map headers,
88 | Boolean parsePayload, OAuthJSONCallback callback) {
89 | HttpRequestData req = new HttpRequestData();
90 | req.url = url;
91 | req.method = method;
92 | req.body = body;
93 | req.headers = headers;
94 | req.parsePayload = parsePayload;
95 | req.callback = callback;
96 | if (callback != null)
97 | new JSONRequest().execute(req);
98 | else
99 | httpReq = req;
100 | }
101 |
102 | public void execute(OAuthJSONCallback callback) {
103 | if (httpReq != null) {
104 | httpReq.callback = callback;
105 | new JSONRequest().execute(httpReq);
106 | }
107 | }
108 |
109 | public class HttpRequestData {
110 | public String url;
111 | public int method;
112 | public String body;
113 | public Map headers;
114 | public Boolean parsePayload = true;
115 | public OAuthJSONCallback callback;
116 | }
117 | private class JSONRequest extends AsyncTask {
118 |
119 | private String errorMessage;
120 | private JSONObject resultObj;
121 | private HttpRequestData param;
122 |
123 | @Override
124 | protected Boolean doInBackground(HttpRequestData... params) {
125 | param = params[0];
126 | DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
127 | InputStream inputStream = null;
128 | String result = null;
129 |
130 | try {
131 | HttpUriRequest req = null;
132 | //param.url = "http://httpbin.org/post";
133 | if (param.method == HTTP_GET) {
134 | req = new HttpGet(param.url);
135 | }
136 | else if (param.method == HTTP_DELETE) {
137 | req = new HttpDelete(param.url);
138 | }
139 | else if (param.method == HTTP_POST) {
140 | HttpPost httppost = new HttpPost(param.url);
141 | httppost.setHeader("Content-Type", "application/json");
142 | httppost.setEntity(new StringEntity(param.body));
143 | req = httppost;
144 | }
145 | else if (param.method == HTTP_PUT) {
146 | HttpPut httpput = new HttpPut(param.url);
147 | httpput.setHeader("Content-Type", "application/json");
148 | httpput.setEntity(new StringEntity(param.body));
149 | req = httpput;
150 | }
151 | else
152 | throw new Exception("Unknown http method");
153 | req.setHeader("Accept", "application/json");
154 | req.setHeader("Origin", "http://localhost");
155 | req.setHeader("User-Agent", "OAuthio-android/1.0");
156 |
157 | if (param.headers != null)
158 | for (Map.Entry entry : param.headers.entrySet())
159 | req.setHeader(entry.getKey(), entry.getValue());
160 |
161 | HttpResponse response = httpclient.execute(req);
162 | HttpEntity entity = response.getEntity();
163 |
164 | inputStream = entity.getContent();
165 | // json is UTF-8 by default
166 | BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
167 | StringBuilder sb = new StringBuilder();
168 |
169 | String line = null;
170 | while ((line = reader.readLine()) != null) {
171 | sb.append(line + "\n");
172 | }
173 | result = sb.toString();
174 |
175 | JSONObject jsondata = new JSONObject(result);
176 |
177 | if (param.parsePayload) {
178 | resultObj = jsondata.optJSONObject("data");
179 |
180 | if (resultObj == null) {
181 | resultObj = new JSONObject();
182 | JSONArray arr = jsondata.optJSONArray("data");
183 | if (arr != null)
184 | resultObj.put("items", arr);
185 | }
186 |
187 | if (jsondata.has("status") && jsondata.getString("status").equals("error")) {
188 | if (jsondata.has("message"))
189 | errorMessage = jsondata.optString("message");
190 | else if (jsondata.has("data")) {
191 | JSONObject dataObj = jsondata.getJSONObject("data");
192 | Iterator> keys = dataObj.keys();
193 | String key = null;
194 | errorMessage = "";
195 | while (keys.hasNext()) {
196 | if (key != null)
197 | errorMessage += ", ";
198 | key = (String) keys.next();
199 | errorMessage += dataObj.optString(key) + " " + key;
200 | }
201 | if (errorMessage.length() > 0)
202 | errorMessage = Character.toString(errorMessage.charAt(0)).toUpperCase() + errorMessage.substring(1);
203 | }
204 | return false;
205 | }
206 | }
207 | else
208 | resultObj = jsondata;
209 | return true;
210 | } catch (Exception e) {
211 | errorMessage = e.getMessage();
212 | return false;
213 | } finally {
214 | try {
215 | if (inputStream != null) inputStream.close();
216 | } catch (Exception squish) {
217 | }
218 | }
219 | }
220 |
221 | protected void onPostExecute(Boolean succeeded) {
222 | if (succeeded)
223 | param.callback.onFinished(resultObj);
224 | else
225 | param.callback.onErrorData(errorMessage, resultObj);
226 | }
227 | }
228 | }
229 |
--------------------------------------------------------------------------------
/oauthio/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | OAuthio
3 |
4 |
--------------------------------------------------------------------------------