SsoGrantPermissionActivity.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * Nextcloud Android client application
  3. *
  4. * @author David Luhmer
  5. * @author Andy Scherzinger
  6. * Copyright (C) 2018 David Luhmer
  7. * Copyright (C) 2018 Andy Scherzinger
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. package com.owncloud.android.ui.activity;
  23. import android.accounts.Account;
  24. import android.accounts.AccountManager;
  25. import android.content.ComponentName;
  26. import android.content.Context;
  27. import android.content.Intent;
  28. import android.content.SharedPreferences;
  29. import android.content.pm.ApplicationInfo;
  30. import android.content.pm.PackageManager;
  31. import android.graphics.Color;
  32. import android.graphics.Typeface;
  33. import android.graphics.drawable.Drawable;
  34. import android.os.Bundle;
  35. import android.text.Spannable;
  36. import android.text.SpannableStringBuilder;
  37. import android.text.style.ForegroundColorSpan;
  38. import android.text.style.StyleSpan;
  39. import android.util.Log;
  40. import android.widget.Button;
  41. import android.widget.ImageView;
  42. import android.widget.TextView;
  43. import com.nextcloud.android.sso.Constants;
  44. import com.owncloud.android.MainApp;
  45. import com.owncloud.android.R;
  46. import com.owncloud.android.lib.common.OwnCloudAccount;
  47. import com.owncloud.android.lib.common.accounts.AccountUtils;
  48. import com.owncloud.android.lib.common.utils.Log_OC;
  49. import com.owncloud.android.utils.EncryptionUtils;
  50. import com.owncloud.android.utils.ThemeUtils;
  51. import java.util.UUID;
  52. import butterknife.BindView;
  53. import butterknife.ButterKnife;
  54. import butterknife.OnClick;
  55. import butterknife.Unbinder;
  56. import static com.nextcloud.android.sso.Constants.EXCEPTION_ACCOUNT_ACCESS_DECLINED;
  57. import static com.nextcloud.android.sso.Constants.EXCEPTION_ACCOUNT_NOT_FOUND;
  58. import static com.nextcloud.android.sso.Constants.NEXTCLOUD_FILES_ACCOUNT;
  59. import static com.nextcloud.android.sso.Constants.NEXTCLOUD_SSO;
  60. import static com.nextcloud.android.sso.Constants.NEXTCLOUD_SSO_EXCEPTION;
  61. import static com.nextcloud.android.sso.Constants.SSO_SHARED_PREFERENCE;
  62. /**
  63. * Activity for granting access rights to a Nextcloud account, used for SSO.
  64. */
  65. public class SsoGrantPermissionActivity extends BaseActivity {
  66. private static final String TAG = SsoGrantPermissionActivity.class.getCanonicalName();
  67. private String packageName;
  68. private Account account;
  69. private Unbinder unbinder;
  70. @BindView(R.id.appIcon)
  71. ImageView appIcon;
  72. @BindView(R.id.permissionText)
  73. TextView permissionText;
  74. @BindView(R.id.btnGrant)
  75. Button grantPermissionButton;
  76. @BindView(R.id.btnDecline)
  77. Button declinePermissionButton;
  78. @Override
  79. protected void onCreate(Bundle savedInstanceState) {
  80. super.onCreate(savedInstanceState);
  81. setContentView(R.layout.activity_sso_grant_permission);
  82. unbinder = ButterKnife.bind(this);
  83. ComponentName callingActivity = getCallingActivity();
  84. if (callingActivity != null) {
  85. packageName = callingActivity.getPackageName();
  86. String appName = getAppNameForPackage(packageName);
  87. account = getIntent().getParcelableExtra(NEXTCLOUD_FILES_ACCOUNT);
  88. permissionText.setText(makeSpecialPartsBold(
  89. getString(R.string.single_sign_on_request_token, appName, account.name),
  90. appName,
  91. account.name)
  92. );
  93. Log.v(TAG, "TOKEN-REQUEST: Calling Package: " + packageName);
  94. Log.v(TAG, "TOKEN-REQUEST: App Name: " + appName);
  95. } else {
  96. // Activity was not started using startActivityForResult!
  97. Log.e(TAG, "Calling Package is null");
  98. setResultAndExit("Request was not executed properly. Use startActivityForResult()");
  99. }
  100. try {
  101. if (packageName != null) {
  102. Drawable appIcon = getPackageManager().getApplicationIcon(packageName);
  103. this.appIcon.setImageDrawable(appIcon);
  104. }
  105. } catch (PackageManager.NameNotFoundException e) {
  106. Log.e(TAG, e.getMessage());
  107. }
  108. int primaryColor = ThemeUtils.primaryColor(this, true);
  109. grantPermissionButton.setTextColor(primaryColor);
  110. declinePermissionButton.setTextColor(primaryColor);
  111. }
  112. @Override
  113. protected void onDestroy() {
  114. super.onDestroy();
  115. unbinder.unbind();
  116. }
  117. private SpannableStringBuilder makeSpecialPartsBold(String text, String... toBeStyledText) {
  118. SpannableStringBuilder ssb = new SpannableStringBuilder(text);
  119. for (String textBlock : toBeStyledText) {
  120. int start = text.indexOf(textBlock);
  121. int end = start + textBlock.length();
  122. ssb.setSpan(new StyleSpan(Typeface.BOLD), start, end, 0);
  123. ssb.setSpan(new ForegroundColorSpan(Color.BLACK), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  124. }
  125. return ssb;
  126. }
  127. private void setResultAndExit(String exception) {
  128. Intent data = new Intent();
  129. data.putExtra(NEXTCLOUD_SSO_EXCEPTION, exception);
  130. setResult(RESULT_CANCELED, data);
  131. finish();
  132. }
  133. private String getAppNameForPackage(String pkg) {
  134. final PackageManager pm = getApplicationContext().getPackageManager();
  135. ApplicationInfo ai = null;
  136. try {
  137. ai = pm.getApplicationInfo(pkg, 0);
  138. } catch (final PackageManager.NameNotFoundException e) {
  139. Log.e(TAG, e.getMessage());
  140. }
  141. return (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
  142. }
  143. @OnClick(R.id.btnDecline)
  144. void exitFailed() {
  145. setResultAndExit(EXCEPTION_ACCOUNT_ACCESS_DECLINED);
  146. }
  147. @OnClick(R.id.btnGrant)
  148. void grantPermission() {
  149. // create token
  150. SharedPreferences sharedPreferences = getSharedPreferences(SSO_SHARED_PREFERENCE, Context.MODE_PRIVATE);
  151. String token = UUID.randomUUID().toString().replaceAll("-", "");
  152. String hashedTokenWithSalt = EncryptionUtils.generateSHA512(token);
  153. SharedPreferences.Editor editor = sharedPreferences.edit();
  154. editor.putString(packageName, hashedTokenWithSalt);
  155. editor.apply();
  156. String serverUrl;
  157. String userId;
  158. try {
  159. OwnCloudAccount ocAccount = new OwnCloudAccount(account, this);
  160. serverUrl = ocAccount.getBaseUri().toString();
  161. AccountManager accountManager = AccountManager.get(this);
  162. userId = accountManager.getUserData(account,
  163. com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
  164. } catch (AccountUtils.AccountNotFoundException e) {
  165. Log_OC.e(TAG, "Account not found");
  166. setResultAndExit(EXCEPTION_ACCOUNT_NOT_FOUND);
  167. return;
  168. }
  169. final Bundle result = new Bundle();
  170. result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
  171. result.putString(AccountManager.KEY_ACCOUNT_TYPE, MainApp.getAccountType(this));
  172. result.putString(AccountManager.KEY_AUTHTOKEN, NEXTCLOUD_SSO);
  173. result.putString(Constants.SSO_USERNAME, userId);
  174. result.putString(Constants.SSO_TOKEN, token);
  175. result.putString(Constants.SSO_SERVER_URL, serverUrl);
  176. Intent data = new Intent();
  177. data.putExtra(NEXTCLOUD_SSO, result);
  178. setResult(RESULT_OK, data);
  179. finish();
  180. }
  181. }