/**
* Copyright 2012 Facebook
*
* 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.facebook;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import com.facebook.model.GraphMultiResult;
import com.facebook.model.GraphObject;
import com.facebook.model.GraphObjectList;
import com.facebook.model.GraphUser;
import java.io.*;
import java.util.*;
public class AuthorizationClientTests extends FacebookTestCase {
private static final String ACCESS_TOKEN = "An access token";
private static final long EXPIRES_IN_DELTA = 3600 * 24 * 60;
private static final ArrayList<String> PERMISSIONS = new ArrayList<String>(
Arrays.asList("go outside", "come back in"));
private static final String ERROR_MESSAGE = "This is bad!";
class MockAuthorizationClient extends AuthorizationClient {
Result result;
boolean triedNextHandler = false;
MockAuthorizationClient() {
setContext(getActivity());
}
AuthorizationClient.AuthorizationRequest getRequest() {
return pendingRequest;
}
void setRequest(AuthorizationClient.AuthorizationRequest request) {
pendingRequest = request;
}
@Override
void complete(Result result) {
this.result = result;
}
@Override
void tryNextHandler() {
triedNextHandler = true;
}
}
// WebViewAuthHandler tests
AuthorizationClient.AuthorizationRequest createRequest() {
Session.AuthorizationRequest request = new Session.AuthorizationRequest(getActivity());
request.setPermissions(PERMISSIONS);
return request.getAuthorizationClientRequest();
}
@SmallTest
@MediumTest
@LargeTest
public void testWebViewHandlesSuccess() {
Bundle bundle = new Bundle();
bundle.putString("access_token", ACCESS_TOKEN);
bundle.putString("expires_in", String.format("%d", EXPIRES_IN_DELTA));
bundle.putString("code", "Something else");
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.WebViewAuthHandler handler = client.new WebViewAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onWebDialogComplete(request, bundle, null);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.SUCCESS, client.result.code);
AccessToken token = client.result.token;
assertNotNull(token);
assertEquals(ACCESS_TOKEN, token.getToken());
assertDateDiffersWithinDelta(new Date(), token.getExpires(), EXPIRES_IN_DELTA * 1000, 1000);
assertEquals(PERMISSIONS, token.getPermissions());
}
@SmallTest
@MediumTest
@LargeTest
public void testWebViewHandlesCancel() {
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.WebViewAuthHandler handler = client.new WebViewAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onWebDialogComplete(request, null, new FacebookOperationCanceledException());
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.CANCEL, client.result.code);
assertNull(client.result.token);
assertNotNull(client.result.errorMessage);
}
@SmallTest
@MediumTest
@LargeTest
public void testWebViewHandlesError() {
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.WebViewAuthHandler handler = client.new WebViewAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onWebDialogComplete(request, null, new FacebookException(ERROR_MESSAGE));
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.ERROR, client.result.code);
assertNull(client.result.token);
assertNotNull(client.result.errorMessage);
assertEquals(client.result.errorMessage, ERROR_MESSAGE);
}
@SmallTest
@MediumTest
@LargeTest
public void testWebViewChecksInternetPermission() {
MockAuthorizationClient client = new MockAuthorizationClient() {
@Override
int checkPermission(String permission) {
return PackageManager.PERMISSION_DENIED;
}
};
AuthorizationClient.WebViewAuthHandler handler = client.new WebViewAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onWebDialogComplete(request, null, new FacebookException(ERROR_MESSAGE));
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.ERROR, client.result.code);
assertNull(client.result.token);
assertNotNull(client.result.errorMessage);
}
// GetTokenAuthHandler tests
@SmallTest
@MediumTest
@LargeTest
public void testGetTokenHandlesSuccessWithAllPermissions() {
Bundle bundle = new Bundle();
bundle.putStringArrayList(NativeProtocol.EXTRA_PERMISSIONS, PERMISSIONS);
bundle.putLong(NativeProtocol.EXTRA_EXPIRES_SECONDS_SINCE_EPOCH, new Date().getTime() / 1000 + EXPIRES_IN_DELTA);
bundle.putString(NativeProtocol.EXTRA_ACCESS_TOKEN, ACCESS_TOKEN);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.GetTokenAuthHandler handler = client.new GetTokenAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.getTokenCompleted(request, bundle);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.SUCCESS, client.result.code);
AccessToken token = client.result.token;
assertNotNull(token);
assertEquals(ACCESS_TOKEN, token.getToken());
assertDateDiffersWithinDelta(new Date(), token.getExpires(), EXPIRES_IN_DELTA * 1000, 1000);
assertEquals(PERMISSIONS, token.getPermissions());
}
@SmallTest
@MediumTest
@LargeTest
public void testGetTokenHandlesSuccessWithSomePermissions() {
Bundle bundle = new Bundle();
bundle.putStringArrayList(NativeProtocol.EXTRA_PERMISSIONS, new ArrayList<String>(Arrays.asList("go outside")));
bundle.putLong(NativeProtocol.EXTRA_EXPIRES_SECONDS_SINCE_EPOCH, new Date().getTime() / 1000 + EXPIRES_IN_DELTA);
bundle.putString(NativeProtocol.EXTRA_ACCESS_TOKEN, ACCESS_TOKEN);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.GetTokenAuthHandler handler = client.new GetTokenAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
assertEquals(PERMISSIONS.size(), request.getPermissions().size());
client.setRequest(request);
handler.getTokenCompleted(request, bundle);
assertNull(client.result);
assertTrue(client.triedNextHandler);
assertEquals(1, request.getPermissions().size());
assertTrue(request.getPermissions().contains("come back in"));
}
@SmallTest
@MediumTest
@LargeTest
public void testGetTokenHandlesNoResult() {
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.GetTokenAuthHandler handler = client.new GetTokenAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
assertEquals(PERMISSIONS.size(), request.getPermissions().size());
client.setRequest(request);
handler.getTokenCompleted(request, null);
assertNull(client.result);
assertTrue(client.triedNextHandler);
assertEquals(PERMISSIONS.size(), request.getPermissions().size());
}
// KatanaLoginDialogAuthHandler tests
@SmallTest
@MediumTest
@LargeTest
public void testLoginDialogHandlesSuccess() {
Bundle bundle = new Bundle();
bundle.putStringArrayList(NativeProtocol.EXTRA_PERMISSIONS, PERMISSIONS);
bundle.putLong(NativeProtocol.EXTRA_EXPIRES_SECONDS_SINCE_EPOCH, new Date().getTime() / 1000 + EXPIRES_IN_DELTA);
bundle.putString(NativeProtocol.EXTRA_ACCESS_TOKEN, ACCESS_TOKEN);
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaLoginDialogAuthHandler handler = client.new KatanaLoginDialogAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_OK, intent);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.SUCCESS, client.result.code);
AccessToken token = client.result.token;
assertNotNull(token);
assertEquals(ACCESS_TOKEN, token.getToken());
assertDateDiffersWithinDelta(new Date(), token.getExpires(), EXPIRES_IN_DELTA * 1000, 1000);
assertEquals(PERMISSIONS, token.getPermissions());
}
@SmallTest
@MediumTest
@LargeTest
public void testLoginDialogHandlesCancel() {
Bundle bundle = new Bundle();
bundle.putString(NativeProtocol.STATUS_ERROR_DESCRIPTION, ERROR_MESSAGE);
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaLoginDialogAuthHandler handler = client.new KatanaLoginDialogAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_CANCELED, intent);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.CANCEL, client.result.code);
AccessToken token = client.result.token;
assertNull(token);
assertNotNull(client.result.errorMessage);
assertEquals(ERROR_MESSAGE, client.result.errorMessage);
}
@SmallTest
@MediumTest
@LargeTest
public void testLoginDialogHandlesError() {
Bundle bundle = new Bundle();
bundle.putString(NativeProtocol.STATUS_ERROR_TYPE, ERROR_MESSAGE);
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaLoginDialogAuthHandler handler = client.new KatanaLoginDialogAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_OK, intent);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.ERROR, client.result.code);
AccessToken token = client.result.token;
assertNull(token);
assertNotNull(client.result.errorMessage);
assertEquals(ERROR_MESSAGE, client.result.errorMessage);
}
@SmallTest
@MediumTest
@LargeTest
public void testLoginDialogHandlesDisabled() {
Bundle bundle = new Bundle();
bundle.putInt(NativeProtocol.EXTRA_PROTOCOL_VERSION, NativeProtocol.PROTOCOL_VERSION_20121101);
bundle.putString(NativeProtocol.STATUS_ERROR_TYPE, NativeProtocol.ERROR_SERVICE_DISABLED);
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaLoginDialogAuthHandler handler = client.new KatanaLoginDialogAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_OK, intent);
assertNull(client.result);
assertTrue(client.triedNextHandler);
}
// KatanaProxyAuthHandler tests
@SmallTest
@MediumTest
@LargeTest
public void testProxyAuthHandlesSuccess() {
Bundle bundle = new Bundle();
bundle.putLong(AccessToken.EXPIRES_IN_KEY, EXPIRES_IN_DELTA);
bundle.putString(AccessToken.ACCESS_TOKEN_KEY, ACCESS_TOKEN);
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaProxyAuthHandler handler = client.new KatanaProxyAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_OK, intent);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.SUCCESS, client.result.code);
AccessToken token = client.result.token;
assertNotNull(token);
assertEquals(ACCESS_TOKEN, token.getToken());
assertDateDiffersWithinDelta(new Date(), token.getExpires(), EXPIRES_IN_DELTA * 1000, 1000);
assertEquals(PERMISSIONS, token.getPermissions());
}
@SmallTest
@MediumTest
@LargeTest
public void testProxyAuthHandlesCancel() {
Bundle bundle = new Bundle();
bundle.putString("error", ERROR_MESSAGE);
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaProxyAuthHandler handler = client.new KatanaProxyAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_CANCELED, intent);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.CANCEL, client.result.code);
assertNull(client.result.token);
assertNotNull(client.result.errorMessage);
assertTrue(client.result.errorMessage.contains(ERROR_MESSAGE));
}
@SmallTest
@MediumTest
@LargeTest
public void testProxyAuthHandlesCancelErrorMessage() {
Bundle bundle = new Bundle();
bundle.putString("error", "access_denied");
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaProxyAuthHandler handler = client.new KatanaProxyAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_CANCELED, intent);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.CANCEL, client.result.code);
assertNull(client.result.token);
}
@SmallTest
@MediumTest
@LargeTest
public void testProxyAuthHandlesDisabled() {
Bundle bundle = new Bundle();
bundle.putString("error", "service_disabled");
Intent intent = new Intent();
intent.putExtras(bundle);
MockAuthorizationClient client = new MockAuthorizationClient();
AuthorizationClient.KatanaProxyAuthHandler handler = client.new KatanaProxyAuthHandler();
AuthorizationClient.AuthorizationRequest request = createRequest();
client.setRequest(request);
handler.onActivityResult(0, Activity.RESULT_OK, intent);
assertNull(client.result);
assertTrue(client.triedNextHandler);
}
// Reauthorization validation tests
class MockValidatingAuthorizationClient extends MockAuthorizationClient {
private final HashMap<String, String> mapAccessTokenToFbid = new HashMap<String, String>();
private List<String> permissionsToReport = Arrays.asList();
private TestBlocker blocker;
public MockValidatingAuthorizationClient(TestBlocker blocker) {
this.blocker = blocker;
}
public void addAccessTokenToFbidMapping(String accessToken, String fbid) {
mapAccessTokenToFbid.put(accessToken, fbid);
}
public void addAccessTokenToFbidMapping(AccessToken accessToken, String fbid) {
mapAccessTokenToFbid.put(accessToken.getToken(), fbid);
}
public void setPermissionsToReport(List<String> permissionsToReport) {
this.permissionsToReport = permissionsToReport;
}
@Override
void complete(Result result) {
super.complete(result);
blocker.signal();
}
@Override
Request createGetProfileIdRequest(final String accessToken) {
return new MockRequest() {
@Override
public Response createResponse() {
String fbid = mapAccessTokenToFbid.get(accessToken);
GraphUser user = GraphObject.Factory.create(GraphUser.class);
user.setId(fbid);
return new Response(this, null, user, false);
}
};
}
@Override
Request createGetPermissionsRequest(String accessToken) {
final List<String> permissions = permissionsToReport;
return new MockRequest() {
@Override
public Response createResponse() {
GraphObject permissionsObject = GraphObject.Factory.create();
if (permissions != null) {
for (String permission : permissions) {
permissionsObject.setProperty(permission, 1);
}
}
GraphObjectList<GraphObject> data = GraphObject.Factory.createList(GraphObject.class);
data.add(permissionsObject);
GraphMultiResult result = GraphObject.Factory.create(GraphMultiResult.class);
result.setProperty("data", data);
return new Response(this, null, result, false);
}
};
}
@Override
RequestBatch createReauthValidationBatch(final Result pendingResult) {
RequestBatch batch = super.createReauthValidationBatch(pendingResult);
batch.setCallbackHandler(blocker.getHandler());
// Turn it into a MockRequestBatch.
return new MockRequestBatch(batch);
}
}
static final String USER_1_FBID = "user1";
static final String USER_1_ACCESS_TOKEN = "An access token for user 1";
static final String USER_2_FBID = "user2";
static final String USER_2_ACCESS_TOKEN = "An access token for user 2";
AuthorizationClient.AuthorizationRequest createNewPermissionRequest(String accessToken) {
Session.NewPermissionsRequest request = new Session.NewPermissionsRequest(getActivity(), PERMISSIONS);
request.setValidateSameFbidAsToken(accessToken);
return request.getAuthorizationClientRequest();
}
@MediumTest
@LargeTest
public void testReauthorizationWithSameFbidSucceeds() throws Exception {
TestBlocker blocker = getTestBlocker();
MockValidatingAuthorizationClient client = new MockValidatingAuthorizationClient(blocker);
client.addAccessTokenToFbidMapping(USER_1_ACCESS_TOKEN, USER_1_FBID);
client.addAccessTokenToFbidMapping(USER_2_ACCESS_TOKEN, USER_2_FBID);
client.setPermissionsToReport(PERMISSIONS);
AuthorizationClient.AuthorizationRequest request = createNewPermissionRequest(USER_1_ACCESS_TOKEN);
client.setRequest(request);
AccessToken token = AccessToken.createFromExistingAccessToken(USER_1_ACCESS_TOKEN, null, null, null, PERMISSIONS);
AuthorizationClient.Result result = AuthorizationClient.Result.createTokenResult(token);
client.completeAndValidate(result);
blocker.waitForSignals(1);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.SUCCESS, client.result.code);
AccessToken resultToken = client.result.token;
assertNotNull(resultToken);
assertEquals(USER_1_ACCESS_TOKEN, resultToken.getToken());
assertEquals(PERMISSIONS, resultToken.getPermissions());
}
@MediumTest
@LargeTest
public void testReauthorizationWithFewerPermissionsSucceeds() throws Exception {
TestBlocker blocker = getTestBlocker();
MockValidatingAuthorizationClient client = new MockValidatingAuthorizationClient(blocker);
client.addAccessTokenToFbidMapping(USER_1_ACCESS_TOKEN, USER_1_FBID);
client.addAccessTokenToFbidMapping(USER_2_ACCESS_TOKEN, USER_2_FBID);
client.setPermissionsToReport(Arrays.asList("go outside"));
AuthorizationClient.AuthorizationRequest request = createNewPermissionRequest(USER_1_ACCESS_TOKEN);
client.setRequest(request);
AccessToken token = AccessToken.createFromExistingAccessToken(USER_1_ACCESS_TOKEN, null, null, null, PERMISSIONS);
AuthorizationClient.Result result = AuthorizationClient.Result.createTokenResult(token);
client.completeAndValidate(result);
blocker.waitForSignals(1);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.SUCCESS, client.result.code);
AccessToken resultToken = client.result.token;
assertNotNull(resultToken);
assertEquals(USER_1_ACCESS_TOKEN, resultToken.getToken());
assertEquals(Arrays.asList("go outside"), resultToken.getPermissions());
}
@MediumTest
@LargeTest
public void testReauthorizationWithDifferentFbidsFails() throws Exception {
TestBlocker blocker = getTestBlocker();
MockValidatingAuthorizationClient client = new MockValidatingAuthorizationClient(blocker);
client.addAccessTokenToFbidMapping(USER_1_ACCESS_TOKEN, USER_1_FBID);
client.addAccessTokenToFbidMapping(USER_2_ACCESS_TOKEN, USER_2_FBID);
client.setPermissionsToReport(PERMISSIONS);
AuthorizationClient.AuthorizationRequest request = createNewPermissionRequest(USER_1_ACCESS_TOKEN);
client.setRequest(request);
AccessToken token = AccessToken.createFromExistingAccessToken(USER_2_ACCESS_TOKEN, null, null, null, PERMISSIONS);
AuthorizationClient.Result result = AuthorizationClient.Result.createTokenResult(token);
client.completeAndValidate(result);
blocker.waitForSignals(1);
assertNotNull(client.result);
assertEquals(AuthorizationClient.Result.Code.ERROR, client.result.code);
assertNull(client.result.token);
assertNotNull(client.result.errorMessage);
}
@MediumTest
@LargeTest
public void testLegacyReauthDoesntValidate() throws Exception {
TestBlocker blocker = getTestBlocker();
MockValidatingAuthorizationClient client = new MockValidatingAuthorizationClient(blocker);
AuthorizationClient.AuthorizationRequest request = createNewPermissionRequest(USER_1_ACCESS_TOKEN);
request.setIsLegacy(true);
client.setRequest(request);
AccessToken token = AccessToken.createFromExistingAccessToken(USER_2_ACCESS_TOKEN, null, null, null, PERMISSIONS);
AuthorizationClient.Result result = AuthorizationClient.Result.createTokenResult(token);
client.completeAndValidate(result);
AccessToken resultToken = client.result.token;
assertNotNull(resultToken);
assertEquals(USER_2_ACCESS_TOKEN, resultToken.getToken());
assertEquals(PERMISSIONS, resultToken.getPermissions());
}
// Serialization tests
static class DoNothingAuthorizationClient extends AuthorizationClient {
// Don't actually do anything.
@Override
boolean tryCurrentHandler() {
return true;
}
}
public void testSerialization() throws IOException, ClassNotFoundException {
AuthorizationClient client = new DoNothingAuthorizationClient();
// Call this to set up some state.
client.setContext(getActivity());
client.setOnCompletedListener(new AuthorizationClient.OnCompletedListener() {
@Override
public void onCompleted(AuthorizationClient.Result result) {
}
});
client.setBackgroundProcessingListener(new AuthorizationClient.BackgroundProcessingListener() {
@Override
public void onBackgroundProcessingStarted() {
}
@Override
public void onBackgroundProcessingStopped() {
}
});
client.authorize(createRequest());
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(client);
outputStream.close();
byte [] byteArray = byteArrayOutputStream.toByteArray();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArray);
ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
Object obj = inputStream.readObject();
assertNotNull(obj);
assertTrue(obj instanceof AuthorizationClient);
AuthorizationClient resultClient = (AuthorizationClient)obj;
assertNull(resultClient.startActivityDelegate);
assertNull(resultClient.onCompletedListener);
assertNull(resultClient.backgroundProcessingListener);
assertNull(resultClient.context);
assertNotNull(resultClient.currentHandler);
assertTrue(resultClient.currentHandler instanceof AuthorizationClient.GetTokenAuthHandler);
assertNotNull(resultClient.handlersToTry);
assertTrue(resultClient.handlersToTry.size() > 0);
assertNotNull(resultClient.pendingRequest);
assertEquals(PERMISSIONS, resultClient.pendingRequest.getPermissions());
}
}