Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.content.Context;
import android.content.Intent;

import com.nextcloud.android.common.core.utils.AccountNameUtils;
import com.owncloud.android.MainApp;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.lib.common.OwnCloudAccount;
Expand Down Expand Up @@ -142,8 +143,7 @@ public interface UserAccountManager extends CurrentAccountProvider {
* @return User name (without domain) or null, if name cannot be extracted.
*/
static String getUsername(User user) {
final String name = user.getAccountName();
return name.substring(0, name.lastIndexOf('@'));
return AccountNameUtils.getUserPart(user.getAccountName());
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import android.preference.PreferenceManager;
import android.text.TextUtils;

import com.nextcloud.android.common.core.utils.AccountNameUtils;
import com.nextcloud.client.onboarding.FirstRunActivity;
import com.nextcloud.common.NextcloudClient;
import com.nextcloud.utils.extensions.AccountExtensionsKt;
Expand Down Expand Up @@ -130,52 +131,20 @@ public boolean exists(Account account) {
return false;
}

int lastAtPos = account.name.lastIndexOf('@');
if (lastAtPos == -1) {
Log_OC.d(TAG, "lastAtPos cannot be found");
return false;
}

boolean isLastAtPosInBoundsForHostAndPort = lastAtPos + 1 < account.name.length();
if (!isLastAtPosInBoundsForHostAndPort) {
Log_OC.d(TAG, "lastAtPos not in bounds");
return false;
}

String hostAndPort = account.name.substring(lastAtPos + 1);

String username = account.name.substring(0, lastAtPos);
String username = AccountNameUtils.getUserPart(account.name);
String hostAndPort = AccountNameUtils.getServerPart(account.name);
if (hostAndPort.isEmpty() || username.isEmpty()) {
Log_OC.d(TAG, "hostAndPort or username is empty");
return false;
}

String otherHostAndPort;
String otherUsername;

for (Account otherAccount : nextcloudAccounts) {
// Skip null accounts or accounts with null names
if (otherAccount == null || otherAccount.name.isEmpty()) {
continue;
}

lastAtPos = otherAccount.name.lastIndexOf('@');

// Skip invalid account names
if (lastAtPos == -1) {
continue;
}

boolean isLastAtPosInBoundsForOtherHostAndPort = lastAtPos + 1 < otherAccount.name.length();
if (!isLastAtPosInBoundsForOtherHostAndPort) {
continue;
}
otherHostAndPort = otherAccount.name.substring(lastAtPos + 1);

otherUsername = otherAccount.name.substring(0, lastAtPos);

if (otherHostAndPort.equals(hostAndPort) &&
otherUsername.equalsIgnoreCase(username)) {
if (hostAndPort.equals(AccountNameUtils.getServerPart(otherAccount.name)) &&
username.equalsIgnoreCase(AccountNameUtils.getUserPart(otherAccount.name))) {
return true;
}
}
Expand Down Expand Up @@ -396,7 +365,16 @@ public void resetOwnCloudAccount() {
@Override
public boolean accountOwnsFile(OCFile file, Account account) {
final String ownerId = file.getOwnerId();
return TextUtils.isEmpty(ownerId) || account.name.split("@")[0].equalsIgnoreCase(ownerId);
if (TextUtils.isEmpty(ownerId)) {
return true;
}

String userId = accountManager.getUserData(account, AccountUtils.Constants.KEY_USER_ID);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the key_user_id always the same like account.name?
I think this can be different.
Account can be tobias@mail.com@server.com
-> name tobias@mail.com
-> userId (internal userid from server) might then be tobias or ldap id.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KEY_USER_ID is not same like account.name always and this is right comparison. Otherwise it will fail like old code.

see, this only set via authenticator code:

Image

Old code should fail via LDAP for example. We are checking here file belongs this account or not that's all.

if (TextUtils.isEmpty(userId)) {
return !file.isSharedWithMe();
}

return ownerId.equalsIgnoreCase(userId);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package com.nextcloud.client.files

import android.net.Uri
import com.nextcloud.android.common.core.utils.AccountNameUtils
import com.nextcloud.client.account.User
import com.nextcloud.client.account.UserAccountManager

Expand Down Expand Up @@ -53,5 +54,5 @@ class DeepLinkHandler(private val userAccountManager: UserAccountManager) {
}

private fun getMatchingUsers(serverBaseUrl: String): List<User> =
userAccountManager.allUsers.filter { it.server.uri.toString() == serverBaseUrl }
userAccountManager.allUsers.filter { AccountNameUtils.isSameServer(it.server.uri.toString(), serverBaseUrl) }
}
5 changes: 3 additions & 2 deletions app/src/main/java/com/nextcloud/utils/avatar/AvatarRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

package com.nextcloud.utils.avatar

import com.nextcloud.android.common.core.utils.AccountNameUtils
import com.nextcloud.client.account.User

data class AvatarRequest(val user: User, val userId: String, val displayName: String?, val avatarRadius: Float) {
val serverName: String = user.accountName.substringAfterLast('@')
val serverName: String = AccountNameUtils.getServerPart(user.accountName)

val accountName: String = "$userId@$serverName"
val accountName: String = AccountNameUtils.build(userId, serverName)

fun cacheKey(eTag: String): String = "a_${userId}_${serverName}_$eTag"
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import android.util.Log;
import android.widget.Toast;

import com.nextcloud.android.common.core.utils.AccountNameUtils;
import com.nextcloud.client.account.User;
import com.nextcloud.client.account.UserAccountManager;
import com.owncloud.android.R;
Expand Down Expand Up @@ -293,10 +294,9 @@ private Cursor searchForUsersOrGroups(Uri uri) {
displayName = name;
subline = getContext().getString(R.string.remote);
} else {
String[] uriSplitted = shareWith.split("@");
displayName = name;
subline = getContext().getString(R.string.share_known_remote_on_clarification,
uriSplitted[uriSplitted.length - 1]);
AccountNameUtils.getServerPart(shareWith));
}
}
break;
Expand All @@ -311,10 +311,9 @@ private Cursor searchForUsersOrGroups(Uri uri) {
subline = getContext().getString(R.string.remote);
subline = "";
} else {
String[] uriSplitted = shareWith.split("@");
displayName = name;
subline = getContext().getString(R.string.share_known_remote_on_clarification,
uriSplitted[uriSplitted.length - 1]);
AccountNameUtils.getServerPart(shareWith));
}
}
break;
Expand Down Expand Up @@ -404,9 +403,10 @@ public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) thr
String userId = uri.getQueryParameter("shareWith");
String displayName = uri.getQueryParameter("displayName");
String accountName = accountManager.getUser().getAccountName();
String serverName = accountName.substring(accountName.lastIndexOf('@') + 1);
String serverName = AccountNameUtils.getServerPart(accountName);

