1
0
mirror of https://github.com/nerzhul/ownCloud-SMS-App.git synced 2025-06-07 07:56:14 +00:00

Rewrite our HTTP Client to remove the owncloud library dependency and doing authentication ourselves

* Fixes issue #122
* Cleanup the code
* Drop owncloud library support, this will help the unofficial F-Droid build
This commit is contained in:
Loic Blot 2016-12-20 21:34:52 +01:00
parent f2082e5215
commit 25e2d13409
7 changed files with 69 additions and 176 deletions

View File

@ -33,7 +33,7 @@ To contribute please download `res/values/strings.xml` and `res/values/google_pl
You can also contribute by adding patches in Java code or cleanups.
## Requirements
- A NextCloud or ownCloud instance with ocsms app
- An Nextcloud or ownCloud instance with ocsms app
## Build requirements
- nrz-androidlib (last version)

View File

@ -13,7 +13,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
useLibrary 'org.apache.http.legacy'
lintOptions {
abortOnError false
@ -45,11 +44,11 @@ repositories {
}
dependencies {
compile project(':owncloudAndroidLibrary')
compile 'com.android.support:support-v13:25.0.1'
compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support:design:25.0.1'
compile files('libs/commons-httpclient-3.1.jar')
compile 'com.android.support:support-v13:25.1.0'
compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:design:25.1.0'
compile 'in.srain.cube:ultra-ptr:1.0.11'
compile 'com.github.dmytrodanylyk.android-process-button:library:1.0.4'
compile 'com.android.support:support-v4:25.0.1'
compile 'com.android.support:support-v4:25.1.0'
}

Binary file not shown.

View File

@ -41,14 +41,14 @@ import android.widget.Spinner;
import android.widget.TextView;
import com.dd.processbutton.iml.ActionProcessButton;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientFactory;
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
import org.apache.commons.httpclient.methods.GetMethod;
import java.io.IOException;
import fr.unix_experience.owncloud_sms.R;
import fr.unix_experience.owncloud_sms.authenticators.OwnCloudAuthenticator;
import fr.unix_experience.owncloud_sms.defines.DefaultPrefs;
import fr.unix_experience.owncloud_sms.enums.LoginReturnCode;
import fr.unix_experience.owncloud_sms.engine.HTTPRequestBuilder;
/**
* A login screen that offers login via email/password.
@ -240,25 +240,19 @@ public class LoginActivity extends AppCompatActivity {
@Override
protected Boolean doInBackground(Void... params) {
// Create client object to perform remote operations
OwnCloudClient ocClient = OwnCloudClientFactory.createOwnCloudClient(
_serverURI, getBaseContext(),
// Activity or Service context
true
);
// Set basic credentials
ocClient.setCredentials(
OwnCloudCredentialsFactory.newBasicCredentials(_login, _password)
);
// Send an authentication test to ownCloud
OwnCloudAuthenticator at = new OwnCloudAuthenticator(getBaseContext());
at.setClient(ocClient);
_returnCode = at.testCredentials();
return (_returnCode == LoginReturnCode.OK);
_returnCode = 0;
HTTPRequestBuilder http = new HTTPRequestBuilder(_serverURI, _login, _password);
GetMethod testMethod = http.getVersion();
try {
_returnCode = http.execute(testMethod);
} catch (IOException e) {
Log.w(TAG, "Failed to login, IOException occured: " + e.getMessage());
_returnCode = 599;
}
testMethod.releaseConnection();
return (_returnCode == 200);
}
@Override
@ -304,26 +298,25 @@ public class LoginActivity extends AppCompatActivity {
} else {
boolean serverViewRequestFocus = true;
switch (_returnCode) {
case INVALID_ADDR:
_serverView.setError(getString(R.string.error_invalid_server_address));
break;
case HTTP_CONN_FAILED:
_serverView.setError(getString(R.string.error_http_connection_failed));
break;
case CONN_FAILED:
_serverView.setError(getString(R.string.error_connection_failed));
break;
case CONN_FAILED_NOT_FOUND:
_serverView.setError(getString(R.string.error_connection_failed_not_found));
break;
case UNKNOWN_ERROR:
case 0:
_serverView.setError("UNK");
break;
case INVALID_LOGIN:
case 404:
_serverView.setError(getString(R.string.error_connection_failed_not_found));
break;
case 400:
case 598:
_serverView.setError(getString(R.string.error_connection_failed));
break;
case 599:
_serverView.setError(getString(R.string.error_http_connection_failed));
break;
case 401:
case 403:
_passwordView.setError(getString(R.string.error_invalid_login));
_passwordView.requestFocus();
// Warning, there is no break here to disable serverViewRequestFocus too
case OK:
case 200:
default:
serverViewRequestFocus = false;
break;
@ -334,7 +327,7 @@ public class LoginActivity extends AppCompatActivity {
}
// If not ok, reset the progress
if (_returnCode != LoginReturnCode.OK) {
if (_returnCode != 200) {
_signInButton.setProgress(0);
}
}
@ -345,13 +338,13 @@ public class LoginActivity extends AppCompatActivity {
mAuthTask = null;
showProgress(false);
}
private final Uri _serverURI;
private final String _login;
private final String _password;
private LoginReturnCode _returnCode;
private int _returnCode;
public static final String PARAM_AUTHTOKEN_TYPE = "auth.token";
static final String PARAM_AUTHTOKEN_TYPE = "auth.token";
private final String TAG = UserLoginTask.class.getCanonicalName();
}
}

View File

@ -25,19 +25,8 @@ import android.accounts.NetworkErrorException;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.http.HttpStatus;
import org.json.JSONObject;
import java.io.IOException;
import fr.unix_experience.owncloud_sms.activities.LoginActivity;
import fr.unix_experience.owncloud_sms.enums.LoginReturnCode;
public class OwnCloudAuthenticator extends AbstractAccountAuthenticator {
// Simple constructor
@ -103,95 +92,8 @@ public class OwnCloudAuthenticator extends AbstractAccountAuthenticator {
// TODO Auto-generated method stub
return null;
}
/*
* Return codes
* 1: invalid address
* 2: HTTP failed
* 3: connexion failed
* 4: invalid login
* 5: unknown error
*/
public LoginReturnCode testCredentials() {
LoginReturnCode bRet = LoginReturnCode.OK;
GetMethod get;
int status;
try {
get = new GetMethod(_client.getBaseUri() + "/index.php/ocs/cloud/user?format=json");
} catch (IllegalArgumentException e) {
return LoginReturnCode.INVALID_ADDR;
}
get.addRequestHeader("OCS-APIREQUEST", "true");
try {
status = _client.executeMethod(get);
} catch (IllegalArgumentException e) {
return LoginReturnCode.INVALID_ADDR;
} catch (HttpException e) {
return LoginReturnCode.HTTP_CONN_FAILED;
} catch (IOException e) {
return LoginReturnCode.CONN_FAILED;
}
try {
if(OwnCloudAuthenticator.isSuccess(status)) {
String response = get.getResponseBodyAsString();
Log.i(OwnCloudAuthenticator.TAG, "Successful response: " + response);
// Parse the response
JSONObject respJSON = new JSONObject(response);
JSONObject respOCS = respJSON.getJSONObject(OwnCloudAuthenticator.NODE_OCS);
JSONObject respData = respOCS.getJSONObject(OwnCloudAuthenticator.NODE_DATA);
String id = respData.getString(OwnCloudAuthenticator.NODE_ID);
String displayName = respData.getString(OwnCloudAuthenticator.NODE_DISPLAY_NAME);
String email = respData.getString(OwnCloudAuthenticator.NODE_EMAIL);
Log.i(OwnCloudAuthenticator.TAG, "*** Parsed user information: " + id + " - " + displayName + " - " + email);
} else {
String response = get.getResponseBodyAsString();
Log.e(OwnCloudAuthenticator.TAG, "Failed response while getting user information ");
if (response != null) {
Log.e(OwnCloudAuthenticator.TAG, "*** status code: " + status + " ; response message: " + response);
} else {
Log.e(OwnCloudAuthenticator.TAG, "*** status code: " + status);
}
switch (status) {
case 401: bRet = LoginReturnCode.INVALID_LOGIN; break;
case 404: bRet = LoginReturnCode.CONN_FAILED_NOT_FOUND; break;
default: bRet = LoginReturnCode.UNKNOWN_ERROR; break;
}
}
} catch (Exception e) {
Log.e(OwnCloudAuthenticator.TAG, "Exception while getting OC user information", e);
bRet = LoginReturnCode.UNKNOWN_ERROR;
} finally {
get.releaseConnection();
}
return bRet;
}
private static boolean isSuccess(int status) {
return (status == HttpStatus.SC_OK);
}
public void setClient(OwnCloudClient oc) {
_client = oc;
}
private final Context _context;
private OwnCloudClient _client;
private static final String TAG = OwnCloudAuthenticator.class.getSimpleName();
private static final String NODE_OCS = "ocs";
private static final String NODE_DATA = "data";
private static final String NODE_ID = "id";
private static final String NODE_DISPLAY_NAME= "display-name";
private static final String NODE_EMAIL= "email";
}

View File

@ -17,13 +17,11 @@ package fr.unix_experience.owncloud_sms.engine;
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import android.content.Context;
import android.net.Uri;
import android.util.Base64;
import android.util.Log;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientFactory;
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
@ -31,9 +29,12 @@ import org.apache.commons.httpclient.methods.StringRequestEntity;
import java.io.IOException;
class HTTPRequestBuilder {
public class HTTPRequestBuilder {
private final OwnCloudClient _ocClient;
private static final String TAG = HTTPRequestBuilder.class.getCanonicalName();
private final Uri _serverURI;
private final String _username;
private final String _password;
// API v1 calls
private static final String OC_GET_VERSION = "/index.php/apps/ocsms/get/apiversion?format=json";
@ -47,20 +48,15 @@ class HTTPRequestBuilder {
private static final String OC_V2_GET_MESSAGES_PHONE ="/index.php/apps/ocsms/api/v2/messages/[PHONENUMBER]/[START]/[LIMIT]?format=json";
private static final String OC_V2_GET_MESSAGES_SENDQUEUE = "/index.php/apps/ocsms/api/v2/messages/sendqueue?format=json";
HTTPRequestBuilder(Context context, Uri serverURI, String accountName, String accountPassword) {
_ocClient = OwnCloudClientFactory.createOwnCloudClient(
serverURI, context, true);
// Set basic credentials
_ocClient.setCredentials(
OwnCloudCredentialsFactory.newBasicCredentials(accountName, accountPassword)
);
public HTTPRequestBuilder(Uri serverURI, String accountName, String accountPassword) {
_serverURI = serverURI;
_username = accountName;
_password = accountPassword;
}
private GetMethod get(String oc_call) {
GetMethod get = new GetMethod(_ocClient.getBaseUri() + oc_call);
get.addRequestHeader("OCS-APIREQUEST", "true");
return get;
Log.i(HTTPRequestBuilder.TAG, "Create GET " + _serverURI + oc_call);
return new GetMethod(_serverURI.toString() + oc_call);
}
GetMethod getAllSmsIds() {
@ -72,8 +68,7 @@ class HTTPRequestBuilder {
}
PostMethod pushSms(StringRequestEntity ent) {
PostMethod post = new PostMethod(_ocClient.getBaseUri() + HTTPRequestBuilder.OC_PUSH_ROUTE);
post.addRequestHeader("OCS-APIREQUEST", "true");
PostMethod post = new PostMethod(_serverURI.toString() + HTTPRequestBuilder.OC_PUSH_ROUTE);
post.setRequestEntity(ent);
return post;
}
@ -87,7 +82,13 @@ class HTTPRequestBuilder {
replace("[START]", start.toString()).replace("[LIMIT]", limit.toString()));
}
int execute(HttpMethod req) throws IOException {
return _ocClient.executeMethod(req);
public int execute(HttpMethod req) throws IOException {
HttpClient http = new HttpClient();
String basicAuth = "Basic " +
Base64.encodeToString((_username + ":" + _password).getBytes(), Base64.NO_WRAP);
//req.setFollowRedirects(true); // App is SIGKILLED by android when doing this... WTF
req.setDoAuthentication(true);
req.addRequestHeader("Authorization", basicAuth);
return http.executeMethod(req);
}
}

View File

@ -27,7 +27,6 @@ import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
@ -57,8 +56,7 @@ public class OCSMSOwnCloudClient {
}
Uri serverURI = Uri.parse(ocURI);
_http = new HTTPRequestBuilder(context, serverURI,
accountManager.getUserData(account, "ocLogin"),
_http = new HTTPRequestBuilder(serverURI, accountManager.getUserData(account, "ocLogin"),
accountManager.getPassword(account));
_connectivityMonitor = new ConnectivityMonitor(_context);
}
@ -321,7 +319,7 @@ public class OCSMSOwnCloudClient {
}
}
if (status == HttpStatus.SC_OK) {
if (status == 200) {
String response;
try {
response = req.getResponseBodyAsString();
@ -346,7 +344,7 @@ public class OCSMSOwnCloudClient {
}
}
}
} else if (status == HttpStatus.SC_FORBIDDEN) {
} else if (status == 403) {
// Authentication failed
throw new OCSyncException(R.string.err_sync_auth_failed, OCSyncErrorType.AUTH);
} else {