Update database and UI to support S3
This commit is contained in:
parent
b0f288f479
commit
a736a33d88
@ -74,7 +74,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
greendao {
|
greendao {
|
||||||
schemaVersion 5
|
schemaVersion 6
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
configurations.all {
|
||||||
|
@ -10,7 +10,7 @@ import org.cryptomator.domain.repository.CloudContentRepository;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import static org.cryptomator.domain.CloudType.PCLOUD;
|
import static org.cryptomator.domain.CloudType.S3;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class S3CloudContentRepositoryFactory implements CloudContentRepositoryFactory {
|
public class S3CloudContentRepositoryFactory implements CloudContentRepositoryFactory {
|
||||||
@ -24,7 +24,7 @@ public class S3CloudContentRepositoryFactory implements CloudContentRepositoryFa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(Cloud cloud) {
|
public boolean supports(Cloud cloud) {
|
||||||
return cloud.type() == PCLOUD;
|
return cloud.type() == S3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -23,14 +23,16 @@ class DatabaseUpgrades {
|
|||||||
Upgrade1To2 upgrade1To2, //
|
Upgrade1To2 upgrade1To2, //
|
||||||
Upgrade2To3 upgrade2To3, //
|
Upgrade2To3 upgrade2To3, //
|
||||||
Upgrade3To4 upgrade3To4, //
|
Upgrade3To4 upgrade3To4, //
|
||||||
Upgrade4To5 upgrade4To5) {
|
Upgrade4To5 upgrade4To5, //
|
||||||
|
Upgrade5To6 upgrade5To6) {
|
||||||
|
|
||||||
availableUpgrades = defineUpgrades( //
|
availableUpgrades = defineUpgrades( //
|
||||||
upgrade0To1, //
|
upgrade0To1, //
|
||||||
upgrade1To2, //
|
upgrade1To2, //
|
||||||
upgrade2To3, //
|
upgrade2To3, //
|
||||||
upgrade3To4, //
|
upgrade3To4, //
|
||||||
upgrade4To5);
|
upgrade4To5, //
|
||||||
|
upgrade5To6);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Comparator<DatabaseUpgrade> reverseOrder() {
|
private static Comparator<DatabaseUpgrade> reverseOrder() {
|
||||||
|
76
data/src/main/java/org/cryptomator/data/db/Upgrade5To6.kt
Normal file
76
data/src/main/java/org/cryptomator/data/db/Upgrade5To6.kt
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package org.cryptomator.data.db
|
||||||
|
|
||||||
|
import org.greenrobot.greendao.database.Database
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
internal class Upgrade5To6 @Inject constructor() : DatabaseUpgrade(5, 6) {
|
||||||
|
|
||||||
|
override fun internalApplyTo(db: Database, origin: Int) {
|
||||||
|
db.beginTransaction()
|
||||||
|
try {
|
||||||
|
changeWebdavUrlInCloudEntityToUrl(db)
|
||||||
|
db.setTransactionSuccessful()
|
||||||
|
} finally {
|
||||||
|
db.endTransaction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun changeWebdavUrlInCloudEntityToUrl(db: Database) {
|
||||||
|
Sql.alterTable("CLOUD_ENTITY").renameTo("CLOUD_ENTITY_OLD").executeOn(db)
|
||||||
|
|
||||||
|
Sql.createTable("CLOUD_ENTITY") //
|
||||||
|
.id() //
|
||||||
|
.requiredText("TYPE") //
|
||||||
|
.optionalText("ACCESS_TOKEN") //
|
||||||
|
.optionalText("URL") //
|
||||||
|
.optionalText("USERNAME") //
|
||||||
|
.optionalText("WEBDAV_CERTIFICATE") //
|
||||||
|
.optionalText("S3_BUCKET") //
|
||||||
|
.optionalText("S3_REGION") //
|
||||||
|
.optionalText("S3_SECRET_KEY") //
|
||||||
|
.executeOn(db);
|
||||||
|
|
||||||
|
Sql.insertInto("CLOUD_ENTITY") //
|
||||||
|
.select("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") //
|
||||||
|
.columns("_id", "TYPE", "ACCESS_TOKEN", "URL", "USERNAME", "WEBDAV_CERTIFICATE") //
|
||||||
|
.from("CLOUD_ENTITY_OLD") //
|
||||||
|
.executeOn(db)
|
||||||
|
|
||||||
|
recreateVaultEntity(db)
|
||||||
|
|
||||||
|
Sql.dropTable("CLOUD_ENTITY_OLD").executeOn(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun recreateVaultEntity(db: Database) {
|
||||||
|
Sql.alterTable("VAULT_ENTITY").renameTo("VAULT_ENTITY_OLD").executeOn(db)
|
||||||
|
Sql.createTable("VAULT_ENTITY") //
|
||||||
|
.id() //
|
||||||
|
.optionalInt("FOLDER_CLOUD_ID") //
|
||||||
|
.optionalText("FOLDER_PATH") //
|
||||||
|
.optionalText("FOLDER_NAME") //
|
||||||
|
.requiredText("CLOUD_TYPE") //
|
||||||
|
.optionalText("PASSWORD") //
|
||||||
|
.optionalInt("POSITION") //
|
||||||
|
.foreignKey("FOLDER_CLOUD_ID", "CLOUD_ENTITY", Sql.SqlCreateTableBuilder.ForeignKeyBehaviour.ON_DELETE_SET_NULL) //
|
||||||
|
.executeOn(db)
|
||||||
|
|
||||||
|
Sql.insertInto("VAULT_ENTITY") //
|
||||||
|
.select("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_ENTITY.TYPE") //
|
||||||
|
.columns("_id", "FOLDER_CLOUD_ID", "FOLDER_PATH", "FOLDER_NAME", "PASSWORD", "POSITION", "CLOUD_TYPE") //
|
||||||
|
.from("VAULT_ENTITY_OLD") //
|
||||||
|
.join("CLOUD_ENTITY", "VAULT_ENTITY_OLD.FOLDER_CLOUD_ID") //
|
||||||
|
.executeOn(db)
|
||||||
|
|
||||||
|
Sql.dropIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID").executeOn(db)
|
||||||
|
|
||||||
|
Sql.createUniqueIndex("IDX_VAULT_ENTITY_FOLDER_PATH_FOLDER_CLOUD_ID") //
|
||||||
|
.on("VAULT_ENTITY") //
|
||||||
|
.asc("FOLDER_PATH") //
|
||||||
|
.asc("FOLDER_CLOUD_ID") //
|
||||||
|
.executeOn(db)
|
||||||
|
|
||||||
|
Sql.dropTable("VAULT_ENTITY_OLD").executeOn(db)
|
||||||
|
}
|
||||||
|
}
|
@ -22,14 +22,23 @@ public class CloudEntity extends DatabaseEntity {
|
|||||||
|
|
||||||
private String webdavCertificate;
|
private String webdavCertificate;
|
||||||
|
|
||||||
@Generated(hash = 361171073)
|
private String s3Bucket;
|
||||||
public CloudEntity(Long id, @NotNull String type, String accessToken, String url, String username, String webdavCertificate) {
|
|
||||||
|
private String s3Region;
|
||||||
|
|
||||||
|
private String s3SecretKey;
|
||||||
|
|
||||||
|
@Generated(hash = 1685351705)
|
||||||
|
public CloudEntity(Long id, @NotNull String type, String accessToken, String url, String username, String webdavCertificate, String s3Bucket, String s3Region, String s3SecretKey) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.username = username;
|
this.username = username;
|
||||||
this.webdavCertificate = webdavCertificate;
|
this.webdavCertificate = webdavCertificate;
|
||||||
|
this.s3Bucket = s3Bucket;
|
||||||
|
this.s3Region = s3Region;
|
||||||
|
this.s3SecretKey = s3SecretKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Generated(hash = 1354152224)
|
@Generated(hash = 1354152224)
|
||||||
@ -83,4 +92,28 @@ public class CloudEntity extends DatabaseEntity {
|
|||||||
public void setWebdavCertificate(String webdavCertificate) {
|
public void setWebdavCertificate(String webdavCertificate) {
|
||||||
this.webdavCertificate = webdavCertificate;
|
this.webdavCertificate = webdavCertificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getS3Bucket() {
|
||||||
|
return this.s3Bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setS3Bucket(String s3Bucket) {
|
||||||
|
this.s3Bucket = s3Bucket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getS3Region() {
|
||||||
|
return this.s3Region;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setS3Region(String s3Region) {
|
||||||
|
this.s3Region = s3Region;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getS3SecretKey() {
|
||||||
|
return this.s3SecretKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setS3SecretKey(String s3SecretKey) {
|
||||||
|
this.s3SecretKey = s3SecretKey;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,9 +182,7 @@ public class VaultEntity extends DatabaseEntity {
|
|||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** called by internal mechanisms, do not call yourself. */
|
||||||
* called by internal mechanisms, do not call yourself.
|
|
||||||
*/
|
|
||||||
@Generated(hash = 674742652)
|
@Generated(hash = 674742652)
|
||||||
public void __setDaoSession(DaoSession daoSession) {
|
public void __setDaoSession(DaoSession daoSession) {
|
||||||
this.daoSession = daoSession;
|
this.daoSession = daoSession;
|
||||||
|
@ -8,6 +8,7 @@ import org.cryptomator.domain.GoogleDriveCloud;
|
|||||||
import org.cryptomator.domain.LocalStorageCloud;
|
import org.cryptomator.domain.LocalStorageCloud;
|
||||||
import org.cryptomator.domain.OnedriveCloud;
|
import org.cryptomator.domain.OnedriveCloud;
|
||||||
import org.cryptomator.domain.PCloud;
|
import org.cryptomator.domain.PCloud;
|
||||||
|
import org.cryptomator.domain.S3Cloud;
|
||||||
import org.cryptomator.domain.WebDavCloud;
|
import org.cryptomator.domain.WebDavCloud;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -18,6 +19,7 @@ import static org.cryptomator.domain.GoogleDriveCloud.aGoogleDriveCloud;
|
|||||||
import static org.cryptomator.domain.LocalStorageCloud.aLocalStorage;
|
import static org.cryptomator.domain.LocalStorageCloud.aLocalStorage;
|
||||||
import static org.cryptomator.domain.OnedriveCloud.aOnedriveCloud;
|
import static org.cryptomator.domain.OnedriveCloud.aOnedriveCloud;
|
||||||
import static org.cryptomator.domain.PCloud.aPCloud;
|
import static org.cryptomator.domain.PCloud.aPCloud;
|
||||||
|
import static org.cryptomator.domain.S3Cloud.aS3Cloud;
|
||||||
import static org.cryptomator.domain.WebDavCloud.aWebDavCloudCloud;
|
import static org.cryptomator.domain.WebDavCloud.aWebDavCloudCloud;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@ -43,6 +45,10 @@ public class CloudEntityMapper extends EntityMapper<CloudEntity, Cloud> {
|
|||||||
.withAccessToken(entity.getAccessToken()) //
|
.withAccessToken(entity.getAccessToken()) //
|
||||||
.withUsername(entity.getUsername()) //
|
.withUsername(entity.getUsername()) //
|
||||||
.build();
|
.build();
|
||||||
|
case LOCAL:
|
||||||
|
return aLocalStorage() //
|
||||||
|
.withId(entity.getId()) //
|
||||||
|
.withRootUri(entity.getAccessToken()).build();
|
||||||
case ONEDRIVE:
|
case ONEDRIVE:
|
||||||
return aOnedriveCloud() //
|
return aOnedriveCloud() //
|
||||||
.withId(entity.getId()) //
|
.withId(entity.getId()) //
|
||||||
@ -56,10 +62,15 @@ public class CloudEntityMapper extends EntityMapper<CloudEntity, Cloud> {
|
|||||||
.withAccessToken(entity.getAccessToken()) //
|
.withAccessToken(entity.getAccessToken()) //
|
||||||
.withUsername(entity.getUsername()) //
|
.withUsername(entity.getUsername()) //
|
||||||
.build();
|
.build();
|
||||||
case LOCAL:
|
case S3:
|
||||||
return aLocalStorage() //
|
aS3Cloud() //
|
||||||
.withId(entity.getId()) //
|
.withId(entity.getId()) //
|
||||||
.withRootUri(entity.getAccessToken()).build();
|
.withS3Endpoint(entity.getUrl()) //
|
||||||
|
.withS3Region(entity.getS3Region()) //
|
||||||
|
.withAccessKey(entity.getAccessToken()) //
|
||||||
|
.withSecretKey(entity.getS3SecretKey()) //
|
||||||
|
.withS3Bucket(entity.getS3Bucket()) //
|
||||||
|
.build();
|
||||||
case WEBDAV:
|
case WEBDAV:
|
||||||
return aWebDavCloudCloud() //
|
return aWebDavCloudCloud() //
|
||||||
.withId(entity.getId()) //
|
.withId(entity.getId()) //
|
||||||
@ -87,6 +98,9 @@ public class CloudEntityMapper extends EntityMapper<CloudEntity, Cloud> {
|
|||||||
result.setAccessToken(((GoogleDriveCloud) domainObject).accessToken());
|
result.setAccessToken(((GoogleDriveCloud) domainObject).accessToken());
|
||||||
result.setUsername(((GoogleDriveCloud) domainObject).username());
|
result.setUsername(((GoogleDriveCloud) domainObject).username());
|
||||||
break;
|
break;
|
||||||
|
case LOCAL:
|
||||||
|
result.setAccessToken(((LocalStorageCloud) domainObject).rootUri());
|
||||||
|
break;
|
||||||
case ONEDRIVE:
|
case ONEDRIVE:
|
||||||
result.setAccessToken(((OnedriveCloud) domainObject).accessToken());
|
result.setAccessToken(((OnedriveCloud) domainObject).accessToken());
|
||||||
result.setUsername(((OnedriveCloud) domainObject).username());
|
result.setUsername(((OnedriveCloud) domainObject).username());
|
||||||
@ -96,8 +110,12 @@ public class CloudEntityMapper extends EntityMapper<CloudEntity, Cloud> {
|
|||||||
result.setUrl(((PCloud) domainObject).url());
|
result.setUrl(((PCloud) domainObject).url());
|
||||||
result.setUsername(((PCloud) domainObject).username());
|
result.setUsername(((PCloud) domainObject).username());
|
||||||
break;
|
break;
|
||||||
case LOCAL:
|
case S3:
|
||||||
result.setAccessToken(((LocalStorageCloud) domainObject).rootUri());
|
result.setUrl(((S3Cloud) domainObject).s3Endpoint());
|
||||||
|
result.setS3Region(((S3Cloud) domainObject).s3Region());
|
||||||
|
result.setAccessToken(((S3Cloud) domainObject).accessKey());
|
||||||
|
result.setS3SecretKey(((S3Cloud) domainObject).secretKey());
|
||||||
|
result.setS3Bucket(((S3Cloud) domainObject).s3Bucket());
|
||||||
break;
|
break;
|
||||||
case WEBDAV:
|
case WEBDAV:
|
||||||
result.setAccessToken(((WebDavCloud) domainObject).password());
|
result.setAccessToken(((WebDavCloud) domainObject).password());
|
||||||
|
@ -6,6 +6,7 @@ import org.cryptomator.data.cloud.googledrive.GoogleDriveCloudContentRepositoryF
|
|||||||
import org.cryptomator.data.cloud.local.LocalStorageContentRepositoryFactory;
|
import org.cryptomator.data.cloud.local.LocalStorageContentRepositoryFactory;
|
||||||
import org.cryptomator.data.cloud.onedrive.OnedriveCloudContentRepositoryFactory;
|
import org.cryptomator.data.cloud.onedrive.OnedriveCloudContentRepositoryFactory;
|
||||||
import org.cryptomator.data.cloud.pcloud.PCloudContentRepositoryFactory;
|
import org.cryptomator.data.cloud.pcloud.PCloudContentRepositoryFactory;
|
||||||
|
import org.cryptomator.data.cloud.s3.S3CloudContentRepositoryFactory;
|
||||||
import org.cryptomator.data.cloud.webdav.WebDavCloudContentRepositoryFactory;
|
import org.cryptomator.data.cloud.webdav.WebDavCloudContentRepositoryFactory;
|
||||||
import org.cryptomator.data.repository.CloudContentRepositoryFactory;
|
import org.cryptomator.data.repository.CloudContentRepositoryFactory;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -27,6 +28,7 @@ public class CloudContentRepositoryFactories implements Iterable<CloudContentRep
|
|||||||
GoogleDriveCloudContentRepositoryFactory googleDriveFactory, //
|
GoogleDriveCloudContentRepositoryFactory googleDriveFactory, //
|
||||||
OnedriveCloudContentRepositoryFactory oneDriveFactory, //
|
OnedriveCloudContentRepositoryFactory oneDriveFactory, //
|
||||||
PCloudContentRepositoryFactory pCloudFactory, //
|
PCloudContentRepositoryFactory pCloudFactory, //
|
||||||
|
S3CloudContentRepositoryFactory s3Factory, //
|
||||||
CryptoCloudContentRepositoryFactory cryptoFactory, //
|
CryptoCloudContentRepositoryFactory cryptoFactory, //
|
||||||
LocalStorageContentRepositoryFactory localStorageFactory, //
|
LocalStorageContentRepositoryFactory localStorageFactory, //
|
||||||
WebDavCloudContentRepositoryFactory webDavFactory) {
|
WebDavCloudContentRepositoryFactory webDavFactory) {
|
||||||
@ -35,6 +37,7 @@ public class CloudContentRepositoryFactories implements Iterable<CloudContentRep
|
|||||||
googleDriveFactory, //
|
googleDriveFactory, //
|
||||||
oneDriveFactory, //
|
oneDriveFactory, //
|
||||||
pCloudFactory, //
|
pCloudFactory, //
|
||||||
|
s3Factory, //
|
||||||
cryptoFactory, //
|
cryptoFactory, //
|
||||||
localStorageFactory, //
|
localStorageFactory, //
|
||||||
webDavFactory);
|
webDavFactory);
|
||||||
|
@ -2,6 +2,6 @@ package org.cryptomator.domain;
|
|||||||
|
|
||||||
public enum CloudType {
|
public enum CloudType {
|
||||||
|
|
||||||
DROPBOX, GOOGLE_DRIVE, ONEDRIVE, PCLOUD, WEBDAV, LOCAL, CRYPTO
|
DROPBOX, GOOGLE_DRIVE, ONEDRIVE, PCLOUD, WEBDAV, LOCAL, S3, CRYPTO
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ public class S3Cloud implements Cloud {
|
|||||||
this.s3Region = builder.s3Region;
|
this.s3Region = builder.s3Region;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder aPCloud() {
|
public static Builder aS3Cloud() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ public class S3Cloud implements Cloud {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CloudType type() {
|
public CloudType type() {
|
||||||
return CloudType.PCLOUD;
|
return CloudType.S3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package org.cryptomator.domain.usecases.cloud;
|
||||||
|
|
||||||
|
import org.cryptomator.domain.S3Cloud;
|
||||||
|
import org.cryptomator.domain.exception.BackendException;
|
||||||
|
import org.cryptomator.domain.repository.CloudContentRepository;
|
||||||
|
import org.cryptomator.generator.Parameter;
|
||||||
|
import org.cryptomator.generator.UseCase;
|
||||||
|
|
||||||
|
@UseCase
|
||||||
|
class ConnectToS3 {
|
||||||
|
|
||||||
|
private final CloudContentRepository cloudContentRepository;
|
||||||
|
private final S3Cloud cloud;
|
||||||
|
|
||||||
|
public ConnectToS3(CloudContentRepository cloudContentRepository, @Parameter S3Cloud cloud) {
|
||||||
|
this.cloudContentRepository = cloudContentRepository;
|
||||||
|
this.cloud = cloud;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute() throws BackendException {
|
||||||
|
cloudContentRepository.checkAuthenticationAndRetrieveCurrentAccount(cloud);
|
||||||
|
}
|
||||||
|
}
|
@ -108,6 +108,7 @@
|
|||||||
<activity android:name=".ui.activity.LicensesActivity" />
|
<activity android:name=".ui.activity.LicensesActivity" />
|
||||||
<activity android:name=".ui.activity.SettingsActivity" />
|
<activity android:name=".ui.activity.SettingsActivity" />
|
||||||
<activity android:name=".ui.activity.WebDavAddOrChangeActivity" />
|
<activity android:name=".ui.activity.WebDavAddOrChangeActivity" />
|
||||||
|
<activity android:name=".ui.activity.S3AddOrChangeActivity" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.AuthenticateCloudActivity"
|
android:name=".ui.activity.AuthenticateCloudActivity"
|
||||||
|
@ -16,6 +16,7 @@ import org.cryptomator.presentation.ui.activity.EmptyDirIdFileInfoActivity;
|
|||||||
import org.cryptomator.presentation.ui.activity.ImagePreviewActivity;
|
import org.cryptomator.presentation.ui.activity.ImagePreviewActivity;
|
||||||
import org.cryptomator.presentation.ui.activity.LicenseCheckActivity;
|
import org.cryptomator.presentation.ui.activity.LicenseCheckActivity;
|
||||||
import org.cryptomator.presentation.ui.activity.LicensesActivity;
|
import org.cryptomator.presentation.ui.activity.LicensesActivity;
|
||||||
|
import org.cryptomator.presentation.ui.activity.S3AddOrChangeActivity;
|
||||||
import org.cryptomator.presentation.ui.activity.SetPasswordActivity;
|
import org.cryptomator.presentation.ui.activity.SetPasswordActivity;
|
||||||
import org.cryptomator.presentation.ui.activity.SettingsActivity;
|
import org.cryptomator.presentation.ui.activity.SettingsActivity;
|
||||||
import org.cryptomator.presentation.ui.activity.SharedFilesActivity;
|
import org.cryptomator.presentation.ui.activity.SharedFilesActivity;
|
||||||
@ -31,6 +32,7 @@ import org.cryptomator.presentation.ui.fragment.CloudConnectionListFragment;
|
|||||||
import org.cryptomator.presentation.ui.fragment.CloudSettingsFragment;
|
import org.cryptomator.presentation.ui.fragment.CloudSettingsFragment;
|
||||||
import org.cryptomator.presentation.ui.fragment.EmptyDirIdFileInfoFragment;
|
import org.cryptomator.presentation.ui.fragment.EmptyDirIdFileInfoFragment;
|
||||||
import org.cryptomator.presentation.ui.fragment.ImagePreviewFragment;
|
import org.cryptomator.presentation.ui.fragment.ImagePreviewFragment;
|
||||||
|
import org.cryptomator.presentation.ui.fragment.S3AddOrChangeFragment;
|
||||||
import org.cryptomator.presentation.ui.fragment.SetPasswordFragment;
|
import org.cryptomator.presentation.ui.fragment.SetPasswordFragment;
|
||||||
import org.cryptomator.presentation.ui.fragment.SharedFilesFragment;
|
import org.cryptomator.presentation.ui.fragment.SharedFilesFragment;
|
||||||
import org.cryptomator.presentation.ui.fragment.TextEditorFragment;
|
import org.cryptomator.presentation.ui.fragment.TextEditorFragment;
|
||||||
@ -114,4 +116,8 @@ public interface ActivityComponent {
|
|||||||
void inject(AutoUploadChooseVaultFragment autoUploadChooseVaultFragment);
|
void inject(AutoUploadChooseVaultFragment autoUploadChooseVaultFragment);
|
||||||
|
|
||||||
void inject(LicenseCheckActivity licenseCheckActivity);
|
void inject(LicenseCheckActivity licenseCheckActivity);
|
||||||
|
|
||||||
|
void inject(S3AddOrChangeActivity s3AddOrChangeActivity);
|
||||||
|
|
||||||
|
void inject(S3AddOrChangeFragment s3AddOrChangeFragment);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
package org.cryptomator.presentation.intent;
|
||||||
|
|
||||||
|
import org.cryptomator.generator.Intent;
|
||||||
|
import org.cryptomator.generator.Optional;
|
||||||
|
import org.cryptomator.presentation.model.S3CloudModel;
|
||||||
|
import org.cryptomator.presentation.ui.activity.S3AddOrChangeActivity;
|
||||||
|
|
||||||
|
@Intent(S3AddOrChangeActivity.class)
|
||||||
|
public interface S3AddOrChangeIntent {
|
||||||
|
|
||||||
|
@Optional
|
||||||
|
S3CloudModel s3Cloud();
|
||||||
|
}
|
@ -28,6 +28,11 @@ enum class CloudTypeModel(builder: Builder) {
|
|||||||
.withVaultImageResource(R.drawable.webdav_vault) //
|
.withVaultImageResource(R.drawable.webdav_vault) //
|
||||||
.withVaultSelectedImageResource(R.drawable.webdav_vault_selected) //
|
.withVaultSelectedImageResource(R.drawable.webdav_vault_selected) //
|
||||||
.withMultiInstances()), //
|
.withMultiInstances()), //
|
||||||
|
S3(Builder("S3", R.string.cloud_names_s3) //
|
||||||
|
.withCloudImageResource(R.drawable.webdav) //
|
||||||
|
.withVaultImageResource(R.drawable.webdav_vault) //
|
||||||
|
.withVaultSelectedImageResource(R.drawable.webdav_vault_selected) //
|
||||||
|
.withMultiInstances()), //
|
||||||
LOCAL(Builder("LOCAL", R.string.cloud_names_local_storage) //
|
LOCAL(Builder("LOCAL", R.string.cloud_names_local_storage) //
|
||||||
.withCloudImageResource(R.drawable.local_fs) //
|
.withCloudImageResource(R.drawable.local_fs) //
|
||||||
.withVaultImageResource(R.drawable.local_fs_vault) //
|
.withVaultImageResource(R.drawable.local_fs_vault) //
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package org.cryptomator.presentation.model
|
||||||
|
|
||||||
|
import org.cryptomator.domain.Cloud
|
||||||
|
import org.cryptomator.domain.S3Cloud
|
||||||
|
import org.cryptomator.presentation.R
|
||||||
|
|
||||||
|
class S3CloudModel(cloud: Cloud) : CloudModel(cloud) {
|
||||||
|
|
||||||
|
override fun name(): Int {
|
||||||
|
return R.string.cloud_names_s3
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun username(): String? {
|
||||||
|
return "" // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cloudType(): CloudTypeModel {
|
||||||
|
return CloudTypeModel.S3
|
||||||
|
}
|
||||||
|
|
||||||
|
fun id(): Long {
|
||||||
|
return cloud().id()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun accessKey(): String {
|
||||||
|
return cloud().accessKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun secretKey(): String {
|
||||||
|
return cloud().secretKey()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun s3Bucket(): String {
|
||||||
|
return cloud().s3Bucket()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun s3Endpoint(): String {
|
||||||
|
return cloud().s3Endpoint()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun s3Region(): String {
|
||||||
|
return cloud().s3Region()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cloud(): S3Cloud {
|
||||||
|
return toCloud() as S3Cloud
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ import org.cryptomator.presentation.model.GoogleDriveCloudModel
|
|||||||
import org.cryptomator.presentation.model.LocalStorageModel
|
import org.cryptomator.presentation.model.LocalStorageModel
|
||||||
import org.cryptomator.presentation.model.OnedriveCloudModel
|
import org.cryptomator.presentation.model.OnedriveCloudModel
|
||||||
import org.cryptomator.presentation.model.PCloudModel
|
import org.cryptomator.presentation.model.PCloudModel
|
||||||
|
import org.cryptomator.presentation.model.S3CloudModel
|
||||||
import org.cryptomator.presentation.model.WebDavCloudModel
|
import org.cryptomator.presentation.model.WebDavCloudModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -24,10 +25,11 @@ class CloudModelMapper @Inject constructor() : ModelMapper<CloudModel, Cloud>()
|
|||||||
return when (CloudTypeModel.valueOf(domainObject.type())) {
|
return when (CloudTypeModel.valueOf(domainObject.type())) {
|
||||||
CloudTypeModel.DROPBOX -> DropboxCloudModel(domainObject)
|
CloudTypeModel.DROPBOX -> DropboxCloudModel(domainObject)
|
||||||
CloudTypeModel.GOOGLE_DRIVE -> GoogleDriveCloudModel(domainObject)
|
CloudTypeModel.GOOGLE_DRIVE -> GoogleDriveCloudModel(domainObject)
|
||||||
|
CloudTypeModel.LOCAL -> LocalStorageModel(domainObject)
|
||||||
CloudTypeModel.ONEDRIVE -> OnedriveCloudModel(domainObject)
|
CloudTypeModel.ONEDRIVE -> OnedriveCloudModel(domainObject)
|
||||||
CloudTypeModel.PCLOUD -> PCloudModel(domainObject)
|
CloudTypeModel.PCLOUD -> PCloudModel(domainObject)
|
||||||
|
CloudTypeModel.S3 -> S3CloudModel(domainObject)
|
||||||
CloudTypeModel.CRYPTO -> CryptoCloudModel(domainObject)
|
CloudTypeModel.CRYPTO -> CryptoCloudModel(domainObject)
|
||||||
CloudTypeModel.LOCAL -> LocalStorageModel(domainObject)
|
|
||||||
CloudTypeModel.WEBDAV -> WebDavCloudModel(domainObject)
|
CloudTypeModel.WEBDAV -> WebDavCloudModel(domainObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import org.cryptomator.presentation.intent.Intents
|
|||||||
import org.cryptomator.presentation.model.CloudModel
|
import org.cryptomator.presentation.model.CloudModel
|
||||||
import org.cryptomator.presentation.model.CloudTypeModel
|
import org.cryptomator.presentation.model.CloudTypeModel
|
||||||
import org.cryptomator.presentation.model.LocalStorageModel
|
import org.cryptomator.presentation.model.LocalStorageModel
|
||||||
|
import org.cryptomator.presentation.model.S3CloudModel
|
||||||
import org.cryptomator.presentation.model.WebDavCloudModel
|
import org.cryptomator.presentation.model.WebDavCloudModel
|
||||||
import org.cryptomator.presentation.model.mappers.CloudModelMapper
|
import org.cryptomator.presentation.model.mappers.CloudModelMapper
|
||||||
import org.cryptomator.presentation.ui.activity.view.CloudConnectionListView
|
import org.cryptomator.presentation.ui.activity.view.CloudConnectionListView
|
||||||
@ -129,7 +130,7 @@ class CloudConnectionListPresenter @Inject constructor( //
|
|||||||
|
|
||||||
fun onAddConnectionClicked() {
|
fun onAddConnectionClicked() {
|
||||||
when (selectedCloudType.get()) {
|
when (selectedCloudType.get()) {
|
||||||
CloudTypeModel.WEBDAV -> requestActivityResult(ActivityResultCallbacks.addChangeWebDavCloud(), //
|
CloudTypeModel.WEBDAV -> requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), //
|
||||||
Intents.webDavAddOrChangeIntent())
|
Intents.webDavAddOrChangeIntent())
|
||||||
CloudTypeModel.PCLOUD -> {
|
CloudTypeModel.PCLOUD -> {
|
||||||
val authIntent: Intent = AuthorizationActivity.createIntent(
|
val authIntent: Intent = AuthorizationActivity.createIntent(
|
||||||
@ -143,6 +144,8 @@ class CloudConnectionListPresenter @Inject constructor( //
|
|||||||
requestActivityResult(ActivityResultCallbacks.pCloudAuthenticationFinished(), //
|
requestActivityResult(ActivityResultCallbacks.pCloudAuthenticationFinished(), //
|
||||||
authIntent)
|
authIntent)
|
||||||
}
|
}
|
||||||
|
CloudTypeModel.S3 -> requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), //
|
||||||
|
Intents.s3AddOrChangeIntent())
|
||||||
CloudTypeModel.LOCAL -> openDocumentTree()
|
CloudTypeModel.LOCAL -> openDocumentTree()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,12 +168,20 @@ class CloudConnectionListPresenter @Inject constructor( //
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onChangeCloudClicked(cloudModel: CloudModel) {
|
fun onChangeCloudClicked(cloudModel: CloudModel) {
|
||||||
if (cloudModel.cloudType() == CloudTypeModel.WEBDAV) {
|
when {
|
||||||
requestActivityResult(ActivityResultCallbacks.addChangeWebDavCloud(), //
|
cloudModel.cloudType() == CloudTypeModel.WEBDAV -> {
|
||||||
Intents.webDavAddOrChangeIntent() //
|
requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), //
|
||||||
.withWebDavCloud(cloudModel as WebDavCloudModel))
|
Intents.webDavAddOrChangeIntent() //
|
||||||
} else {
|
.withWebDavCloud(cloudModel as WebDavCloudModel))
|
||||||
throw IllegalStateException("Change cloud with type " + cloudModel.cloudType() + " is not supported")
|
}
|
||||||
|
cloudModel.cloudType() == CloudTypeModel.S3 -> {
|
||||||
|
requestActivityResult(ActivityResultCallbacks.addChangeMultiCloud(), //
|
||||||
|
Intents.s3AddOrChangeIntent() //
|
||||||
|
.withS3Cloud(cloudModel as S3CloudModel))
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
throw IllegalStateException("Change cloud with type " + cloudModel.cloudType() + " is not supported")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +190,7 @@ class CloudConnectionListPresenter @Inject constructor( //
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Callback
|
@Callback
|
||||||
fun addChangeWebDavCloud(result: ActivityResult?) {
|
fun addChangeMultiCloud(result: ActivityResult?) {
|
||||||
loadCloudList()
|
loadCloudList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package org.cryptomator.presentation.presenter
|
|||||||
import org.cryptomator.domain.Cloud
|
import org.cryptomator.domain.Cloud
|
||||||
import org.cryptomator.domain.LocalStorageCloud
|
import org.cryptomator.domain.LocalStorageCloud
|
||||||
import org.cryptomator.domain.PCloud
|
import org.cryptomator.domain.PCloud
|
||||||
|
import org.cryptomator.domain.S3Cloud
|
||||||
import org.cryptomator.domain.WebDavCloud
|
import org.cryptomator.domain.WebDavCloud
|
||||||
import org.cryptomator.domain.di.PerView
|
import org.cryptomator.domain.di.PerView
|
||||||
import org.cryptomator.domain.exception.FatalBackendException
|
import org.cryptomator.domain.exception.FatalBackendException
|
||||||
@ -18,6 +19,7 @@ import org.cryptomator.presentation.model.CloudModel
|
|||||||
import org.cryptomator.presentation.model.CloudTypeModel
|
import org.cryptomator.presentation.model.CloudTypeModel
|
||||||
import org.cryptomator.presentation.model.LocalStorageModel
|
import org.cryptomator.presentation.model.LocalStorageModel
|
||||||
import org.cryptomator.presentation.model.PCloudModel
|
import org.cryptomator.presentation.model.PCloudModel
|
||||||
|
import org.cryptomator.presentation.model.S3CloudModel
|
||||||
import org.cryptomator.presentation.model.WebDavCloudModel
|
import org.cryptomator.presentation.model.WebDavCloudModel
|
||||||
import org.cryptomator.presentation.model.mappers.CloudModelMapper
|
import org.cryptomator.presentation.model.mappers.CloudModelMapper
|
||||||
import org.cryptomator.presentation.ui.activity.view.CloudSettingsView
|
import org.cryptomator.presentation.ui.activity.view.CloudSettingsView
|
||||||
@ -37,6 +39,7 @@ class CloudSettingsPresenter @Inject constructor( //
|
|||||||
CloudTypeModel.CRYPTO, //
|
CloudTypeModel.CRYPTO, //
|
||||||
CloudTypeModel.LOCAL, //
|
CloudTypeModel.LOCAL, //
|
||||||
CloudTypeModel.PCLOUD, //
|
CloudTypeModel.PCLOUD, //
|
||||||
|
CloudTypeModel.S3, //
|
||||||
CloudTypeModel.WEBDAV)
|
CloudTypeModel.WEBDAV)
|
||||||
|
|
||||||
fun loadClouds() {
|
fun loadClouds() {
|
||||||
@ -44,7 +47,7 @@ class CloudSettingsPresenter @Inject constructor( //
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onCloudClicked(cloudModel: CloudModel) {
|
fun onCloudClicked(cloudModel: CloudModel) {
|
||||||
if (isWebdavOrPCloudOrLocal(cloudModel)) {
|
if (cloudModel.cloudType().isMultiInstance) {
|
||||||
startConnectionListActivity(cloudModel.cloudType())
|
startConnectionListActivity(cloudModel.cloudType())
|
||||||
} else {
|
} else {
|
||||||
if (isLoggedIn(cloudModel)) {
|
if (isLoggedIn(cloudModel)) {
|
||||||
@ -61,10 +64,6 @@ class CloudSettingsPresenter @Inject constructor( //
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isWebdavOrPCloudOrLocal(cloudModel: CloudModel): Boolean {
|
|
||||||
return cloudModel is WebDavCloudModel || cloudModel is LocalStorageModel || cloudModel is PCloudModel
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loginCloud(cloudModel: CloudModel) {
|
private fun loginCloud(cloudModel: CloudModel) {
|
||||||
getCloudsUseCase //
|
getCloudsUseCase //
|
||||||
.withCloudType(CloudTypeModel.valueOf(cloudModel.cloudType())) //
|
.withCloudType(CloudTypeModel.valueOf(cloudModel.cloudType())) //
|
||||||
@ -95,6 +94,7 @@ class CloudSettingsPresenter @Inject constructor( //
|
|||||||
when (cloudTypeModel) {
|
when (cloudTypeModel) {
|
||||||
CloudTypeModel.WEBDAV -> return context().getString(R.string.screen_cloud_settings_webdav_connections)
|
CloudTypeModel.WEBDAV -> return context().getString(R.string.screen_cloud_settings_webdav_connections)
|
||||||
CloudTypeModel.PCLOUD -> return context().getString(R.string.screen_cloud_settings_pcloud_connections)
|
CloudTypeModel.PCLOUD -> return context().getString(R.string.screen_cloud_settings_pcloud_connections)
|
||||||
|
CloudTypeModel.S3 -> return context().getString(R.string.screen_cloud_settings_s3_connections)
|
||||||
CloudTypeModel.LOCAL -> return context().getString(R.string.screen_cloud_settings_local_storage_locations)
|
CloudTypeModel.LOCAL -> return context().getString(R.string.screen_cloud_settings_local_storage_locations)
|
||||||
}
|
}
|
||||||
return context().getString(R.string.screen_cloud_settings_title)
|
return context().getString(R.string.screen_cloud_settings_title)
|
||||||
@ -128,6 +128,7 @@ class CloudSettingsPresenter @Inject constructor( //
|
|||||||
.also {
|
.also {
|
||||||
it.add(aWebdavCloud())
|
it.add(aWebdavCloud())
|
||||||
it.add(aPCloud())
|
it.add(aPCloud())
|
||||||
|
it.add(aS3Cloud())
|
||||||
it.add(aLocalCloud())
|
it.add(aLocalCloud())
|
||||||
}
|
}
|
||||||
view?.render(cloudModel)
|
view?.render(cloudModel)
|
||||||
@ -141,6 +142,10 @@ class CloudSettingsPresenter @Inject constructor( //
|
|||||||
return PCloudModel(PCloud.aPCloud().build())
|
return PCloudModel(PCloud.aPCloud().build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun aS3Cloud(): S3CloudModel {
|
||||||
|
return S3CloudModel(S3Cloud.aS3Cloud().build())
|
||||||
|
}
|
||||||
|
|
||||||
private fun aLocalCloud(): CloudModel {
|
private fun aLocalCloud(): CloudModel {
|
||||||
return LocalStorageModel(LocalStorageCloud.aLocalStorage().build())
|
return LocalStorageModel(LocalStorageCloud.aLocalStorage().build())
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,97 @@
|
|||||||
|
package org.cryptomator.presentation.presenter
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
|
import org.cryptomator.domain.Cloud
|
||||||
|
import org.cryptomator.domain.S3Cloud
|
||||||
|
import org.cryptomator.domain.di.PerView
|
||||||
|
import org.cryptomator.domain.usecases.cloud.AddOrChangeCloudConnectionUseCase
|
||||||
|
import org.cryptomator.domain.usecases.cloud.ConnectToS3UseCase
|
||||||
|
import org.cryptomator.presentation.exception.ExceptionHandlers
|
||||||
|
import org.cryptomator.presentation.model.ProgressModel
|
||||||
|
import org.cryptomator.presentation.model.ProgressStateModel
|
||||||
|
import org.cryptomator.presentation.ui.activity.view.S3AddOrChangeView
|
||||||
|
import org.cryptomator.util.crypto.CredentialCryptor
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@PerView
|
||||||
|
class S3AddOrChangePresenter @Inject internal constructor( //
|
||||||
|
private val addOrChangeCloudConnectionUseCase: AddOrChangeCloudConnectionUseCase, //
|
||||||
|
private val connectToS3UseCase: ConnectToS3UseCase, //
|
||||||
|
exceptionMappings: ExceptionHandlers) : Presenter<S3AddOrChangeView>(exceptionMappings) {
|
||||||
|
|
||||||
|
fun checkUserInput(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?) {
|
||||||
|
var statusMessage: String? = null
|
||||||
|
|
||||||
|
/*if (accessKey.isEmpty()) {
|
||||||
|
statusMessage = getString(R.string.screen_webdav_settings_msg_password_must_not_be_empty)
|
||||||
|
}
|
||||||
|
if (secretKey.isEmpty()) {
|
||||||
|
statusMessage = getString(R.string.screen_webdav_settings_msg_username_must_not_be_empty)
|
||||||
|
}
|
||||||
|
if (bucket.isEmpty()) {
|
||||||
|
statusMessage = getString(R.string.screen_webdav_settings_msg_url_must_not_be_empty)
|
||||||
|
}*/ // FIXME define what is required
|
||||||
|
|
||||||
|
if (statusMessage != null) {
|
||||||
|
// FIXME showError instead of displaying a toast
|
||||||
|
Toast.makeText(context(), statusMessage, Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
view?.onCheckUserInputSucceeded(encrypt(accessKey), encrypt(secretKey), bucket, endpoint, region, cloudId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun encrypt(text: String): String {
|
||||||
|
return CredentialCryptor //
|
||||||
|
.getInstance(context()) //
|
||||||
|
.encrypt(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mapToCloud(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?): S3Cloud {
|
||||||
|
var builder = S3Cloud //
|
||||||
|
.aS3Cloud() //
|
||||||
|
.withAccessKey(accessKey) //
|
||||||
|
.withSecretKey(secretKey) //
|
||||||
|
.withS3Bucket(bucket) //
|
||||||
|
.withS3Endpoint(endpoint) //
|
||||||
|
.withS3Region(region)
|
||||||
|
|
||||||
|
cloudId?.let { builder = builder.withId(cloudId) }
|
||||||
|
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun authenticate(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?) {
|
||||||
|
authenticate(mapToCloud(accessKey, secretKey, bucket, endpoint, region, cloudId))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun authenticate(cloud: S3Cloud) {
|
||||||
|
view?.showProgress(ProgressModel(ProgressStateModel.AUTHENTICATION))
|
||||||
|
connectToS3UseCase //
|
||||||
|
.withCloud(cloud) //
|
||||||
|
.run(object : DefaultResultHandler<Void?>() {
|
||||||
|
override fun onSuccess(void: Void?) {
|
||||||
|
onCloudAuthenticated(cloud)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onError(e: Throwable) {
|
||||||
|
view?.showProgress(ProgressModel.COMPLETED)
|
||||||
|
super.onError(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onCloudAuthenticated(cloud: Cloud) {
|
||||||
|
save(cloud)
|
||||||
|
finishWithResult(CloudConnectionListPresenter.SELECTED_CLOUD, cloud)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun save(cloud: Cloud) {
|
||||||
|
addOrChangeCloudConnectionUseCase //
|
||||||
|
.withCloud(cloud) //
|
||||||
|
.run(DefaultResultHandler())
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
unsubscribeOnDestroy(addOrChangeCloudConnectionUseCase, connectToS3UseCase)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package org.cryptomator.presentation.ui.activity
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import org.cryptomator.generator.Activity
|
||||||
|
import org.cryptomator.generator.InjectIntent
|
||||||
|
import org.cryptomator.presentation.R
|
||||||
|
import org.cryptomator.presentation.intent.S3AddOrChangeIntent
|
||||||
|
import org.cryptomator.presentation.presenter.S3AddOrChangePresenter
|
||||||
|
import org.cryptomator.presentation.ui.activity.view.S3AddOrChangeView
|
||||||
|
import org.cryptomator.presentation.ui.fragment.S3AddOrChangeFragment
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlinx.android.synthetic.main.toolbar_layout.toolbar
|
||||||
|
|
||||||
|
@Activity
|
||||||
|
class S3AddOrChangeActivity : BaseActivity(), S3AddOrChangeView {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var s3AddOrChangePresenter: S3AddOrChangePresenter
|
||||||
|
|
||||||
|
@InjectIntent
|
||||||
|
lateinit var s3AddOrChangeIntent: S3AddOrChangeIntent
|
||||||
|
|
||||||
|
override fun setupView() {
|
||||||
|
toolbar.setTitle(R.string.screen_s3_settings_title)
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createFragment(): Fragment = S3AddOrChangeFragment.newInstance(s3AddOrChangeIntent.s3Cloud())
|
||||||
|
|
||||||
|
override fun onCheckUserInputSucceeded(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?) {
|
||||||
|
s3AddOrChangeFragment().hideKeyboard()
|
||||||
|
s3AddOrChangePresenter.authenticate(accessKey, secretKey, bucket, endpoint, region, cloudId)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun s3AddOrChangeFragment(): S3AddOrChangeFragment = getCurrentFragment(R.id.fragmentContainer) as S3AddOrChangeFragment
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package org.cryptomator.presentation.ui.activity.view
|
||||||
|
|
||||||
|
interface S3AddOrChangeView : View {
|
||||||
|
|
||||||
|
fun onCheckUserInputSucceeded(accessKey: String, secretKey: String, bucket: String, endpoint: String?, region: String?, cloudId: Long?)
|
||||||
|
|
||||||
|
}
|
@ -39,19 +39,19 @@ constructor(private val context: Context) : RecyclerViewBaseAdapter<CloudModel,
|
|||||||
|
|
||||||
itemView.cloudImage.setImageResource(cloudModel.cloudType().cloudImageResource)
|
itemView.cloudImage.setImageResource(cloudModel.cloudType().cloudImageResource)
|
||||||
|
|
||||||
if (webdav(cloudModel.cloudType())) {
|
when (cloudModel.cloudType()) {
|
||||||
itemView.cloudName.text = context.getString(R.string.screen_cloud_settings_webdav_connections)
|
CloudTypeModel.PCLOUD -> itemView.cloudName.text = context.getString(R.string.screen_cloud_settings_pcloud_connections)
|
||||||
} else if (pCloud(cloudModel.cloudType())) {
|
CloudTypeModel.S3 -> itemView.cloudName.text = context.getString(R.string.screen_cloud_settings_s3_connections)
|
||||||
itemView.cloudName.text = context.getString(R.string.screen_cloud_settings_pcloud_connections)
|
CloudTypeModel.WEBDAV -> itemView.cloudName.text = context.getString(R.string.screen_cloud_settings_webdav_connections)
|
||||||
} else if (local(cloudModel.cloudType())) {
|
CloudTypeModel.LOCAL -> itemView.cloudName.text = context.getString(R.string.screen_cloud_settings_local_storage_locations)
|
||||||
itemView.cloudName.text = context.getString(R.string.screen_cloud_settings_local_storage_locations)
|
else -> {
|
||||||
} else {
|
itemView.cloudName.text = getCloudNameText(isAlreadyLoggedIn(cloudModel), cloudModel)
|
||||||
itemView.cloudName.text = getCloudNameText(isAlreadyLoggedIn(cloudModel), cloudModel)
|
if (isAlreadyLoggedIn(cloudModel)) {
|
||||||
if (isAlreadyLoggedIn(cloudModel)) {
|
itemView.cloudUsername.text = cloudModel.username()
|
||||||
itemView.cloudUsername.text = cloudModel.username()
|
itemView.cloudUsername.visibility = View.VISIBLE
|
||||||
itemView.cloudUsername.visibility = View.VISIBLE
|
} else {
|
||||||
} else {
|
itemView.cloudUsername.visibility = View.GONE
|
||||||
itemView.cloudUsername.visibility = View.GONE
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,16 +73,4 @@ constructor(private val context: Context) : RecyclerViewBaseAdapter<CloudModel,
|
|||||||
context.getString(R.string.screen_cloud_settings_log_in_to)
|
context.getString(R.string.screen_cloud_settings_log_in_to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun local(cloudType: CloudTypeModel): Boolean {
|
|
||||||
return CloudTypeModel.LOCAL == cloudType
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun webdav(cloudType: CloudTypeModel): Boolean {
|
|
||||||
return CloudTypeModel.WEBDAV == cloudType
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun pCloud(cloudType: CloudTypeModel): Boolean {
|
|
||||||
return CloudTypeModel.PCLOUD == cloudType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
package org.cryptomator.presentation.ui.fragment
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.view.inputmethod.EditorInfo
|
||||||
|
import androidx.core.view.isVisible
|
||||||
|
import com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
import org.cryptomator.generator.Fragment
|
||||||
|
import org.cryptomator.presentation.R
|
||||||
|
import org.cryptomator.presentation.model.S3CloudModel
|
||||||
|
import org.cryptomator.presentation.presenter.S3AddOrChangePresenter
|
||||||
|
import org.cryptomator.util.crypto.CredentialCryptor
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.accessKeyEditText
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.bucketEditText
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.createCloudButton
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.endpointEditText
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.ll_custom_s3
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.regionEditText
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.secretKeyEditText
|
||||||
|
import kotlinx.android.synthetic.main.fragment_setup_s3.toggleCustomS3
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
@Fragment(R.layout.fragment_setup_s3)
|
||||||
|
class S3AddOrChangeFragment : BaseFragment() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var s3AddOrChangePresenter: S3AddOrChangePresenter
|
||||||
|
|
||||||
|
private var cloudId: Long? = null
|
||||||
|
|
||||||
|
private val s3CloudModel: S3CloudModel?
|
||||||
|
get() = arguments?.getSerializable(ARG_S3_CLOUD) as? S3CloudModel
|
||||||
|
|
||||||
|
override fun setupView() {
|
||||||
|
createCloudButton.setOnClickListener { createCloud() }
|
||||||
|
createCloudButton.setOnEditorActionListener { _, actionId, _ ->
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
|
createCloud()
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
toggleCustomS3.setOnClickListener { switch ->
|
||||||
|
toggleCustomS3Changed((switch as SwitchMaterial).isChecked)
|
||||||
|
}
|
||||||
|
|
||||||
|
showEditableCloudContent(s3CloudModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun toggleCustomS3Changed(checked: Boolean) = if(checked) {
|
||||||
|
ll_custom_s3.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
ll_custom_s3.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showEditableCloudContent(s3CloudModel: S3CloudModel?) {
|
||||||
|
s3CloudModel?.let {
|
||||||
|
cloudId = s3CloudModel.id()
|
||||||
|
accessKeyEditText.setText(decrypt(s3CloudModel.accessKey()))
|
||||||
|
secretKeyEditText.setText(decrypt(s3CloudModel.secretKey()))
|
||||||
|
bucketEditText.setText(s3CloudModel.s3Bucket())
|
||||||
|
endpointEditText.setText(s3CloudModel.s3Endpoint())
|
||||||
|
regionEditText.setText(s3CloudModel.s3Region())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun decrypt(text: String?): String {
|
||||||
|
return if (text != null) {
|
||||||
|
try {
|
||||||
|
CredentialCryptor //
|
||||||
|
.getInstance(activity?.applicationContext) //
|
||||||
|
.decrypt(text)
|
||||||
|
} catch (e: RuntimeException) {
|
||||||
|
Timber.tag("S3AddOrChangeFragment").e(e, "Unable to decrypt password, clearing it")
|
||||||
|
""
|
||||||
|
}
|
||||||
|
} else ""
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createCloud() {
|
||||||
|
val accessKey = accessKeyEditText.text.toString().trim()
|
||||||
|
val secretKey = secretKeyEditText.text.toString().trim()
|
||||||
|
val bucket = bucketEditText.text.toString().trim()
|
||||||
|
|
||||||
|
var endpoint: String? = null
|
||||||
|
var region: String? = null
|
||||||
|
if(ll_custom_s3.isVisible) {
|
||||||
|
endpoint = endpointEditText.text.toString().trim()
|
||||||
|
region = regionEditText.text.toString().trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
s3AddOrChangePresenter.checkUserInput(accessKey, secretKey, bucket, endpoint, region, cloudId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hideKeyboard() {
|
||||||
|
hideKeyboard(bucketEditText)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val ARG_S3_CLOUD = "S3_CLOUD"
|
||||||
|
|
||||||
|
fun newInstance(cloudModel: S3CloudModel?): S3AddOrChangeFragment {
|
||||||
|
val result = S3AddOrChangeFragment()
|
||||||
|
val args = Bundle()
|
||||||
|
args.putSerializable(ARG_S3_CLOUD, cloudModel)
|
||||||
|
result.arguments = args
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
112
presentation/src/main/res/layout/fragment_setup_s3.xml
Normal file
112
presentation/src/main/res/layout/fragment_setup_s3.xml
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/activity_vertical_margin">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/accessKeyEditText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/screen_s3_settings_access_key_label"
|
||||||
|
android:imeOptions="flagNoPersonalizedLearning"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/secretKeyEditText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/screen_s3_settings_secret_key_label"
|
||||||
|
android:imeOptions="flagNoPersonalizedLearning"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/bucketEditText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/screen_s3_settings_bucket_label"
|
||||||
|
android:imeOptions="flagNoPersonalizedLearning"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/toggleCustomS3"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/screen_s3_settings_amazon_s3_text" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/ll_custom_s3"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/endpointEditText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/screen_s3_settings_endpoint_label"
|
||||||
|
android:imeOptions="flagNoPersonalizedLearning"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/regionEditText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/screen_s3_settings_region_label"
|
||||||
|
android:imeOptions="flagNoPersonalizedLearning"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:singleLine="true" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/createCloudButton"
|
||||||
|
style="?android:textAppearanceSmall"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="@string/screen_webdav_settings_done_button_text"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
@ -43,6 +43,7 @@
|
|||||||
<string name="cloud_names_onedrive" translatable="false">OneDrive</string>
|
<string name="cloud_names_onedrive" translatable="false">OneDrive</string>
|
||||||
<string name="cloud_names_pcloud" translatable="false">pCloud</string>
|
<string name="cloud_names_pcloud" translatable="false">pCloud</string>
|
||||||
<string name="cloud_names_webdav" translatable="false">WebDAV</string>
|
<string name="cloud_names_webdav" translatable="false">WebDAV</string>
|
||||||
|
<string name="cloud_names_s3" translatable="false">S3</string>
|
||||||
<string name="cloud_names_local_storage">Local storage</string>
|
<string name="cloud_names_local_storage">Local storage</string>
|
||||||
|
|
||||||
<!-- # permission -->
|
<!-- # permission -->
|
||||||
@ -172,6 +173,15 @@
|
|||||||
<string name="screen_webdav_settings_msg_username_must_not_be_empty">Username can\'t be empty.</string>
|
<string name="screen_webdav_settings_msg_username_must_not_be_empty">Username can\'t be empty.</string>
|
||||||
<string name="screen_webdav_settings_msg_password_must_not_be_empty">Password can\'t be empty.</string>
|
<string name="screen_webdav_settings_msg_password_must_not_be_empty">Password can\'t be empty.</string>
|
||||||
|
|
||||||
|
<!-- ## screen: s3 settings -->
|
||||||
|
<string name="screen_s3_settings_title" translatable="false">@string/cloud_names_s3</string>
|
||||||
|
<string name="screen_s3_settings_access_key_label">Access Key</string>
|
||||||
|
<string name="screen_s3_settings_secret_key_label">Secret Key</string>
|
||||||
|
<string name="screen_s3_settings_bucket_label">Bucket</string>
|
||||||
|
<string name="screen_s3_settings_endpoint_label">Endpoint</string>
|
||||||
|
<string name="screen_s3_settings_region_label">Region</string>
|
||||||
|
<string name="screen_s3_settings_amazon_s3_text" translatable="false">Amazon S3</string>
|
||||||
|
|
||||||
<!-- ## screen: enter vault name -->
|
<!-- ## screen: enter vault name -->
|
||||||
<string name="screen_enter_vault_name_title" translatable="false">@string/screen_vault_list_action_create_new_vault</string>
|
<string name="screen_enter_vault_name_title" translatable="false">@string/screen_vault_list_action_create_new_vault</string>
|
||||||
<string name="screen_enter_vault_name_msg_name_empty">Vault name can\'t be empty.</string>
|
<string name="screen_enter_vault_name_msg_name_empty">Vault name can\'t be empty.</string>
|
||||||
@ -257,6 +267,7 @@
|
|||||||
<string name="screen_cloud_settings_title" translatable="false">@string/screen_settings_cloud_settings_label</string>
|
<string name="screen_cloud_settings_title" translatable="false">@string/screen_settings_cloud_settings_label</string>
|
||||||
<string name="screen_cloud_settings_webdav_connections">WebDAV connections</string>
|
<string name="screen_cloud_settings_webdav_connections">WebDAV connections</string>
|
||||||
<string name="screen_cloud_settings_pcloud_connections">pCloud connections</string>
|
<string name="screen_cloud_settings_pcloud_connections">pCloud connections</string>
|
||||||
|
<string name="screen_cloud_settings_s3_connections">S3 connections</string>
|
||||||
<string name="screen_cloud_settings_local_storage_locations">Local storage locations</string>
|
<string name="screen_cloud_settings_local_storage_locations">Local storage locations</string>
|
||||||
<string name="screen_cloud_settings_log_in_to">Log in to</string>
|
<string name="screen_cloud_settings_log_in_to">Log in to</string>
|
||||||
<string name="screen_cloud_settings_sign_out_from_cloud">Sign out from</string>
|
<string name="screen_cloud_settings_sign_out_from_cloud">Sign out from</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user