String eTag = arbitraryDataProvider.getValue(userId + "@" + serverName, ThumbnailsCacheManager.AVATAR);
String eTag = arbitraryDataProvider.getValue(AccountNameUtils.build(userId, serverName),
ThumbnailsCacheManager.AVATAR);
String avatarKey = "a_" + userId + "_" + serverName + "_" + eTag;

StatusType status = StatusType.valueOf(uri.getQueryParameter("status"));
Expand Down
10 changes: 5 additions & 5 deletions app/src/main/java/com/owncloud/android/ui/AvatarGroupLayout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.view.updateLayoutParams
import com.nextcloud.android.common.ui.theme.utils.ColorRole
import com.nextcloud.android.common.core.utils.AccountNameUtils
import com.nextcloud.client.account.User
import com.nextcloud.utils.GlideHelper.loadCircularBitmapIntoImageView
import com.nextcloud.utils.avatar.AvatarGenerationListener
Expand Down Expand Up @@ -81,7 +82,7 @@ class AvatarGroupLayout @JvmOverloads constructor(

val avatarCount = sharees.size.coerceAtMost(MAX_AVATAR_COUNT)
val hasOverflow = sharees.size > MAX_AVATAR_COUNT
val serverName = user.accountName.substringAfterLast('@')
val serverName = AccountNameUtils.getServerPart(user.accountName)

repeat(avatarCount) { index ->
val avatar = addAvatarView(index)
Expand Down Expand Up @@ -130,7 +131,7 @@ class AvatarGroupLayout @JvmOverloads constructor(

else -> {
val userId = checkNotNull(sharee.userId)
avatar.tag = "$userId@$serverName"
avatar.tag = AccountNameUtils.build(userId, serverName)
avatarGenerator.setUserAvatar(
userId,
this,
Expand All @@ -145,9 +146,8 @@ class AvatarGroupLayout @JvmOverloads constructor(
}

private fun showFederatedShareAvatar(federatedId: String, avatar: ImageView, viewThemeUtils: ViewThemeUtils) {
val parts = federatedId.split("@")
val userId = parts.first()
val url = parts.getOrNull(1)?.let { server ->
val userId = AccountNameUtils.getUserPart(federatedId)
val url = AccountNameUtils.getServerPart(federatedId).ifEmpty { null }?.let { server ->
"https://$server/index.php/avatar/$userId/${resources.getInteger(R.integer.file_avatar_px)}"
}
val placeholder = createFederatedPlaceholder(userId, viewThemeUtils)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3123,34 +3123,32 @@ class FileDisplayActivity :
val intentData = intent.data
if (userName == null && fileId == null && intentData != null) {
openDeepLink(intentData)
} else {
val optionalUser = if (userName == null) user else userAccountManager.getUser(userName)
if (optionalUser.isPresent) {
if (!TextUtils.isEmpty(fileId)) {
openFile(optionalUser.get(), fileId)
} else if (!TextUtils.isEmpty(filePath)) {
openFileByPath(optionalUser.get(), filePath)
} else {
accountClicked(optionalUser.get())
}
} else {
SnackbarUtil.show(this, getString(R.string.associated_account_not_found))
}
return
}

val optionalUser = if (userName == null) user else userAccountManager.getUser(userName)
val targetUser = optionalUser.orElse(null) ?: run {
SnackbarUtil.show(this, getString(R.string.associated_account_not_found))
return
}

when {
!fileId.isNullOrEmpty() -> openFile(targetUser, fileId)
!filePath.isNullOrEmpty() -> openFileByPath(targetUser, filePath)
else -> accountClicked(targetUser)
}
}

private fun openDeepLink(uri: Uri) {
val linkHandler = DeepLinkHandler(userAccountManager)
val match = linkHandler.parseDeepLink(uri)

if (match == null) {
val match = DeepLinkHandler(userAccountManager).parseDeepLink(uri) ?: run {
handleDeepLink(uri)
} else if (match.users.isEmpty()) {
SnackbarUtil.show(this, getString(R.string.associated_account_not_found))
} else if (match.users.size == SINGLE_USER_SIZE) {
openFile(match.users[0], match.fileId)
} else {
selectUserAndOpenFile(match.users.toMutableList(), match.fileId)
return
}

when {
match.users.isEmpty() -> SnackbarUtil.show(this, getString(R.string.associated_account_not_found))
match.users.size == SINGLE_USER_SIZE -> openFile(match.users.first(), match.fileId)
else -> selectUserAndOpenFile(match.users.toMutableList(), match.fileId)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.android.common.core.utils.AccountNameUtils
import com.nextcloud.client.account.User
import com.nextcloud.utils.avatar.AvatarGenerationListener
import com.nextcloud.utils.avatar.AvatarGenerator
Expand Down Expand Up @@ -156,7 +157,7 @@ class ShareeListAdapter(
override fun shouldCallGeneratedCallback(tag: String?, callContext: Any?): Boolean {
if (callContext is ImageView) {
// needs to be changed once federated users have avatars
return callContext.tag.toString() == tag?.substringBefore('@')
return callContext.tag.toString() == tag?.let(AccountNameUtils::getUserPart)
}
return false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.nextcloud.android.lib.resources.profile.Action
import com.nextcloud.android.lib.resources.profile.HoverCard
import com.nextcloud.android.common.core.utils.AccountNameUtils
import com.nextcloud.client.account.User
import com.nextcloud.client.utils.IntentUtil
import com.nextcloud.utils.avatar.AvatarGenerationListener
Expand Down Expand Up @@ -188,7 +189,7 @@ class ProfileBottomSheetDialog(
override fun shouldCallGeneratedCallback(tag: String?, callContext: Any?): Boolean {
if (callContext is ImageView) {
// needs to be changed once federated users have avatars
return callContext.tag.toString() == tag!!.split("@").toTypedArray()[0]
return callContext.tag.toString() == tag?.let(AccountNameUtils::getUserPart)
}
return false
}
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: AGPL-3.0-or-later

[versions]
androidCommonLibraryVersion = "0.34.0"
androidCommonLibraryVersion = "f6515c1c36"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: change after merging upstream?

androidGifDrawableVersion = "1.2.32"
androidImageCropperVersion = "4.7.0"
androidLibraryVersion ="a15346847d3f03c8b17932bc4acf2124a2f82b81"
Expand Down
29 changes: 29 additions & 0 deletions gradle/verification-metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24290,6 +24290,14 @@
<sha256 value="274d2e0e4771f95d44fb02beac00da2059e76f1aeca7f573cfb4f5634cbd8593" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="com.github.nextcloud.android-common" name="core" version="f6515c1c36">
<artifact name="core-f6515c1c36.aar">
<sha256 value="4ef33d9ec973b53f73048c914cd8018eb5da9a47eeb637795d0e9b9da5c77dbe" origin="Generated by Gradle"/>
</artifact>
<artifact name="core-f6515c1c36.module">
<sha256 value="d3108f02040359dd61a176473c71817d0373f19eddeed003162c5c7d7661126a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.github.nextcloud.android-common" name="material-color-utilities" version="0.13.0">
<artifact name="material-color-utilities-0.13.0.jar">
<sha256 value="d0e932c5de6e2aefd4c0a66caa86df4bc6c582189e67de95ede894ed1adb9367" origin="Generated by Gradle" reason="Artifact is not signed"/>
Expand Down Expand Up @@ -24590,6 +24598,14 @@
<sha256 value="562c5c6a413aa811e1353013c1b5e6fe56477eabdf361611c5f6aea8d39071e3" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="com.github.nextcloud.android-common" name="material-color-utilities" version="f6515c1c36">
<artifact name="material-color-utilities-f6515c1c36.jar">
<sha256 value="b901a9fdcc750cd912686ce7cdcadc03ceec7391ca0cdbddc356de3966672c9a" origin="Generated by Gradle"/>
</artifact>
<artifact name="material-color-utilities-f6515c1c36.module">
<sha256 value="478bea3c849d5ae8578584b11ebf8cd9b30f4c67c52b80380456fd0413b7b5a3" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.github.nextcloud.android-common" name="ui" version="0.13.0">
<artifact name="ui-0.13.0.aar">
<sha256 value="4d73e91f3692d9f1d34d89d8a87d91e632f18e6366ec9f1fec6b0648bc4f25ea" origin="Generated by Gradle" reason="Artifact is not signed"/>
Expand Down Expand Up @@ -24886,6 +24902,14 @@
<sha256 value="8507e07778e080278bc88b786232b1ad9c64129567d5410f7b14df45ce6ecf41" origin="Generated by Gradle" reason="Artifact is not signed"/>
</artifact>
</component>
<component group="com.github.nextcloud.android-common" name="ui" version="f6515c1c36">
<artifact name="ui-f6515c1c36.aar">
<sha256 value="495bf1ba3278c14210e5dfca4e11dbb9ae10bedac67031fc5a006348649dbf46" origin="Generated by Gradle"/>
</artifact>
<artifact name="ui-f6515c1c36.module">
<sha256 value="bd5e8341b2dd1b2aed46f163d524dd3714533058d2c1d5dd2c1a25a22b0cd74f" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.github.oowekyala.ooxml" name="nice-xml-messages" version="3.1">
<artifact name="nice-xml-messages-3.1.jar">
<sha256 value="0b4ceb5b8362d43c9c6c49b1bd57f1c5da54d3c5c7c305fa39c0a04462bb4799" origin="Generated by Gradle" reason="A key couldn't be downloaded"/>
Expand Down Expand Up @@ -29766,6 +29790,11 @@
<sha256 value="f80588e52a2f780da6082b0518a30dbfb756f2992258c9cba77bc51612e98505" origin="Generated by Gradle" reason="A key couldn't be downloaded"/>
</artifact>
</component>
<component group="com.squareup.okhttp3" name="okhttp-bom" version="5.5.1">
<artifact name="okhttp-bom-5.5.1.module">
<sha256 value="89f62b594c03a8ea35381bdf85c1a143e0b6ff359cbab334a67a6a50395f1a65" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.squareup.okhttp3" name="okhttp-jvm" version="5.0.0-alpha.12">
<artifact name="okhttp-jvm-5.0.0-alpha.12.jar">
<sha256 value="05bea20bc7831d1507612b12b82ba94a06750711ed1d6f092bc37e0b8a0d1276" origin="Generated by Gradle"/>
Expand Down
Loading