123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- /*
- * Nextcloud Android client application
- *
- * @author David Luhmer
- * @author Andy Scherzinger
- * Copyright (C) 2018 David Luhmer
- * Copyright (C) 2018 Andy Scherzinger
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero 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 Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- package com.owncloud.android.ui.activity;
- import android.accounts.Account;
- import android.accounts.AccountManager;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.content.pm.ApplicationInfo;
- import android.content.pm.PackageManager;
- import android.graphics.Color;
- import android.graphics.Typeface;
- import android.graphics.drawable.Drawable;
- import android.os.Bundle;
- import android.text.Spannable;
- import android.text.SpannableStringBuilder;
- import android.text.style.ForegroundColorSpan;
- import android.text.style.StyleSpan;
- import android.util.Log;
- import android.widget.Button;
- import android.widget.ImageView;
- import android.widget.TextView;
- import com.nextcloud.android.sso.Constants;
- import com.owncloud.android.MainApp;
- import com.owncloud.android.R;
- import com.owncloud.android.lib.common.OwnCloudAccount;
- import com.owncloud.android.lib.common.accounts.AccountUtils;
- import com.owncloud.android.lib.common.utils.Log_OC;
- import com.owncloud.android.utils.EncryptionUtils;
- import com.owncloud.android.utils.ThemeUtils;
- import java.util.UUID;
- import butterknife.BindView;
- import butterknife.ButterKnife;
- import butterknife.OnClick;
- import butterknife.Unbinder;
- import static com.nextcloud.android.sso.Constants.EXCEPTION_ACCOUNT_ACCESS_DECLINED;
- import static com.nextcloud.android.sso.Constants.EXCEPTION_ACCOUNT_NOT_FOUND;
- import static com.nextcloud.android.sso.Constants.NEXTCLOUD_FILES_ACCOUNT;
- import static com.nextcloud.android.sso.Constants.NEXTCLOUD_SSO;
- import static com.nextcloud.android.sso.Constants.NEXTCLOUD_SSO_EXCEPTION;
- import static com.nextcloud.android.sso.Constants.SSO_SHARED_PREFERENCE;
- /**
- * Activity for granting access rights to a Nextcloud account, used for SSO.
- */
- public class SsoGrantPermissionActivity extends BaseActivity {
- private static final String TAG = SsoGrantPermissionActivity.class.getCanonicalName();
- private String packageName;
- private Account account;
- private Unbinder unbinder;
- @BindView(R.id.appIcon)
- ImageView appIcon;
- @BindView(R.id.permissionText)
- TextView permissionText;
- @BindView(R.id.btnGrant)
- Button grantPermissionButton;
- @BindView(R.id.btnDecline)
- Button declinePermissionButton;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_sso_grant_permission);
- unbinder = ButterKnife.bind(this);
- ComponentName callingActivity = getCallingActivity();
- if (callingActivity != null) {
- packageName = callingActivity.getPackageName();
- String appName = getAppNameForPackage(packageName);
- account = getIntent().getParcelableExtra(NEXTCLOUD_FILES_ACCOUNT);
- permissionText.setText(makeSpecialPartsBold(
- getString(R.string.single_sign_on_request_token, appName, account.name),
- appName,
- account.name)
- );
- Log.v(TAG, "TOKEN-REQUEST: Calling Package: " + packageName);
- Log.v(TAG, "TOKEN-REQUEST: App Name: " + appName);
- } else {
- // Activity was not started using startActivityForResult!
- Log.e(TAG, "Calling Package is null");
- setResultAndExit("Request was not executed properly. Use startActivityForResult()");
- }
- try {
- if (packageName != null) {
- Drawable appIcon = getPackageManager().getApplicationIcon(packageName);
- this.appIcon.setImageDrawable(appIcon);
- }
- } catch (PackageManager.NameNotFoundException e) {
- Log.e(TAG, e.getMessage());
- }
- int primaryColor = ThemeUtils.primaryColor(this, true);
- grantPermissionButton.setTextColor(primaryColor);
- declinePermissionButton.setTextColor(primaryColor);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- unbinder.unbind();
- }
- private SpannableStringBuilder makeSpecialPartsBold(String text, String... toBeStyledText) {
- SpannableStringBuilder ssb = new SpannableStringBuilder(text);
- for (String textBlock : toBeStyledText) {
- int start = text.indexOf(textBlock);
- int end = start + textBlock.length();
- ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, 0);
- ssb.setSpan(new ForegroundColorSpan(Color.BLACK), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- return ssb;
- }
- private void setResultAndExit(String exception) {
- Intent data = new Intent();
- data.putExtra(NEXTCLOUD_SSO_EXCEPTION, exception);
- setResult(RESULT_CANCELED, data);
- finish();
- }
- private String getAppNameForPackage(String pkg) {
- final PackageManager pm = getApplicationContext().getPackageManager();
- ApplicationInfo ai = null;
- try {
- ai = pm.getApplicationInfo(pkg, 0);
- } catch (final PackageManager.NameNotFoundException e) {
- Log.e(TAG, e.getMessage());
- }
- return (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
- }
- @OnClick(R.id.btnDecline)
- void exitFailed() {
- setResultAndExit(EXCEPTION_ACCOUNT_ACCESS_DECLINED);
- }
- @OnClick(R.id.btnGrant)
- void grantPermission() {
- // create token
- SharedPreferences sharedPreferences = getSharedPreferences(SSO_SHARED_PREFERENCE, Context.MODE_PRIVATE);
- String token = UUID.randomUUID().toString().replaceAll("-", "");
- String hashedTokenWithSalt = EncryptionUtils.generateSHA512(token);
- SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.putString(packageName, hashedTokenWithSalt);
- editor.apply();
- String serverUrl;
- String userId;
- try {
- OwnCloudAccount ocAccount = new OwnCloudAccount(account, this);
- serverUrl = ocAccount.getBaseUri().toString();
- AccountManager accountManager = AccountManager.get(this);
- userId = accountManager.getUserData(account,
- com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
- } catch (AccountUtils.AccountNotFoundException e) {
- Log_OC.e(TAG, "Account not found");
- setResultAndExit(EXCEPTION_ACCOUNT_NOT_FOUND);
- return;
- }
- final Bundle result = new Bundle();
- result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
- result.putString(AccountManager.KEY_ACCOUNT_TYPE, MainApp.getAccountType(this));
- result.putString(AccountManager.KEY_AUTHTOKEN, NEXTCLOUD_SSO);
- result.putString(Constants.SSO_USERNAME, userId);
- result.putString(Constants.SSO_TOKEN, token);
- result.putString(Constants.SSO_SERVER_URL, serverUrl);
- Intent data = new Intent();
- data.putExtra(NEXTCLOUD_SSO, result);
- setResult(RESULT_OK, data);
- finish();
- }
- }
|