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

Compare commits

...

3 Commits

Author SHA1 Message Date
Loïc Blot
41da561d38 Bump 0.24.1 2017-01-20 11:19:01 +01:00
Loïc Blot
580c13de90 HTTPClient: add redirection follower 2017-01-20 11:18:35 +01:00
Loïc Blot
4b5dca282f HTTPClient: send application name & version code in User Agent
Also ignore cookies like owncloud android lib & set http version to 1.1
2017-01-20 10:40:24 +01:00
6 changed files with 340 additions and 7 deletions

231
.idea/codeStyleSettings.xml generated Normal file
View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectCodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS">
<value>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
</value>
</option>
<option name="RIGHT_MARGIN" value="100" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
</AndroidXmlCodeStyleSettings>
<Objective-C-extensions>
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" />
<option name="RELEASE_STYLE" value="IVAR" />
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" />
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" />
<pair source="c" header="h" />
</extensions>
</Objective-C-extensions>
<XML>
<option name="XML_KEEP_LINE_BREAKS" value="false" />
<option name="XML_ALIGN_ATTRIBUTES" value="false" />
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
</XML>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</value>
</option>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
</component>
</project>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="fr.unix_experience.owncloud_sms"
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="44"
android:versionName="0.24.0"> <!-- From Android 4.1 to 7.1 -->
android:versionCode="45"
android:versionName="0.24.1"> <!-- From Android 4.1 to 7.1 -->
<uses-sdk android:maxSdkVersion="25"/>
<uses-permission android:name="android.permission.READ_SMS"/>

View File

@ -241,7 +241,7 @@ public class LoginActivity extends AppCompatActivity {
@Override
protected Boolean doInBackground(Void... params) {
_returnCode = 0;
OCHttpClient http = new OCHttpClient(_serverURI, _login, _password);
OCHttpClient http = new OCHttpClient(getBaseContext(), _serverURI, _login, _password);
GetMethod testMethod = http.getVersion();
try {
_returnCode = http.execute(testMethod);

View File

@ -17,12 +17,19 @@ 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 org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
@ -31,12 +38,16 @@ import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.params.HttpMethodParams;
import java.io.IOException;
import fr.unix_experience.owncloud_sms.providers.AndroidVersionProvider;
public class OCHttpClient extends HttpClient {
private static final String TAG = OCHttpClient.class.getCanonicalName();
private static final String PARAM_PROTOCOL_VERSION = "http.protocol.version";
private final Uri _serverURI;
private final String _username;
private final String _password;
@ -53,7 +64,7 @@ public class OCHttpClient extends HttpClient {
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";
public OCHttpClient(Uri serverURI, String accountName, String accountPassword) {
public OCHttpClient(Context context, Uri serverURI, String accountName, String accountPassword) {
super(new MultiThreadedHttpConnectionManager());
Protocol easyhttps = new Protocol("https", (ProtocolSocketFactory)new EasySSLProtocolSocketFactory(), 443);
Protocol.registerProtocol("https", easyhttps);
@ -61,6 +72,10 @@ public class OCHttpClient extends HttpClient {
_username = accountName;
_password = accountPassword;
getParams().setParameter(HttpClientParams.ALLOW_CIRCULAR_REDIRECTS, true);
getParams().setParameter(PARAM_PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
getParams().setParameter(HttpMethodParams.USER_AGENT,
"nextcloud-phonesync (" + new AndroidVersionProvider(context).getVersionCode() + ")");
}
private GetMethod get(String oc_call) {
@ -91,12 +106,51 @@ public class OCHttpClient extends HttpClient {
replace("[START]", start.toString()).replace("[LIMIT]", limit.toString()));
}
private int followRedirections(HttpMethod httpMethod) throws IOException {
int redirectionsCount = 0;
int status = httpMethod.getStatusCode();
while (redirectionsCount < 3 &&
(status == HttpStatus.SC_MOVED_PERMANENTLY ||
status == HttpStatus.SC_MOVED_TEMPORARILY ||
status == HttpStatus.SC_TEMPORARY_REDIRECT)
) {
Header location = httpMethod.getResponseHeader("Location");
if (location == null) {
location = httpMethod.getResponseHeader("location");
}
if (location == null) {
Log.e(TAG, "No valid location header found when redirecting.");
return 500;
}
try {
httpMethod.setURI(new URI(location.getValue()));
} catch (URIException e) {
Log.e(TAG, "Invalid URI in 302 FOUND response");
return 500;
}
status = executeMethod(httpMethod);
redirectionsCount++;
}
if (redirectionsCount >= 3 && status == HttpStatus.SC_MOVED_PERMANENTLY ||
status == HttpStatus.SC_MOVED_TEMPORARILY ||
status == HttpStatus.SC_TEMPORARY_REDIRECT) {
Log.e(TAG, "Too many redirection done. Aborting, please ensure your server is " +
"correctly configured");
return 400;
}
return status;
}
public int execute(HttpMethod req) throws IOException {
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 executeMethod(req);
executeMethod(req);
return followRedirections(req);
}
}

View File

@ -56,7 +56,8 @@ public class OCSMSOwnCloudClient {
}
Uri serverURI = Uri.parse(ocURI);
_http = new OCHttpClient(serverURI, accountManager.getUserData(account, "ocLogin"),
_http = new OCHttpClient(context,
serverURI, accountManager.getUserData(account, "ocLogin"),
accountManager.getPassword(account));
_connectivityMonitor = new ConnectivityMonitor(_context);
}

View File

@ -0,0 +1,47 @@
package fr.unix_experience.owncloud_sms.providers;
import android.content.Context;
import android.content.pm.PackageManager;
/*
* Copyright (c) 2014-2017, Loic Blot <loic.blot@unix-experience.fr>
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
public class AndroidVersionProvider {
private Context _context;
public AndroidVersionProvider(Context context) {
assert (context != null);
_context = context;
}
public String getVersionCode() {
try {
return _context.getPackageManager().
getPackageInfo(_context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
return "unknown version";
}
}
}