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

Commit 7e3ab357 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Check permissions in RcsMessageStoreController"

parents ec370627 5df72432
Loading
Loading
Loading
Loading
+550 −388

File changed.

Preview size limit exceeded, changes collapsed.

+61 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.ims;

import android.Manifest;
import android.app.AppOpsManager;
import android.content.Context;
import android.os.Binder;

class RcsPermissions {
    static void checkReadPermissions(Context context, String callingPackage) {
        int pid = Binder.getCallingPid();
        int uid = Binder.getCallingUid();

        context.enforcePermission(Manifest.permission.READ_SMS, pid, uid, null);

        checkOp(context, uid, callingPackage, AppOpsManager.OP_READ_SMS);
    }

    static void checkWritePermissions(Context context, String callingPackage) {
        int uid = Binder.getCallingUid();

        checkOp(context, uid, callingPackage, AppOpsManager.OP_WRITE_SMS);
    }

    /**
     * Notes the provided op, but throws even if the op mode is {@link AppOpsManager.MODE_IGNORED}.
     * <p>
     * {@link AppOpsManager.OP_WRITE_SMS} defaults to {@link AppOpsManager.MODE_IGNORED} to avoid
     * crashing applications written before the app op was introduced. Since this is a new API,
     * consumers should be aware of the permission requirements, and we should be safe to throw a
     * {@link SecurityException} instead of providing a dummy value (which could cause unexpected
     * application behavior and possible loss of user data). {@link AppOpsManager.OP_READ_SMS} is
     * not normally in {@link AppOpsManager.MODE_IGNORED}, but we maintain the same behavior for
     * consistency with handling of write permissions.
     */
    private static void checkOp(Context context, int uid, String callingPackage, int op) {
        AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);

        int mode = appOps.noteOp(op, uid, callingPackage);

        if (mode != AppOpsManager.MODE_ALLOWED) {
            throw new SecurityException(
                    AppOpsManager.opToName(op) + " not allowed for " + callingPackage);
        }
    }
}
+21 −16
Original line number Original line Diff line number Diff line
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.doReturn;
import android.content.ContentValues;
import android.content.ContentValues;
import android.database.MatrixCursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.Telephony;
import android.provider.Telephony;
import android.provider.Telephony.RcsColumns.RcsParticipantColumns;
import android.provider.Telephony.RcsColumns.RcsParticipantColumns;
import android.telephony.ims.RcsParticipant;
import android.telephony.ims.RcsParticipant;
@@ -65,7 +64,7 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
        mContentResolver = (MockContentResolver) mContext.getContentResolver();
        mContentResolver = (MockContentResolver) mContext.getContentResolver();
        mContentResolver.addProvider("rcs", mFakeRcsProvider);
        mContentResolver.addProvider("rcs", mFakeRcsProvider);


        mRcsMessageStoreController = new RcsMessageStoreController(mContentResolver);
        mRcsMessageStoreController = new RcsMessageStoreController(mContext);
    }
    }


    @After
    @After
@@ -85,14 +84,14 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
                Uri.parse("content://rcs/thread"), null, null, null, null, null));
                Uri.parse("content://rcs/thread"), null, null, null, null, null));


        try {
        try {
            mRcsMessageStoreController.getRcsThreads(queryParameters);
            mRcsMessageStoreController.getRcsThreads(queryParameters, getPackageName());
        } catch (RemoteException e) {
        } catch (RuntimeException e) {
            // eat the exception as there is no provider - we care about the expected update assert
            // eat the exception as there is no provider - we care about the expected update assert
        }
        }
    }
    }


    @Test
    @Test
    public void testCreateRcsParticipant() throws RemoteException {
    public void testCreateRcsParticipant() {
        String canonicalAddress = "+5551234567";
        String canonicalAddress = "+5551234567";


        // verify the first query to canonical addresses
        // verify the first query to canonical addresses
@@ -118,7 +117,8 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
                Uri.parse("content://rcs/participant/1001")));
                Uri.parse("content://rcs/participant/1001")));


        int participantId =
        int participantId =
                mRcsMessageStoreController.createRcsParticipant(canonicalAddress, "alias");
                mRcsMessageStoreController.createRcsParticipant(canonicalAddress, "alias",
                        getPackageName());


        assertThat(participantId).isEqualTo(1001);
        assertThat(participantId).isEqualTo(1001);
    }
    }
