Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc7a0767 authored by Fahim Salam Chowdhury's avatar Fahim Salam Chowdhury 👽
Browse files

Merge branch '1897-Enable_session_cookie_sharing_for_murena_account' into 'main'

1897-Enable_session_cookie_sharing_for_murena_account

See merge request !113
parents 3bae1fae 2cc52015
Loading
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ plugins {
    id 'dagger.hilt.android.plugin'
    id 'kotlin-android'
    id 'kotlin-kapt'     // remove as soon as Hilt supports KSP [https://issuetracker.google.com/179057202]
    id 'kotlin-parcelize'
}

// Android configuration
@@ -28,7 +29,7 @@ android {
        minSdkVersion 24        // Android 7.0
        targetSdkVersion 33     // Android 13

        buildConfigField "String", "userAgent", "\"DAVx5\""
        buildConfigField "String", "userAgent", "\"AccountManager\""

        testInstrumentationRunner "at.bitfire.davdroid.CustomTestRunner"
    }
@@ -146,6 +147,7 @@ configurations {
dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:${versions.kotlin}"
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.3'

    implementation "com.google.dagger:hilt-android:${versions.hilt}"
@@ -217,7 +219,7 @@ dependencies {
    implementation "commons-httpclient:commons-httpclient:3.1@jar" // remove after entire switch to lib v2
    implementation 'org.apache.jackrabbit:jackrabbit-webdav:2.13.5' // remove after entire switch to lib v2
    implementation 'com.google.code.gson:gson:2.10.1'
    implementation("com.github.nextcloud:android-library:2.14.0") {
    implementation("foundation.e:Nextcloud-Android-Library:1.0.5-release") {
        exclude group: 'com.gitlab.bitfireAT', module: 'dav4jvm'
        exclude group: 'org.ogce', module: 'xpp3' // unused in Android and brings wrong Junit version
        exclude group: 'com.squareup.okhttp3'
+10 −1
Original line number Diff line number Diff line
@@ -684,13 +684,22 @@


        <receiver
            android:name=".BootCompletedReceiver"
            android:name=".receiver.BootCompletedReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <receiver
            android:name=".receiver.AccountRemovedReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.accounts.action.ACCOUNT_REMOVED"/>
            </intent-filter>
        </receiver>

        <!-- provider to share debug info/logs -->
        <provider
            android:name="androidx.core.content.FileProvider"
+20 −15
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import static com.nextcloud.android.sso.Constants.EXCEPTION_UNSUPPORTED_METHOD;
import static com.nextcloud.android.sso.Constants.SSO_SHARED_PREFERENCE;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
@@ -43,10 +42,10 @@ import com.nextcloud.android.sso.aidl.NextcloudRequest;
import com.nextcloud.android.sso.aidl.ParcelFileDescriptorUtil;
import com.nextcloud.android.utils.AccountManagerUtils;
import com.nextcloud.android.utils.EncryptionUtils;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.OwnCloudClientFactory;
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.OwnCloudClientManager;
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;

import org.apache.commons.httpclient.HttpConnection;
import org.apache.commons.httpclient.HttpMethodBase;
@@ -79,6 +78,7 @@ import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import at.bitfire.davdroid.BuildConfig;
import at.bitfire.davdroid.log.Logger;

public class InputStreamBinder extends IInputStreamService.Stub {
@@ -333,9 +333,10 @@ public class InputStreamBinder extends IInputStreamService.Stub {
                    new IllegalStateException("URL need to start with a /"));
        }

        Uri serverUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, account));
        OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(serverUri, context, true);
        client.setCredentials(OwnCloudCredentialsFactory.newBasicCredentials(account.name, getAcountPwd(account, context)));
        OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
        final OwnCloudClientManager ownCloudClientManager = OwnCloudClientManagerFactory.getDefaultSingleton();
        final OwnCloudAccount ownCloudAccount = new OwnCloudAccount(account, context);
        final OwnCloudClient client = ownCloudClientManager.getClientFor(ownCloudAccount, context);

        HttpMethodBase method = buildMethod(request, client.getBaseUri(), requestBodyInputStream);

@@ -360,6 +361,8 @@ public class InputStreamBinder extends IInputStreamService.Stub {
        client.setFollowRedirects(true);
        int status = client.executeMethod(method);

        ownCloudClientManager.saveAllClients(context, account.type);

        // Check if status code is 2xx --> https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success
        if (status >= HTTP_STATUS_CODE_OK && status < HTTP_STATUS_CODE_MULTIPLE_CHOICES) {
            return method;
@@ -380,6 +383,10 @@ public class InputStreamBinder extends IInputStreamService.Stub {
        }
    }

    private static String getUserAgent() {
        return "AccountManager-SSO(" + BuildConfig.VERSION_NAME + ")";
    }

    private Response processRequestV2(final NextcloudRequest request, final InputStream requestBodyInputStream)
            throws UnsupportedOperationException,
            com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException,
@@ -400,9 +407,10 @@ public class InputStreamBinder extends IInputStreamService.Stub {
                    new IllegalStateException("URL need to start with a /"));
        }

        Uri serverUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, account));
        OwnCloudClient client = OwnCloudClientFactory.createOwnCloudClient(serverUri, context, true);
        client.setCredentials(OwnCloudCredentialsFactory.newBasicCredentials(account.name, getAcountPwd(account, context)));
        OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
        final OwnCloudClientManager ownCloudClientManager = OwnCloudClientManagerFactory.getDefaultSingleton();
        final OwnCloudAccount ownCloudAccount = new OwnCloudAccount(account, context);
        final OwnCloudClient client = ownCloudClientManager.getClientFor(ownCloudAccount, context);

        HttpMethodBase method = buildMethod(request, client.getBaseUri(), requestBodyInputStream);

