diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/database/DataBaseAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/database/DataBaseAdapter.java index 942afd4a1..1149316eb 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/database/DataBaseAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/database/DataBaseAdapter.java @@ -426,9 +426,8 @@ public void updateUser(long accountId, User user, boolean setStatus) { @WorkerThread public UserForAssignment getUserForAssignmentDirectly(long localUserId) { SimpleSQLiteQuery query = new SimpleSQLiteQuery( - "SELECT case when acl.type is null then 0 else 1 end as type, u.uid as userId " + + "SELECT u.type as type, u.uid as userId " + "FROM User u " + - "left join AccessControl acl on acl.userId = u.localId " + " WHERE u.localId = ? LIMIT 1", new Object[]{localUserId}); return db.getUserInGroupDao().getUserForAssignment(query); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/database/DeckDatabase.java b/app/src/main/java/it/niedermann/nextcloud/deck/database/DeckDatabase.java index a41379e8d..021cea921 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/database/DeckDatabase.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/database/DeckDatabase.java @@ -66,6 +66,7 @@ import it.niedermann.nextcloud.deck.database.migration.Migration_30_31; import it.niedermann.nextcloud.deck.database.migration.Migration_31_32; import it.niedermann.nextcloud.deck.database.migration.Migration_32_33; +import it.niedermann.nextcloud.deck.database.migration.Migration_33_34; import it.niedermann.nextcloud.deck.database.migration.Migration_8_9; import it.niedermann.nextcloud.deck.database.migration.Migration_9_10; import it.niedermann.nextcloud.deck.model.AccessControl; @@ -136,7 +137,7 @@ FilterWidgetSort.class, }, exportSchema = false, - version = 33 + version = 34 ) @TypeConverters({DateTypeConverter.class, EnumConverter.class}) public abstract class DeckDatabase extends RoomDatabase { @@ -190,6 +191,7 @@ private static DeckDatabase create(final Context context) { .addMigrations(new Migration_30_31()) .addMigrations(new Migration_31_32(context)) .addMigrations(new Migration_32_33()) + .addMigrations(new Migration_33_34()) .fallbackToDestructiveMigration() .addCallback(ON_CREATE_CALLBACK) .build(); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_33_34.java b/app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_33_34.java new file mode 100644 index 000000000..4bf45d667 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/database/migration/Migration_33_34.java @@ -0,0 +1,22 @@ +package it.niedermann.nextcloud.deck.database.migration; + +import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + +/** + * Adds support for marking a card as done: https://github.com/stefan-niedermann/nextcloud-deck/issues/1556 + */ +public class Migration_33_34 extends Migration { + + public Migration_33_34() { + super(33, 34); + } + + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("ALTER TABLE `User` add column type INTEGER not null default 0"); + // Reset ETags to refetch Users + database.execSQL("UPDATE `Account` SET `boardsEtag` = NULL"); + } +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/User.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/User.java index 6d2381d82..28fa91a05 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/User.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/User.java @@ -6,7 +6,6 @@ import androidx.room.Index; import java.io.Serializable; -import java.util.Objects; import it.niedermann.nextcloud.deck.model.interfaces.AbstractRemoteEntity; @@ -24,10 +23,13 @@ ) public class User extends AbstractRemoteEntity implements Serializable { + public static final long TYPE_USER = 0L; + public static final long TYPE_GROUP = 1L; private String primaryKey; private String uid; private String displayname; + private long type; public User() { super(); @@ -44,6 +46,7 @@ public User(User user) { super(user); this.primaryKey = user.getPrimaryKey(); this.uid = user.getUid(); + this.type = user.getType(); this.displayname = user.getDisplayname(); } @@ -71,24 +74,32 @@ public void setDisplayname(String displayname) { this.displayname = displayname; } + public long getType() { + return type; + } + + public void setType(long type) { + this.type = type; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; User user = (User) o; - - if (!Objects.equals(primaryKey, user.primaryKey)) - return false; - if (!Objects.equals(uid, user.uid)) return false; - return Objects.equals(displayname, user.displayname); + return type == user.type && primaryKey.equals(user.primaryKey) && + uid.equals(user.uid) && displayname.equals(user.displayname); } @Override public int hashCode() { - int result = primaryKey != null ? primaryKey.hashCode() : 0; - result = 31 * result + (uid != null ? uid.hashCode() : 0); - result = 31 * result + (displayname != null ? displayname.hashCode() : 0); + int result = super.hashCode(); + result = 31 * result + primaryKey.hashCode(); + result = 31 * result + uid.hashCode(); + result = 31 * result + displayname.hashCode(); + result = 31 * result + Long.hashCode(type); return result; } @@ -98,12 +109,14 @@ public String toString() { "primaryKey='" + primaryKey + '\'' + ", uid='" + uid + '\'' + ", displayname='" + displayname + '\'' + + ", type=" + type + ", localId=" + localId + ", accountId=" + accountId + ", id=" + id + ", status=" + status + ", lastModified=" + lastModified + ", lastModifiedLocal=" + lastModifiedLocal + + ", etag='" + etag + '\'' + "} " + super.toString(); } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/user/OcsUserList.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/user/OcsUserList.java index 818d5b96e..3173a366e 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/user/OcsUserList.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/ocs/user/OcsUserList.java @@ -5,6 +5,7 @@ public class OcsUserList { private List users = new ArrayList<>(); + private List groups = new ArrayList<>(); public List getUsers() { return users; @@ -13,4 +14,12 @@ public List getUsers() { public void addUser(OcsUser user) { this.users.add(user); } + + public List getGroups() { + return groups; + } + + public void addGroup(OcsUser user) { + this.groups.add(user); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/GsonConfig.java b/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/GsonConfig.java index fb3d58a6b..cb84349e5 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/GsonConfig.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/GsonConfig.java @@ -2,6 +2,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.google.gson.Strictness; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; @@ -55,7 +56,7 @@ public class GsonConfig { INSTANCE = new GsonBuilder() .setDateFormat(DATE_PATTERN) - .setLenient() + .setStrictness(Strictness.LENIENT) .registerTypeAdapter(Instant.class, new GsonUTCInstantAdapter()) .registerTypeAdapter(boardList, new NextcloudArrayDeserializer<>("boards", FullBoard.class)) .registerTypeAdapter(board, new NextcloudDeserializer<>("board", FullBoard.class)) diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/JsonToEntityParser.java b/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/JsonToEntityParser.java index 83c458ffe..64827b69d 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/JsonToEntityParser.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/remote/api/JsonToEntityParser.java @@ -114,6 +114,19 @@ private static OcsUserList parseOcsUserList(JsonObject obj) { ocsUserList.addUser(user); } } + JsonElement groups = data.getAsJsonObject().get("groups"); + if (!groups.isJsonNull() && groups.isJsonArray()) { + for (JsonElement userElement : groups.getAsJsonArray()) { + JsonObject singleGroupElement = userElement.getAsJsonObject(); + OcsUser group = new OcsUser(); + group.setDisplayName(singleGroupElement.get("label").getAsString()); + group.setId( + singleGroupElement.get("value").getAsJsonObject() + .get("shareWith").getAsString() + ); + ocsUserList.addGroup(group); + } + } } }, obj); @@ -523,6 +536,7 @@ protected static User parseUser(JsonElement userElement) { user.setDisplayname(getNullAsEmptyString(userJson.get("displayname"))); user.setPrimaryKey(getNullAsEmptyString(userJson.get("primaryKey"))); user.setUid(getNullAsEmptyString(userJson.get("uid"))); + user.setType(getNullAsZero(userJson.get("type"))); } }, userElement); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/remote/helpers/providers/BoardDataProvider.java b/app/src/main/java/it/niedermann/nextcloud/deck/remote/helpers/providers/BoardDataProvider.java index 15eabd7a7..dd4c691d0 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/remote/helpers/providers/BoardDataProvider.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/remote/helpers/providers/BoardDataProvider.java @@ -17,11 +17,15 @@ import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.database.DataBaseAdapter; import it.niedermann.nextcloud.deck.model.AccessControl; +import it.niedermann.nextcloud.deck.model.Account; import it.niedermann.nextcloud.deck.model.Board; import it.niedermann.nextcloud.deck.model.Label; import it.niedermann.nextcloud.deck.model.User; +import it.niedermann.nextcloud.deck.model.enums.DBStatus; import it.niedermann.nextcloud.deck.model.full.FullBoard; import it.niedermann.nextcloud.deck.model.full.FullStack; +import it.niedermann.nextcloud.deck.model.ocs.user.OcsUser; +import it.niedermann.nextcloud.deck.model.ocs.user.OcsUserList; import it.niedermann.nextcloud.deck.remote.adapters.ServerAdapter; import it.niedermann.nextcloud.deck.remote.api.IResponseCallback; import it.niedermann.nextcloud.deck.remote.api.ResponseCallback; @@ -64,6 +68,7 @@ public void onResponse(List response, Headers headers) { if (etag != null && !etag.equals(account.getBoardsEtag())) { account.setBoardsEtag(etag); dataBaseAdapter.updateAccount(account); + updateUsers(serverAdapter, dataBaseAdapter, responder.getAccount()); } List ret = response; if (response != null) { @@ -85,6 +90,29 @@ public void onError(Throwable throwable) { }); } + private void updateUsers(ServerAdapter serverAdapter, DataBaseAdapter dataBaseAdapter, Account account) { + serverAdapter.searchUser("", new ResponseCallback<>(account) { + @Override + public void onResponse(OcsUserList response, Headers headers) { + Long accountId = account.getId(); + for (OcsUser u : response.getUsers()) { + User user = new User(u.getId(), u.getId(), u.getDisplayName()); + user.setType(User.TYPE_USER); + user.setAccountId(accountId); + user.setStatus(DBStatus.UP_TO_DATE.getId()); + createOrUpdateUser(dataBaseAdapter, accountId, user); + } + for (OcsUser u : response.getGroups()) { + User user = new User(u.getId(), u.getId(), u.getDisplayName()); + user.setType(User.TYPE_GROUP); + user.setAccountId(accountId); + user.setStatus(DBStatus.UP_TO_DATE.getId()); + createOrUpdateUser(dataBaseAdapter, accountId, user); + } + } + }); + } + private void updateProgress() { if (progress != null) { DeckLog.log("New progress post", progressDone, progressTotal); @@ -142,6 +170,7 @@ private User createOrUpdateUser(DataBaseAdapter dataBaseAdapter, long accountId, if (owner == null) { dataBaseAdapter.createUser(accountId, remoteUser); } else { + remoteUser.setLocalId(owner.getLocalId()); dataBaseAdapter.updateUser(accountId, remoteUser, false); } return dataBaseAdapter.getUserByUidDirectly(accountId, remoteUser.getUid()); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/repository/SyncRepository.java b/app/src/main/java/it/niedermann/nextcloud/deck/repository/SyncRepository.java index 86eae7e03..8b55bbe00 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/repository/SyncRepository.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/repository/SyncRepository.java @@ -1335,10 +1335,23 @@ public void onResponse(OcsUserList response, Headers headers) { newUser.setStatus(DBStatus.UP_TO_DATE.getId()); newUser.setPrimaryKey(user.getId()); newUser.setUid(user.getId()); + newUser.setType(User.TYPE_USER); newUser.setDisplayname(user.getDisplayName()); dataBaseAdapter.createUser(account.getId(), newUser); } } + for (var group : response.getGroups()) { + final var existingGroup = dataBaseAdapter.getUserByUidDirectly(account.getId(), group.getId()); + if (existingGroup == null) { + User newGroup = new User(); + newGroup.setStatus(DBStatus.UP_TO_DATE.getId()); + newGroup.setPrimaryKey(group.getId()); + newGroup.setUid(group.getId()); + newGroup.setType(User.TYPE_GROUP); + newGroup.setDisplayname(group.getDisplayName()); + dataBaseAdapter.createUser(account.getId(), newGroup); + } + } } @Override diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/accesscontrol/AccessControlDialogFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/accesscontrol/AccessControlDialogFragment.java index 08c2dd11c..b4081f164 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/accesscontrol/AccessControlDialogFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/board/accesscontrol/AccessControlDialogFragment.java @@ -168,7 +168,7 @@ public void onItemClick(AdapterView parent, View view, int position, long id) final User user = userAutoCompleteAdapter.getItem(position); ac.setPermissionEdit(true); ac.setBoardId(boardId); - ac.setType(0L); // https://github.com/nextcloud/deck/blob/master/docs/API.md#post-boardsboardidacl---add-new-acl-rule + ac.setType(user.getType()); // https://github.com/nextcloud/deck/blob/master/docs/API.md#post-boardsboardidacl---add-new-acl-rule ac.setUserId(user.getLocalId()); ac.setUser(user); accessControlViewModel.createAccessControl(account, ac, new IResponseCallback<>() { diff --git a/app/src/test/java/it/niedermann/nextcloud/deck/database/dao/UserDaoTest.java b/app/src/test/java/it/niedermann/nextcloud/deck/database/dao/UserDaoTest.java index 02fda1ae0..56fa7ab35 100644 --- a/app/src/test/java/it/niedermann/nextcloud/deck/database/dao/UserDaoTest.java +++ b/app/src/test/java/it/niedermann/nextcloud/deck/database/dao/UserDaoTest.java @@ -19,6 +19,7 @@ public void writeAndReadUser() { final var userToCreate = new User(); userToCreate.setDisplayname("Test Tester"); userToCreate.setUid("test"); + userToCreate.setType(User.TYPE_USER); userToCreate.setAccountId(account.getId()); db.getUserDao().insert(userToCreate);