@@ -131,8 +131,8 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
                Uri.parse("content://rcs/participant/551"), null, null, contentValues, 0));
                Uri.parse("content://rcs/participant/551"), null, null, contentValues, 0));


        try {
        try {
            mRcsMessageStoreController.setRcsParticipantAlias(551, "New Alias");
            mRcsMessageStoreController.setRcsParticipantAlias(551, "New Alias", getPackageName());
        } catch (RemoteException e) {
        } catch (RuntimeException e) {
            // eat the exception as there is no provider - we care about the expected update assert
            // eat the exception as there is no provider - we care about the expected update assert
        }
        }
    }
    }
@@ -144,8 +144,8 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
        mFakeRcsProvider.addExpectedOperation(new ExpectedUpdate(
        mFakeRcsProvider.addExpectedOperation(new ExpectedUpdate(
                Uri.parse("content://rcs/p2p_thread/123"), null, null, contentValues, 0));
                Uri.parse("content://rcs/p2p_thread/123"), null, null, contentValues, 0));
        try {
        try {
            mRcsMessageStoreController.set1To1ThreadFallbackThreadId(123, 456L);
            mRcsMessageStoreController.set1To1ThreadFallbackThreadId(123, 456L, getPackageName());
        } catch (RemoteException e) {
        } catch (RuntimeException e) {
            // eat the exception as there is no provider - we care about the expected update assert
            // eat the exception as there is no provider - we care about the expected update assert
        }
        }
    }
    }
@@ -158,8 +158,8 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
                Uri.parse("content://rcs/group_thread/345"), null, null, contentValues, 0));
                Uri.parse("content://rcs/group_thread/345"), null, null, contentValues, 0));


        try {
        try {
            mRcsMessageStoreController.setGroupThreadName(345, "new name");
            mRcsMessageStoreController.setGroupThreadName(345, "new name", getPackageName());
        } catch (RemoteException e) {
        } catch (RuntimeException e) {
            // eat the exception as there is no provider - we care about the expected update assert
            // eat the exception as there is no provider - we care about the expected update assert
        }
        }
    }
    }
@@ -172,8 +172,9 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
                Uri.parse("content://rcs/group_thread/345"), null, null, contentValues, 0));
                Uri.parse("content://rcs/group_thread/345"), null, null, contentValues, 0));


        try {
        try {
            mRcsMessageStoreController.setGroupThreadIcon(345, Uri.parse("newIcon"));
            mRcsMessageStoreController.setGroupThreadIcon(345, Uri.parse("newIcon"),
        } catch (RemoteException e) {
                    getPackageName());
        } catch (RuntimeException e) {
            // eat the exception as there is no provider - we care about the expected update assert
            // eat the exception as there is no provider - we care about the expected update assert
        }
        }
    }
    }
@@ -186,9 +187,13 @@ public class RcsMessageStoreControllerTest extends TelephonyTest {
                Uri.parse("content://rcs/group_thread/454"), null, null, contentValues, 0));
                Uri.parse("content://rcs/group_thread/454"), null, null, contentValues, 0));


        try {
        try {
            mRcsMessageStoreController.setGroupThreadOwner(454, 9);
            mRcsMessageStoreController.setGroupThreadOwner(454, 9, getPackageName());
        } catch (RemoteException e) {
        } catch (RuntimeException e) {
            // eat the exception as there is no provider - we care about the expected update assert
            // eat the exception as there is no provider - we care about the expected update assert
        }
        }
    }
    }

    private String getPackageName() {
        return mContext.getOpPackageName();
    }
}
}