@@ -428,6 +436,8 @@ public class InputStreamBinder extends IInputStreamService.Stub {
        client.setFollowRedirects(true);
        int status = client.executeMethod(method);

        ownCloudClientManager.saveAllClients(context, account.type);

        // Check if status code is 2xx --> https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#2xx_Success
        if (status >= HTTP_STATUS_CODE_OK && status < HTTP_STATUS_CODE_MULTIPLE_CHOICES) {
            return new Response(method);
@@ -447,11 +457,6 @@ public class InputStreamBinder extends IInputStreamService.Stub {
        }
    }

    private static String getAcountPwd(Account account, Context ctx) throws AccountUtils.AccountNotFoundException {
        return AccountManager.get(ctx).getPassword(account);
    }


    private boolean isValid(NextcloudRequest request) {
        String callingPackageName = context.getPackageManager().getNameForUid(Binder.getCallingUid());

+2 −19
Original line number Diff line number Diff line
@@ -35,7 +35,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

@@ -49,6 +48,7 @@ import java.util.logging.Level;

import at.bitfire.davdroid.R;
import at.bitfire.davdroid.log.Logger;
import at.bitfire.davdroid.util.SsoUtils;

public class SsoGrantPermissionActivity extends AppCompatActivity {

@@ -115,7 +115,7 @@ public class SsoGrantPermissionActivity extends AppCompatActivity {

        // create token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        String userId = sanitizeUserId(account.name);
        String userId = SsoUtils.INSTANCE.sanitizeUserId(account.name);

        saveToken(token, account.name);
        setResultData(token, userId, serverUrl);
@@ -136,23 +136,6 @@ public class SsoGrantPermissionActivity extends AppCompatActivity {
        setResult(RESULT_OK, data);
    }

    /**
     * Murena account's userId is set same as it's email address.
     * For old accounts (@e.email) userId = email.
     * For new accounts (@murena.io) userId is first part of email (ex: for email abc@murena.io, userId is abc).
     * For api requests, we needed to pass the actual userId. This method remove the unwanted part (@murena.io) from the userId
     */
    @NonNull
    private static String sanitizeUserId(@NonNull String userId) {
        final String murenaMailEndPart = "@murena.io";

        if (!userId.endsWith(murenaMailEndPart)) {
            return userId;
        }

        return userId.split(murenaMailEndPart)[0];
    }

    @Nullable
    private String getServerUrl() {
        try {
+22 −0
Original line number Diff line number Diff line
/*
 * Copyright MURENA SAS 2024
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package at.bitfire.davdroid.network

interface CookieParser {

    fun cookiesAsString(): String
}
 No newline at end of file
Loading