1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

Compare commits

...

1294 Commits

Author SHA1 Message Date
Aitorbp
71224c30d1
Merge pull request #581 from owncloud/release/4.1
[RELEASE] 4.1 library to master
2023-09-05 09:49:55 +01:00
Aitorbp
c82d75b1d8 New fix for snackbar when copy without server on 2023-08-30 10:16:58 +01:00
Manuel Plazas Palacio
530999848f Solving bugs when getting file existence in OC10 2023-08-24 14:12:30 +02:00
Manuel Plazas Palacio
b4625d017c Solving bugs when getting file existence. 2023-08-24 12:28:23 +02:00
Manuel Plazas Palacio
2c698cc2a4
Merge pull request #578 from owncloud/feature/unneccesary_call
[BUG] unneccessary or wrong call ....
2023-08-23 10:56:22 +02:00
Manuel Plazas Palacio
bf183fe04d Solving bug when copyin or moving 2023-08-22 15:24:59 +02:00
Manuel Plazas Palacio
1f8de383b6 Removing extra path on check path existence. 2023-08-18 11:14:11 +02:00
Aitorbp
8eb435a1c2
Merge pull request #577 from owncloud/feature/respect_app_provider_values_from_capabilities
[FEATURE REQUEST] Respect app_provider values from capabilities
2023-08-03 08:26:26 +01:00
Aitorbp
052566d205 Added variable from local data source 2023-07-31 12:43:16 +01:00
Manuel Plazas Palacio
063c3fa9e9
Merge pull request #571 from owncloud/feature/copy_move_conflic_solved_users
[FEATURE REQUEST] Copy/move conflict solved by users
2023-06-21 08:33:47 +02:00
Manuel Plazas Palacio
fa143804d2 Solving CR changes. 2023-06-08 13:31:09 +02:00
Manuel Plazas Palacio
5b64876e2c Showing decision dialog when moving file conflict.
Solving errors when copying, replace and keep both.
2023-06-07 12:15:14 +02:00
Manuel Plazas Palacio
d81ca97f14 Showing decision dialog when copying file conflict. 2023-06-07 12:15:14 +02:00
Juan Carlos Garrote
5607f76a1d
Merge pull request #566 from owncloud/technical/min_sdk_23
[TECHNICAL] Upgrade min SDK to Android 6 (v23)
2023-05-25 14:03:37 +02:00
Juan Carlos Garrote
b4137502d2 Remove unnecessary code after upgrading to min SDK 23 2023-05-25 13:33:49 +02:00
Juan Carlos Garrote
261075a8ad Update minSdkVersion to 23 (Android 6) 2023-05-25 13:33:49 +02:00
Juan Carlos Garrote
c2874357f0
Merge pull request #569 from owncloud/release/4.0
[Release] 2.1
2023-05-25 13:30:31 +02:00
Juan Carlos Garrote
e6937b4210 Removed publicUpload parameter from public shares creation and update requests 2023-05-15 14:01:16 +02:00
Juan Carlos Garrote
89dd13cec4
Merge pull request #562 from owncloud/feature/create_file_web
[FEATURE REQUEST] Create new file via Open in Web
2023-05-04 09:11:24 +02:00
Juan Carlos Garrote
ab3a594e5c Create network call to create file via app provider 2023-04-14 11:02:21 +02:00
Juan Carlos Garrote
cbbe044212
Merge pull request #558 from owncloud/fix/unknown_error_message
[FIX] Introduce new error message for ProtocolException
2023-04-13 08:26:42 +02:00
Juan Carlos Garrote
17aa1ea7bd Introduce new error message for ProtocolException 2023-04-13 08:20:50 +02:00
Abel García de Prada
cbf6365e93
Merge pull request #559 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.10
Bump org.robolectric:robolectric from 4.9.2 to 4.10
2023-04-12 08:21:19 +02:00
dependabot[bot]
15bccd3f80
Bump org.robolectric:robolectric from 4.9.2 to 4.10
Bumps [org.robolectric:robolectric](https://github.com/robolectric/robolectric) from 4.9.2 to 4.10.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9.2...robolectric-4.10)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-12 02:57:14 +00:00
Juan Carlos Garrote
8cee0a37a7
Merge pull request #553 from owncloud/feature/app_registry
[Feature] Open in specific web provider
2023-04-10 09:17:36 +02:00
Abel García de Prada
393ec6e07e Open file in web with a specific app 2023-04-05 16:16:50 +02:00
Abel García de Prada
f35daacdf1 Pleasure the lint 2023-04-05 16:16:50 +02:00
Abel García de Prada
2ac5cf0657 Move open in web operations to their proper location 2023-04-05 16:16:50 +02:00
Abel García de Prada
173b12eeca Retrieve the list of available apps to open in web 2023-04-05 16:16:50 +02:00
Juan Carlos Garrote
602ab41fcc
Merge pull request #555 from owncloud/feature/auth_webfinger_flow
Update WebFinger flow
2023-04-04 13:44:31 +02:00
Juan Carlos Garrote
3a27baad3a Fix WebfingerResponse tests 2023-04-04 11:51:06 +02:00
Abel García de Prada
14baadd7ea Webfinger calls won't follow redirections. Only working with 2XX 2023-03-31 09:41:57 +02:00
Abel García de Prada
fa65c1a84d
Merge pull request #551 from owncloud/feature/add_language_header
Add accept language header to all requests
2023-03-24 13:33:42 +01:00
Abel García de Prada
c429b575a9 Add accept language header to all requests 2023-03-24 08:31:34 +01:00
Abel García de Prada
f7d4d27ebb
Merge pull request #552 from owncloud/remove_drives_permission_parsing
Remove permission parsing from spaces.
2023-03-23 10:21:01 +01:00
Abel García de Prada
3681f1001a Remove permission parsing from spaces. Will be done via WebDav permissions 2023-03-22 15:23:57 +01:00
Abel García de Prada
ee5130d3e6
Merge pull request #550 from owncloud/technical/bump_target_sdk
[TECHNICAL] Bump target sdk to 33
2023-03-21 12:23:38 +01:00
Abel García de Prada
1f93cfaf52 Bump target sdk to 33 2023-03-16 13:06:00 +01:00
Juan Carlos Garrote
e6e30fc352
Merge pull request #549 from owncloud/release/2.1
[Release] 2.1 beta.1
2023-03-13 13:09:04 +01:00
Abel García de Prada
c53475da37 Removing quotas from webdav properties in regular propfinds 2023-03-10 12:47:35 +01:00
Abel García de Prada
c2f32b2a82
Merge pull request #548 from owncloud/technical/replace_kapt_with_ksp
[Technical] Replace kapt with ksp
2023-03-09 13:02:47 +01:00
Abel García de Prada
6846e25fa3 Replace kapt with ksp 2023-03-09 11:51:13 +01:00
Juan Carlos Garrote
0e9f9c6391
Merge pull request #530 from owncloud/spaces/main
[SPACES] Main features
2023-03-09 11:49:00 +01:00
Juan Carlos Garrote
159dcd6d68 Rename file to be the same as the class it contains 2023-03-09 09:43:07 +01:00
Juan Carlos Garrote
b660ee98fd Rename files to be the same as the classes they contain 2023-03-09 09:37:09 +01:00
Abel García de Prada
ff90598a2d Rename WebFinger classes to make them consistent 2023-03-09 09:19:25 +01:00
Abel García de Prada
0017079a69 Allow retrieval of several instances from webfinger 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
2458db1828 Fix to KtLint report 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
e6f3fd2e16 Upload workers and network operations adapted to spaces 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
a395787e0b Adapted copy operation for spaces 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
e9f291371d Move network operation adapted to spaces 2023-03-09 09:19:25 +01:00
Abel García de Prada
b65efc2b69 Allow downloads from specific WebDav urls 2023-03-09 09:19:25 +01:00
Abel García de Prada
78665e8cb0 Add support for spaces web dav specific urls to the rename operation 2023-03-09 09:19:25 +01:00
Abel García de Prada
9c844aae7e Support removal of files from specific space 2023-03-09 09:19:25 +01:00
Abel García de Prada
2c18e7b679 Added create folder operation support for specific space 2023-03-09 09:19:25 +01:00
Abel García de Prada
cb73d537e4 Allow support to read specific file from a space 2023-03-09 09:19:25 +01:00
Abel García de Prada
8e4f243031 Fix remote path retrieval. Now it depends on webdav url to support spaces 2023-03-09 09:19:25 +01:00
Abel García de Prada
a65a82cae0 Adapt the propfind to work with specific webdavurl from the space 2023-03-09 09:19:25 +01:00
Abel García de Prada
45f53656ba Update permissions parsing to latest api changes
Supports api renaming from grantedTo to grantedToIdentities on v1.0.1
https://github.com/owncloud/libre-graph-api/releases/tag/v1.0.1
2023-03-09 09:19:25 +01:00
Abel García de Prada
8a4fcb6550 Support shares space 2023-03-09 09:19:25 +01:00
Abel García de Prada
31ccf56e97 Fix parsing when space is disabled 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
0d7a49b3ff Some type changes and renamings 2023-03-09 09:19:25 +01:00
Abel García de Prada
7bb94cf289 Make quota attribute nullable. Its not mandatory 2023-03-09 09:19:25 +01:00
Abel García de Prada
b1a3402656 Create spaces fetch operation and spaces service 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
f0dda9eb8b Added trailing comma 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
4f001550f9 Save spaces-related capabilities in database 2023-03-09 09:19:25 +01:00
Juan Carlos Garrote
e30246c486
Merge pull request #547 from owncloud/release/2.0.3
[Release] 2.0.3
2023-03-07 18:20:51 +01:00
Abel García de Prada
602b7e7548 Show the url in the response http log too 2023-03-07 14:14:54 +01:00
Abel García de Prada
f8da84d0ad
Merge pull request #544 from owncloud/dependabot/gradle/com.android.tools.build-gradle-7.4.2
Bump com.android.tools.build:gradle from 7.4.1 to 7.4.2
2023-02-28 08:02:23 +01:00
dependabot[bot]
763005b051
Bump com.android.tools.build:gradle from 7.4.1 to 7.4.2
Bumps com.android.tools.build:gradle from 7.4.1 to 7.4.2.

---
updated-dependencies:
- dependency-name: com.android.tools.build:gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-28 02:57:18 +00:00
Abel García de Prada
d6f969bd91
Merge pull request #540 from owncloud/bump/kotlin_gradle
Bump kotlin version to 1.8.10
2023-02-14 10:17:37 +01:00
Abel García de Prada
4200ed324c Bump kotlin version to 1.8.10 2023-02-14 09:45:29 +01:00
Abel García de Prada
7ee2c5eb15
Merge pull request #535 from owncloud/dependabot/gradle/org.jlleitschuh.gradle-ktlint-gradle-11.1.0
Bump ktlint-gradle from 11.0.0 to 11.1.0
2023-01-30 10:47:27 +01:00
dependabot[bot]
b5cd4a1df2
Bump ktlint-gradle from 11.0.0 to 11.1.0
Bumps ktlint-gradle from 11.0.0 to 11.1.0.

---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle:ktlint-gradle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-30 02:11:34 +00:00
Abel García de Prada
8a8a931e66
Merge pull request #534 from owncloud/release/2.0.2
[Release] 2.0.2
2023-01-27 13:11:39 +01:00
Abel García de Prada
148a97cd32 Potential fix to oauth error after logging in for first time that makes user to reauthenticate 2023-01-26 14:36:38 +01:00
Abel García de Prada
00948ffd73
Merge pull request #528 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.9.2
Bump robolectric from 4.9.1 to 4.9.2
2023-01-09 08:34:18 +01:00
dependabot[bot]
118646290d
Bump robolectric from 4.9.1 to 4.9.2
Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.9.1 to 4.9.2.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9.1...robolectric-4.9.2)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-28 02:01:23 +00:00
Abel García de Prada
defa4d1469
Merge pull request #525 from owncloud/debug/connection_validator_logs
Add several logs to try to debug potential errors related to token refreshment
2022-12-21 12:15:35 +01:00
Abel García de Prada
3545686a31 Add several logs to try to debug potential errors related to oAuth 2022-12-21 11:32:55 +01:00
Abel García de Prada
b710070426
Merge pull request #524 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.9.1
Bump robolectric from 4.9 to 4.9.1
2022-12-20 12:58:27 +01:00
dependabot[bot]
a0750c613a
Bump robolectric from 4.9 to 4.9.1
Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.9 to 4.9.1.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.9...robolectric-4.9.1)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-20 02:01:28 +00:00
Abel García de Prada
9df62a51f3
Merge pull request #523 from owncloud/fix/unshare_ocis
Unsharing wont return anything anymore since result object was not used
2022-12-19 08:29:11 +01:00
Abel García de Prada
fa7bfdd597 Unsharing wont return anything anymore since result object was not used 2022-12-15 15:26:37 +01:00
Abel García de Prada
cb076aa6b9
Merge pull request #520 from owncloud/dependencies/bump_bulk
Bump several dependencies at the same time
2022-12-15 14:49:39 +01:00
Abel García de Prada
7ceef58382 Bump gradle plugin to 7.3.1 and move package name fro manifest to gradle namespace 2022-12-13 19:00:10 +01:00
Abel García de Prada
a877612fca Bump several dependencies at the same time 2022-12-13 14:51:57 +01:00
Abel García de Prada
359e591275
Merge pull request #339 from owncloud/new_arch/synchronization
[New arch] Synchronization
2022-12-12 09:54:27 +01:00
Abel García de Prada
f9bc792ded Do data field not mandatory on ocs response 2022-11-28 19:35:47 +01:00
Juan Carlos Garrote
9adadbddcc Fix lint reports 2022-11-28 19:35:47 +01:00
Abel García de Prada
1ecb8020b1 Remove legacy KEY_OC_VERSION constant 2022-11-28 19:35:47 +01:00
Abel García de Prada
b7d3cc2687 Remove legacy owncloud version from the client. 2022-11-28 19:35:47 +01:00
Juan Carlos Garrote
2b27b9657c Increased the chunk size to 10 MB 2022-11-28 19:35:47 +01:00
Abel García de Prada
959cb7b015 Retrieve Etag from successful upload 2022-11-28 19:35:47 +01:00
Abel García de Prada
b59a4e6947 Read remote file function added to the file service 2022-11-28 19:35:47 +01:00
Abel García de Prada
17821e5760 Migrate ReadRemoteFileOperation to kotlin. Second step to keep git history 2022-11-28 19:35:47 +01:00
Abel García de Prada
2b79175b5a Migrate ReadRemoteFileOperation to kotlin. First step to keep git history 2022-11-28 19:35:47 +01:00
Abel García de Prada
b25fbc4604 Fix an error after rebasing with latest version 2022-11-28 19:35:47 +01:00
Abel García de Prada
79173af930 Polish a little bit the code 2022-11-28 19:35:47 +01:00
Abel García de Prada
c36eedd481 Return Unit when the upload operation succeeds 2022-11-28 19:35:47 +01:00
Abel García de Prada
ba37bce0e1 Add transfer listeners to content uri worker 2022-11-28 19:35:47 +01:00
Abel García de Prada
dc7022c531 Pleasure the ktlint 2022-11-28 19:35:47 +01:00
Abel García de Prada
1f499fb67d Make requireEtag nullable 2022-11-28 19:35:46 +01:00
Abel García de Prada
12040a1261 Migrate old request bodies from java to kotlin 2022-11-28 19:35:46 +01:00
Abel García de Prada
7e56412748 Move content uri request body to a new file 2022-11-28 19:35:46 +01:00
Abel García de Prada
71e9bbd2da Delete old java operations. Use the kotlin ones from now on 2022-11-28 19:35:46 +01:00
Abel García de Prada
cbbeaab251 Migrate remote chunk upload operation to kotlin 2022-11-28 19:35:46 +01:00
Abel García de Prada
340e114a91 Use extension to simplify a little bit the code 2022-11-28 19:35:46 +01:00
Abel García de Prada
c6584d69fd Migrate remote upload operation to kotlin 2022-11-28 19:35:46 +01:00
Abel García de Prada
4c39990edb Add copy operation to the file service 2022-11-28 19:35:46 +01:00
Abel García de Prada
34cc4c87b1 Refactor copy remote file operation. Make overwrite false as default to avoid some potential errors 2022-11-28 19:35:46 +01:00
Abel García de Prada
5449eb7480 Migrate CopyRemoteFileOperation to kotlin. Second step to keep git history 2022-11-28 19:35:46 +01:00
Abel García de Prada
33d6141613 Migrate CopyRemoteFileOperation to kotlin. First step to keep git history 2022-11-28 19:35:46 +01:00
Abel García de Prada
f7645c1648 Apply code review suggestions 2022-11-28 19:35:46 +01:00
Abel García de Prada
6f33dca672 Remove nullability from a variable 2022-11-28 19:35:46 +01:00
Abel García de Prada
6fb5350dea Add rename file to FileService 2022-11-28 19:35:46 +01:00
Abel García de Prada
24037a7a3e Migrate RenameRemoteFileOperation to kotlin. Second step to keep git history 2022-11-28 19:35:46 +01:00
Abel García de Prada
5f01b32b12 Migrate RenameRemoteFileOperation to kotlin. First step to keep git history 2022-11-28 19:35:46 +01:00
Abel García de Prada
f849cd76d4 Make overwrite option disabled by default for move operations 2022-11-28 19:35:46 +01:00
Abel García de Prada
7c825b2dc3 Add move operation to file service 2022-11-28 19:35:46 +01:00
Abel García de Prada
b3cccfa007 Add move operation to chunk service 2022-11-28 19:35:46 +01:00
Abel García de Prada
5beb30e07a Migrate MoveRemoteFileOperation to kotlin. Second step to keep git history 2022-11-28 19:35:46 +01:00
Abel García de Prada
d736c7cdbf Migrate MoveRemoteFileOperation to kotlin. First step to keep git history 2022-11-28 19:35:46 +01:00
Abel García de Prada
d99444e279 Apply code review suggestions 2022-11-28 19:35:46 +01:00
Abel García de Prada
86f16c3460 Add removeFile to FileService 2022-11-28 19:35:46 +01:00
Abel García de Prada
62dbdb1021 Converting RemoveRemoteFileOperation from java to kotlin. Final step. 2022-11-28 19:35:46 +01:00
Abel García de Prada
f706595a9a Converting RemoveRemoteFileOperation from java to kotlin. Intermediate step to preserve git history. 2022-11-28 19:35:46 +01:00
Abel García de Prada
03303ac4f2 Replace kotlin android extensions with kotlin-parcelize 2022-11-28 19:35:46 +01:00
Abel García de Prada
039245742c Apply code review suggestions 2022-11-28 19:35:46 +01:00
Abel García de Prada
3a996ef583 Download file operation will return unit instead of Any 2022-11-28 19:35:46 +01:00
agarcia
ec71fa6c23 Create parent folder when downloading a file if possible 2022-11-28 19:35:46 +01:00
agarcia
56248af6ec Add download file to file service 2022-11-28 19:35:46 +01:00
agarcia
389c0a0fc6 Migrate DownloadRemoteFileOperation to kotlin 2022-11-28 19:35:46 +01:00
Abel García de Prada
405da9a729 Apply CR changes 2022-11-28 19:35:46 +01:00
Abel García de Prada
a02844d2c7 Map size or length property depending on mimetype 2022-11-28 19:35:46 +01:00
Abel García de Prada
53c99a21c2 Transform RemoteFile to kotlin and apply necessary changes 2022-11-28 19:35:46 +01:00
agarcia
5e478036ae Apply code review suggestions 2022-11-28 19:28:41 +01:00
agarcia
cd94e39b7f Include createFolder as file service operation 2022-11-28 19:28:41 +01:00
agarcia
b0798194be Migrate CreateRemoteFolderOperation to kotlin 2022-11-28 19:28:41 +01:00
agarcia
2b5f80bdb9 Apply CR suggestions 2022-11-28 19:28:41 +01:00
agarcia
32891e2cf5 Add owner field to remote file 2022-11-28 19:28:41 +01:00
agarcia
d164b34fe8 Migrate ReadRemoteFolderOperation to kotlin and add it to FileService 2022-11-28 19:28:41 +01:00
Juan Carlos Garrote
c2f7426a3e
Merge pull request #515 from owncloud/feature/handle_425_response
Handle 425 TOO EARLY propfind responses
2022-11-17 13:15:10 +01:00
Juan Carlos Garrote
1e9d8cef42 Handle 425 when trying to open in web 2022-11-17 12:50:55 +01:00
Abel García de Prada
b083debac9 Handle 425 TOO EARLY propfind responses 2022-11-17 12:50:55 +01:00
Jesús Recio
376d52ac5b
Merge pull request #481 from owncloud/feature/webfinger
add moshi classes for webfinger responses
2022-11-02 11:16:57 +01:00
Abel García de Prada
e769684920 Reformat some webfinger classes 2022-10-13 10:22:39 +02:00
Abel García de Prada
70bf35f683 Remove unused imports 2022-10-11 18:00:03 +02:00
Abel García de Prada
1afa124b7d Add webfinger service and update the remote operation 2022-10-10 13:07:11 +02:00
Christian Schabesberger
f19b2355b4 create scaffold for webfinger request operation 2022-10-06 09:34:13 +02:00
Christian Schabesberger
c966bf14d0 add moshi classes for webfinger responses 2022-10-06 09:34:13 +02:00
Abel García de Prada
2c225d8e66
Merge pull request #509 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.9
Bump robolectric from 4.8.1 to 4.9
2022-10-03 09:32:24 +02:00
dependabot[bot]
f8a829d6b7
Bump robolectric from 4.8.1 to 4.9
Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.8.1 to 4.9.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.8.1...robolectric-4.9)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-10-03 02:15:21 +00:00
Abel García de Prada
0ea053d612
Merge pull request #503 from owncloud/feature/open_in_web
[Feature] Open in web
2022-09-01 10:54:05 +02:00
Abel García de Prada
0be462c9aa Set private link capability to unknown type when it is not retrieved
The CapabilityBooleanType.fromBooleanValue set it to FALSE when the capability is not retrieved. We don't want this for this case. Probably neither for the rest, but changing that now would need deeper testing
2022-08-31 17:21:55 +02:00
Abel García de Prada
32ef5d2125 Add a new capability to allow/disallow private links 2022-08-31 17:21:55 +02:00
Abel García de Prada
6282fbd419 Add the open in web to the service facade 2022-08-31 17:21:55 +02:00
Abel García de Prada
6d235fe74a Add a new remote operation to retrieve the url to open a file with ocis provider 2022-08-31 17:21:55 +02:00
Abel García de Prada
9ab7c139e1 Retrieve the app providers from the capabilities 2022-08-31 17:21:55 +02:00
Abel García de Prada
24b850d20c
Merge pull request #496 from owncloud/propfind_with_shares
Retrieve share type directly within the propfind
2022-07-07 14:59:20 +02:00
Abel García de Prada
5be4eca0f7 Added a new property, so that, we can retrieve the shares within the propfind 2022-07-07 08:18:54 +02:00
Jesús Recio
2dc6f30a5e
Merge pull request #490 from owncloud/fix/eos
Fix unexpected end of stream when connecting with server
2022-05-31 11:48:55 +02:00
Abel García de Prada
f712a384cd Fix unexpected end of stream when connecting with server 2022-05-30 13:41:41 +02:00
Abel García de Prada
1f9bff1df0
Merge pull request #439 from owncloud/Modernize
Modernize
2022-05-30 09:36:35 +02:00
Hannes Achleitner
1412117dcd Android Arctic Fox 2022-05-30 09:12:42 +02:00
Hannes Achleitner
a054adc688 Java 8 is by default 2022-05-30 09:11:56 +02:00
Abel García de Prada
809e641b1a
Merge pull request #488 from owncloud/release/2.21-beta.1
[Release] 1.0.15-beta.1
2022-05-12 09:49:09 +02:00
Fernando Sanz
fd8caa42cb Updated versionCode and versionName 2022-05-11 09:53:47 +02:00
Abel García de Prada
45a9a190f8
Merge pull request #486 from owncloud/bump/kotlin_version
Bump kotlin version to 1.6.21
2022-05-09 14:43:16 +02:00
Abel García de Prada
2931a5494a Bump kotlin version to 1.6.21 2022-05-09 14:09:21 +02:00
Abel García de Prada
35fb64c1bd
Merge pull request #484 from owncloud/dependabot/gradle/org.jlleitschuh.gradle-ktlint-gradle-10.3.0
Bump ktlint-gradle from 10.2.1 to 10.3.0
2022-05-09 14:04:04 +02:00
dependabot[bot]
544fc6efd4
Bump ktlint-gradle from 10.2.1 to 10.3.0
Bumps ktlint-gradle from 10.2.1 to 10.3.0.

---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle:ktlint-gradle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-04 07:13:39 +00:00
Abel García de Prada
16c31988e0
Merge pull request #485 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.8.1
Bump robolectric from 4.8 to 4.8.1
2022-05-04 09:12:31 +02:00
dependabot[bot]
7fe41ce51c
Bump robolectric from 4.8 to 4.8.1
Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.8 to 4.8.1.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.8...robolectric-4.8.1)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-05-04 02:08:05 +00:00
Abel García de Prada
aaafdb5ea2
Merge pull request #483 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.8
Bump robolectric from 4.7.3 to 4.8
2022-04-29 08:28:09 +02:00
dependabot[bot]
6e503c2cf7
Bump robolectric from 4.7.3 to 4.8
Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.7.3 to 4.8.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.7.3...robolectric-4.8)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-29 02:44:52 +00:00
Abel García de Prada
4de236b3c7
Merge pull request #364 from owncloud/fix/okhttp_singleton
remove okhttp singleton
2022-04-27 18:35:58 +02:00
Abel García de Prada
f6eb631fbf Reformat some code 2022-04-25 08:41:14 +02:00
Christian Schabesberger
be758eb5ea apply requested changes 2022-04-25 08:41:14 +02:00
Christian Schabesberger
d16ab2e643 remove sample client yet again 2022-04-25 08:41:14 +02:00
Christian Schabesberger
105830e4f0 apply requested changes 2022-04-25 08:41:14 +02:00
Christian Schabesberger
09375ce053 rebase okhttp_signleton fix on top of connection validator
fix token oauth token refresh error

pleasure the linter
2022-04-25 08:41:14 +02:00
Christian Schabesberger
fc4ae27bbe remove redundant intercept of httpclient with httpmethod 2022-04-25 08:41:14 +02:00
Schabi
344c1e1136 apply required fixes 2022-04-25 08:41:14 +02:00
Schabi
79e4287223 clean up http client 2022-04-25 08:41:14 +02:00
Christian Schabesberger
0313c1e103 get okhttp singleton removal changes to compile 2022-04-25 08:41:14 +02:00
Abel García de Prada
06e361afaa
Merge pull request #479 from owncloud/rename_check_script
rename verify_licnese_script back to check_script
2022-04-22 10:57:49 +02:00
Christian Schabesberger
217216e43f rename verify_licnese_script to check_code_script 2022-04-22 09:44:28 +02:00
Abel García de Prada
060a988978
Merge pull request #478 from owncloud/bump/gradle_kotlin
Bump gradle and kotlin to the latest versions
2022-04-11 09:29:57 +02:00
Abel García de Prada
e0b81bd11a Bump kotlin to 1.6.20 2022-04-08 10:53:23 +02:00
Abel García de Prada
97a613f168 Bump target sdk to api 31 2022-04-08 09:48:29 +02:00
Abel García de Prada
d8ac22d57e
Merge pull request #450 from owncloud/connection_validator
Connection validator
2022-03-31 14:55:31 +02:00
Christian Schabesberger
7c77c267f9 apply changes according to review 2022-03-23 13:27:19 +01:00
Christian Schabesberger
2a4195c966 fix lint and compile issues 2022-03-23 13:27:18 +01:00
Christian Schabesberger
d9dce81ce7 add GetBaseUrlRemoteOperation 2022-03-23 13:26:58 +01:00
Christian Schabesberger
4f3e167efa fix spelling mistakes 2022-03-23 13:26:58 +01:00
Christian Schabesberger
fc8440cc01 remove debug statements 2022-03-23 13:26:58 +01:00
Christian Schabesberger
5ca99a0e69 update base url in active client after 301 redirect
reduce validation retry count
2022-03-23 13:26:58 +01:00
Christian Schabesberger
ce761aaec2 remove redirect code from owncloudclient use okhttp instead 2022-03-23 13:26:58 +01:00
Christian Schabesberger
c59d1540c7 clean up credentials stuff from owncloudclient 2022-03-23 13:26:58 +01:00
Christian Schabesberger
5582097ca1 get access token to update through connection validator
update token
2022-03-23 13:26:58 +01:00
Christian Schabesberger
e27a968ddb add update authToken code to connectionValidator 2022-03-23 13:26:58 +01:00
Christian Schabesberger
cfd69987e9 update session from APM while running the app 2022-03-23 13:26:57 +01:00
Christian Schabesberger
b2f6d7f3b1 make initial check with apm work though connection validator 2022-03-23 13:24:27 +01:00
Christian Schabesberger
7ccb86c153 stop validation process if failing 2022-03-23 13:24:27 +01:00
Christian Schabesberger
e878ad3931 make oidc discovery work again 2022-03-23 13:24:27 +01:00
Schabi
8d09a5c242 make initial connection using connection validator work 2022-03-23 13:24:27 +01:00
Christian Schabesberger
ddb15a33f1 try shifting over to connection validator for updating credentials
intermediate commit
2022-03-23 13:24:27 +01:00
Christian Schabesberger
c2c351c912 set max redirect count for owncloud client to 5 2022-03-23 13:24:27 +01:00
Christian Schabesberger
ca206173df create logic scaffold for connection validator get status.php with it 2022-03-23 13:24:27 +01:00
Christian Schabesberger
7e4b43e7cb prepare code for the inclusion of connection validator 2022-03-23 13:24:27 +01:00
Christian Schabesberger
0e82f983b5 remove OwnCloudClient factory 2022-03-23 13:24:27 +01:00
Christian Schabesberger
0d94058db9 remove retrive cookies from middleware 2022-03-23 13:24:27 +01:00
Christian Schabesberger
2f952a3a09 debug and add mutex for halding requiests 2022-03-23 13:24:27 +01:00
Christian Schabesberger
39b1fce7f6 init connectionvalidator 2022-03-23 13:24:27 +01:00
Abel García de Prada
351efb7bf2
Merge pull request #474 from owncloud/dependabot/gradle/com.facebook.stetho-stetho-okhttp3-1.6.0
Bump stetho-okhttp3 from 1.5.1 to 1.6.0
2022-03-10 11:30:54 +01:00
dependabot[bot]
2edfc17653
Bump stetho-okhttp3 from 1.5.1 to 1.6.0
Bumps [stetho-okhttp3](https://github.com/facebook/stetho) from 1.5.1 to 1.6.0.
- [Release notes](https://github.com/facebook/stetho/releases)
- [Changelog](https://github.com/facebook/stetho/blob/main/CHANGELOG.md)
- [Commits](https://github.com/facebook/stetho/compare/v1.5.1...v1.6.0)

---
updated-dependencies:
- dependency-name: com.facebook.stetho:stetho-okhttp3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-10 10:15:54 +00:00
Abel García de Prada
e0efa7b3ab
Merge pull request #472 from owncloud/feature/check_script
Feature/check script
2022-03-10 10:21:07 +01:00
Abel García de Prada
5ab6514164 Rename the script and function to clarify their purpose 2022-03-10 09:45:34 +01:00
Christian Schabesberger
194894637e fix wrongly licensed source files 2022-03-10 09:45:34 +01:00
Christian Schabesberger
c662383182 add mit license header to where it was missing 2022-03-10 09:45:34 +01:00
Christian Schabesberger
f8c7c12f5b add check_script 2022-03-10 09:45:34 +01:00
Abel García de Prada
61508c85d1
Merge pull request #469 from owncloud/feature/add_stetho
Feature/add stetho
2022-03-08 09:27:34 +01:00
Christian Schabesberger
5619c1daf8 apply code cleanup according to review 2022-03-08 08:59:10 +01:00
Christian Schabesberger
85a3918ff1 fix usage of debug interceptor 2022-03-08 08:59:10 +01:00
Christian Schabesberger
7e507abf32 add debug interceptor 2022-03-08 08:59:10 +01:00
Abel García de Prada
a7e9138593
Merge pull request #471 from owncloud/fix/remove_sample_client
remove sample client
2022-03-08 08:58:00 +01:00
Christian Schabesberger
0ae5cf5ca2 remove sample client 2022-03-08 08:49:26 +01:00
Abel García de Prada
063e7366e5
Merge pull request #473 from owncloud/dependabot/github_actions/actions/checkout-3
Bump actions/checkout from 2 to 3
2022-03-07 07:52:38 +01:00
dependabot[bot]
5cec7b43e2
Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-03-07 02:03:39 +00:00
Abel García de Prada
ff0cde35fe
Merge pull request #466 from owncloud/release/1.0.14
[Release] 1.0.14
2022-02-16 10:45:45 +01:00
Fernando Sanz
a9a6ca6d4e Upgraded versionName and versionNumber 2022-02-09 14:32:09 +01:00
Abel García de Prada
57882e793e
Merge pull request #464 from owncloud/FixLint
Fix lint warnings
2022-01-31 09:10:32 +01:00
Hannes Achleitner
7365c0b126 Fix lint warnings 2022-01-31 08:09:53 +01:00
Abel García de Prada
5bebbe2d3d
Merge pull request #461 from owncloud/dependabot/gradle/org.jlleitschuh.gradle-ktlint-gradle-10.2.1
Bump ktlint-gradle from 10.2.0 to 10.2.1
2022-01-10 09:23:40 +01:00
dependabot[bot]
3aa9e72a22
Bump ktlint-gradle from 10.2.0 to 10.2.1
Bumps ktlint-gradle from 10.2.0 to 10.2.1.

---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle:ktlint-gradle
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-28 02:05:26 +00:00
Abel García de Prada
cc53ed6f68
Merge pull request #460 from owncloud/bump/kotlin_1.6.10
Bump kotlin version to 1.6.10
2021-12-23 10:34:59 +01:00
Abel García de Prada
377572e87a Bump kotlin version to 1.6.10 2021-12-23 09:31:34 +01:00
Abel García de Prada
9fc5ddbc39
Merge pull request #459 from hannesa2/Gradle-Log4j
Bump Gradle for Log4j
2021-12-23 08:37:55 +01:00
Hannes Achleitner
b649ee0ad6 Bump Gradle for Log4j
https://github.com/gradle/gradle/releases/tag/v7.3.3
2021-12-23 08:23:02 +01:00
Abel García de Prada
e6e763882c
Merge pull request #442 from owncloud/feature/avatar_capability_library
[Feature] Respect capability for Avatar support
2021-12-13 11:37:10 +01:00
Fernando Sanz
27e5d367af Ktlint fixes. 2021-12-13 08:53:18 +01:00
Fernando Sanz
2b299da415 Retrieve new capability to user's avatar. 2021-12-13 08:53:18 +01:00
Abel García de Prada
2c0745f20a
Merge pull request #454 from owncloud/dependabot/gradle/moshiVersion-1.13.0
Bump moshiVersion from 1.12.0 to 1.13.0
2021-12-10 08:30:20 +01:00
dependabot[bot]
1a4b98d232
Bump moshiVersion from 1.12.0 to 1.13.0
Bumps `moshiVersion` from 1.12.0 to 1.13.0.

Updates `moshi-kotlin` from 1.12.0 to 1.13.0
- [Release notes](https://github.com/square/moshi/releases)
- [Changelog](https://github.com/square/moshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/moshi/compare/moshi-parent-1.12.0...moshi-parent-1.13.0)

Updates `moshi-kotlin-codegen` from 1.12.0 to 1.13.0
- [Release notes](https://github.com/square/moshi/releases)
- [Changelog](https://github.com/square/moshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/moshi/compare/moshi-parent-1.12.0...moshi-parent-1.13.0)

---
updated-dependencies:
- dependency-name: com.squareup.moshi:moshi-kotlin
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.squareup.moshi:moshi-kotlin-codegen
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 02:09:45 +00:00
Abel García de Prada
aef967bf25
Merge pull request #452 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.7.3
Bump robolectric from 4.5.1 to 4.7.3
2021-12-02 08:52:35 +01:00
dependabot[bot]
5ce81e3b17
Bump robolectric from 4.5.1 to 4.7.3
Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.5.1 to 4.7.3.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.5.1...robolectric-4.7.3)

---
updated-dependencies:
- dependency-name: org.robolectric:robolectric
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-02 02:08:45 +00:00
Abel García de Prada
4fa986e053
Merge pull request #448 from owncloud/gradle_7.3
Bump gradle version to 7.3
2021-11-17 13:18:31 +01:00
Abel García de Prada
5e8f0b8286 Bump gradle version to 7.3 2021-11-17 10:31:10 +01:00
Abel García de Prada
050b98f78b
Merge pull request #433 from owncloud/Gradle-7.2
Gradle 7.2
2021-11-17 10:03:53 +01:00
Hannes Achleitner
487c4f682a Gradle 7.2 2021-11-17 09:50:05 +01:00
Abel García de Prada
f75f64ab13
Merge pull request #434 from owncloud/api30
Api 30
2021-11-17 09:46:11 +01:00
Hannes Achleitner
dd088d7222 Api 30 2021-11-17 09:32:18 +01:00
Abel García de Prada
05705722ef
Merge pull request #447 from owncloud/bump_several_dependencies
Bump Kotlin version to 1.5.31
2021-11-17 09:19:36 +01:00
Abel García de Prada
36cf45c377 Bump some dependencies 2021-11-17 08:51:39 +01:00
Abel García de Prada
eea5240bd0
Merge pull request #441 from owncloud/release/1.0.13
[Release] 1.0.13
2021-11-15 11:22:22 +01:00
Fernando Sanz
20efe90e2d QA report (5) fixed 2021-11-08 13:37:52 +01:00
Abel García de Prada
83048b61d8 Update versionName and versionCode for a new stable release 2021-11-05 13:18:04 +01:00
Abel García de Prada
8a3ba16f96
Merge pull request #440 from owncloud/release/1.0.13_beta.1
[Release] 1.0.13-beta.1
2021-11-05 08:25:12 +01:00
Abel García de Prada
e6b3df103e Update versionCode and versionName 2021-11-03 18:23:58 +01:00
Abel García de Prada
37bae10618
Merge pull request #436 from owncloud/fix/final_chunk_size
Fix a protocol exception when uploading chunked files
2021-11-03 18:07:18 +01:00
Abel García de Prada
10e44627e1 Change last chunk size to fix a protocol exception when sending files 2021-09-28 10:58:32 +02:00
Abel García de Prada
1baeebe5ee
Merge pull request #430 from owncloud/feature/parse_shares
[FEATURE REQUEST] Use Moshi to parse shares
2021-09-24 11:49:33 +02:00
Abel García de Prada
fa7d83edb3
Merge pull request #432 from owncloud/dependabot/gradle/org.jlleitschuh.gradle-ktlint-gradle-10.2.0
Bump ktlint-gradle from 10.1.0 to 10.2.0
2021-09-09 08:10:44 +02:00
dependabot[bot]
46dcb4434d
Bump ktlint-gradle from 10.1.0 to 10.2.0
Bumps ktlint-gradle from 10.1.0 to 10.2.0.

---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle:ktlint-gradle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-09 02:06:37 +00:00
Fernando Sanz
3c46c95ac1 Code revision suggestions have been implemented. 2021-09-02 12:33:48 +02:00
Fernando Sanz
f14abb0bcd Code revision suggestions have been implemented. 2021-09-02 10:55:02 +02:00
Fernando Sanz
0895732ed4 Library's copyright has been modified and restored. 2021-09-01 13:23:49 +02:00
Fernando Sanz
91bd322b68 The ShareXMLParser has been removed from UpdateRemoteShareOperation.kt class. 2021-08-31 14:47:48 +02:00
Fernando Sanz
7baf3e43a5 The ShareXMLParser has been removed from RemoveRemoteShareOperation.kt class. 2021-08-31 12:37:36 +02:00
Fernando Sanz
6285c6c70a The ShareXMLParser has been removed from GetRemoteSharesForFileOperation.kt class. 2021-08-31 11:59:41 +02:00
Fernando Sanz
b40a394ab1 The ShareXMLParser has been removed from CreateRemoteShareOperation.kt class. 2021-08-31 10:43:29 +02:00
Fernando Sanz
037a2b30df Fixed some bugs on how to create shares. 2021-08-31 08:52:55 +02:00
Abel García de Prada
45fb12df0e Fix shares parsing 2021-08-27 15:38:49 +02:00
Fernando Sanz
27b18c33a9 The way to retrieve list of shares has been modified from java to kotlin and its result has been parsed to ShareResponse.kt object. 2021-08-27 14:08:58 +02:00
Christian Schabesberger
c24ffcfaa4
Merge pull request #425 from owncloud/fix/add_content_length_error
add error log when content-length not equal to transfaired bytes
2021-08-18 17:13:20 +02:00
Christian Schabesberger
fbf0fab800 add error log when content-length not equal to transfaired bytes 2021-08-17 12:41:35 +02:00
Abel García de Prada
5852921764
Merge pull request #420 from owncloud/release/1.0.12
[Release] 1.0.12
2021-07-20 12:55:28 +02:00
Abel García de Prada
7b5c070175 Update version name and version code 2021-07-15 09:55:21 +02:00
Abel García de Prada
650f348c35
Merge pull request #419 from owncloud/improvement/oauth2_pkce
Add PKCE support
2021-07-14 19:11:21 +02:00
Abel García de Prada
20070775d7 Add parameters required for PKCE 2021-07-14 12:40:08 +02:00
Abel García de Prada
593da77a04
Merge pull request #418 from owncloud/dependabot/gradle/kotlinVersion-1.5.21
Bump kotlinVersion from 1.5.20 to 1.5.21
2021-07-14 09:33:08 +02:00
dependabot[bot]
3025ddce23
Bump kotlinVersion from 1.5.20 to 1.5.21
Bumps `kotlinVersion` from 1.5.20 to 1.5.21.

Updates `kotlin-gradle-plugin` from 1.5.20 to 1.5.21
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.21/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.20...v1.5.21)

Updates `kotlin-stdlib-jdk8` from 1.5.20 to 1.5.21
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.5.21/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.5.20...v1.5.21)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib-jdk8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-14 07:06:34 +00:00
Abel García de Prada
ac2f837f9e
Merge pull request #414 from owncloud/new_arch/camera_uploads
[New arch] Camera Uploads
2021-07-14 09:05:36 +02:00
Abel García de Prada
22719c8f40 Return unit in the remote operation 2021-07-08 12:24:21 +02:00
Abel García de Prada
12b009e378 Update operation 2021-07-05 09:17:37 +02:00
Abel García de Prada
5c2be25d66 Override contentLength in content uri request body to fix uploads to ocis 2021-07-05 09:17:37 +02:00
Abel García de Prada
99e636e8f6 Add a new operation to upload files directly with a content uri 2021-07-05 09:17:37 +02:00
Abel García de Prada
022c486603
Merge pull request #415 from owncloud/bump_kotlin_gradle
Bump kotlin to 1.5.20
2021-07-02 13:07:53 +02:00
Abel García de Prada
b491641eff Bump kotlin to 1.5.20 2021-07-02 09:57:38 +02:00
Abel García de Prada
86bfc3383c
Merge pull request #410 from owncloud/dependabot/gradle/org.jlleitschuh.gradle-ktlint-gradle-10.1.0
Bump ktlint-gradle from 10.0.0 to 10.1.0
2021-06-04 08:20:47 +02:00
dependabot[bot]
58ac89cb30
Bump ktlint-gradle from 10.0.0 to 10.1.0
Bumps ktlint-gradle from 10.0.0 to 10.1.0.

---
updated-dependencies:
- dependency-name: org.jlleitschuh.gradle:ktlint-gradle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-03 06:49:43 +00:00
Abel García de Prada
cfe5793d0d
Merge pull request #409 from owncloud/bump/kotlin_version
Bump kotlin version and AS
2021-05-26 09:38:43 +02:00
Abel García de Prada
c02a4dea91 Bump kotlin version 2021-05-26 08:57:03 +02:00
Abel García de Prada
e9d23d9cd2
Merge pull request #403 from owncloud/Gradle-6.9
Gradle 6.9
2021-05-24 09:46:36 +02:00
Hannes Achleitner
93497ca225 Gradle 6.9
It comes with Apple Silicon support
2021-05-24 09:36:33 +02:00
Abel García de Prada
abdbdbe4cc
Merge pull request #405 from owncloud/release/1.0.11
[Release] 1.0.11
2021-05-24 08:25:39 +02:00
Abel García de Prada
351682cc7f Use userId instead of username to build the webdavurl 2021-05-21 13:16:04 +02:00
Abel García de Prada
634c4a0f93 Update version name and version code for release 1.0.11 2021-05-18 12:19:40 +02:00
Abel García de Prada
307bf93a40
Merge pull request #404 from owncloud/MoveToMavenCentral
MavenCentral
2021-05-17 09:11:21 +02:00
Hannes Achleitner
d0e50c4fca MavenCentral 2021-05-15 07:07:16 +02:00
Abel García de Prada
bf6f93ff1c
Merge pull request #396 from owncloud/fix/xodo_bug
fix xodo sync bug
2021-05-11 17:09:09 +02:00
Abel García de Prada
2c18ae4ebb Clean unused imports 2021-05-10 09:56:18 +02:00
Christian Schabesberger
594ed2ee1b fix xodo file sync bug 2021-04-30 15:58:42 +02:00
Abel García de Prada
ccaf5a8e0e
Merge pull request #392 from owncloud/fix/oidc_no_registration_endpoint
Make some fields not mandatory in discovery response
2021-04-22 13:48:22 +02:00
Abel García de Prada
8c4a2708c2 Make some fields not mandatory in discovery response 2021-04-22 12:50:27 +02:00
Abel García de Prada
3f8ddd0ba9
Merge pull request #391 from owncloud/ktLintLibraryCheck
ktLint check in library
2021-04-22 12:47:51 +02:00
Abel García de Prada
13344ae622 Fix lint errors 2021-04-21 18:59:17 +02:00
Abel García de Prada
845b61ea4d Enable import ordering rule 2021-04-21 18:44:48 +02:00
Hannes Achleitner
257f616b0f ktLint check in library 2021-04-14 10:33:49 +02:00
Abel García de Prada
7dc81fb74c
Merge pull request #390 from owncloud/ktLint
Fix some ktlint findings
2021-04-14 09:45:16 +02:00
Abel García de Prada
1287035311 Fix some ktlint findings 2021-04-12 08:18:32 +02:00
Abel García de Prada
5ca9d5e330
Merge pull request #388 from owncloud/bump_kotlin_version
Bump kotlin version
2021-04-06 11:32:26 +02:00
Abel García de Prada
7924561a62 Bump kotlin version 2021-04-06 09:55:19 +02:00
Abel García de Prada
aa65410535
Merge pull request #387 from owncloud/dependabot/gradle/moshiVersion-1.12.0
Bump moshiVersion from 1.11.0 to 1.12.0
2021-04-06 09:46:04 +02:00
dependabot[bot]
88bb79c5ea
Bump moshiVersion from 1.11.0 to 1.12.0
Bumps `moshiVersion` from 1.11.0 to 1.12.0.

Updates `moshi-kotlin` from 1.11.0 to 1.12.0
- [Release notes](https://github.com/square/moshi/releases)
- [Changelog](https://github.com/square/moshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/moshi/compare/moshi-parent-1.11.0...parent-1.12.0)

Updates `moshi-kotlin-codegen` from 1.11.0 to 1.12.0
- [Release notes](https://github.com/square/moshi/releases)
- [Changelog](https://github.com/square/moshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/moshi/compare/moshi-parent-1.11.0...parent-1.12.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-05 09:33:44 +00:00
Abel García de Prada
87aa7137e7
Merge pull request #385 from owncloud/ktLintFindings
Fix ktlint findings
2021-04-05 08:21:24 +02:00
Hannes Achleitner
4df880357c Fix ktlint findings 2021-03-24 11:37:48 +01:00
JuancaG05
d1765eefb3
Merge pull request #384 from owncloud/bump_gradle_version
Bump gradle version to 1.4.3
2021-03-23 11:54:47 +01:00
Abel García de Prada
bf0ff3ce11 Bump gradle version to 1.4.3 2021-03-23 10:06:58 +01:00
Abel García de Prada
286fd65aff
Merge pull request #377 from owncloud/dependabot/gradle/org.robolectric-robolectric-4.5.1
Bump robolectric from 4.3.1 to 4.5.1
2021-03-22 15:07:30 +01:00
dependabot[bot]
a5574e1e45
Bump robolectric from 4.3.1 to 4.5.1
Bumps [robolectric](https://github.com/robolectric/robolectric) from 4.3.1 to 4.5.1.
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.3.1...robolectric-4.5.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-22 11:27:08 +00:00
Abel García de Prada
0daa19cf90
Merge pull request #380 from owncloud/release/1.0.10
[Release] 1.0.10
2021-03-22 11:23:32 +01:00
Abel García de Prada
663e067d08 Update client with latest url 2021-03-16 12:40:51 +01:00
Abel García de Prada
a60c4909f4 Prepare 1.0.10 release 2021-03-16 11:11:39 +01:00
Abel García de Prada
b96a3e9be3
Merge pull request #376 from owncloud/release/1.0.10_beta.1
[RELEASE] 1.0.10-beta.1
2021-03-09 15:11:36 +01:00
Abel García de Prada
46495e0df2 Update versionCode and versionName 2021-03-08 16:26:20 +01:00
Abel García de Prada
87a05491ab
Merge pull request #368 from owncloud/fix/cookie_handling
[Fix] Cookie handling
2021-03-08 15:01:02 +01:00
Abel García de Prada
f248448e08 Update licenses, naming and apply CR suggestions 2021-03-02 10:35:51 +01:00
Abel García de Prada
3a79a86cd7 Fix 301 redirections 2021-03-02 10:34:39 +01:00
Abel García de Prada
1194b9a412 Use the same ownCloudClient across the whole login process 2021-03-02 10:34:39 +01:00
Christian Schabesberger
2a23a1c773 remove result from status requester 2021-03-02 10:34:39 +01:00
Schabi
9ad0e8f9bc apply codereview 2021-03-02 10:34:39 +01:00
Schabi
61ee5aab91 add test from redirect from http to http 2021-03-02 10:34:39 +01:00
Schabi
950d3a50da fix wrong handling of redirect to unsecure connection 2021-03-02 10:34:39 +01:00
Schabi
8eaa98af30 accept ssl connections for status when OK is returned 2021-03-02 10:34:39 +01:00
Abel García de Prada
6ea9f9996d Fix problem during rebase 2021-03-02 10:34:39 +01:00
Christian Schabesberger
f9ea701e2f remove cookie persistence 2021-03-02 10:34:38 +01:00
Christian Schabesberger
51dacd0bb0 remove KEY_OC_VERSION key 2021-03-02 10:34:38 +01:00
Christian Schabesberger
033e6822a2 prevent acumulating cookies on account change 2021-03-02 10:34:38 +01:00
agarcia
f8904dca9d Make get cookies static 2021-03-02 10:34:38 +01:00
Christian Schabesberger
654efea7e5 add tests for cookie jar 2021-03-02 10:34:38 +01:00
Christian Schabesberger
c3189b7b46 replace old cookies but don't delete them 2021-03-02 10:34:38 +01:00
agarcia
c54f1c98f6 Update some tests naming and remove unused dependencies 2021-03-02 10:34:38 +01:00
Christian Schabesberger
cba63c060f use robolectric for android tests 2021-03-02 10:34:38 +01:00
Christian Schabesberger
d0a710e31b add fixes according to review 2021-03-02 10:33:49 +01:00
Christian Schabesberger
91c7900d5c fix ip address without http prefix not recognized 2021-03-02 10:33:49 +01:00
Christian Schabesberger
b207fd1c67 fix rellative redirect 2021-03-02 10:33:49 +01:00
Christian Schabesberger
dac7bcc0e7 pleasure the linter 2021-03-02 10:33:49 +01:00
Christian Schabesberger
270e127940 fix according to review 2021-03-02 10:33:49 +01:00
Christian Schabesberger
84240ef78b detach request logic from operation 2021-03-02 10:33:49 +01:00
Christian Schabesberger
9d4b88cad7 refactor run function 2021-03-02 10:33:49 +01:00
Christian Schabesberger
cbfd977350 clean up tryConnect function 2021-03-02 10:33:49 +01:00
Christian Schabesberger
257cbcff03 add basic test functionality for andorid library 2021-03-02 10:33:49 +01:00
Christian Schabesberger
cc91ad9dde add fix for redirect, untested 2021-03-02 10:33:49 +01:00
Abel García de Prada
9ffe758dca
Merge pull request #374 from owncloud/dependabot/gradle/junit-junit-4.13.2
Bump junit from 4.13.1 to 4.13.2
2021-03-02 10:33:23 +01:00
dependabot[bot]
e821bee594
Bump junit from 4.13.1 to 4.13.2
Bumps [junit](https://github.com/junit-team/junit4) from 4.13.1 to 4.13.2.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.13.1.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.13.1...r4.13.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-02 08:31:56 +00:00
Abel García de Prada
4676eb48d7
Merge pull request #373 from owncloud/dependabot/gradle/moshiVersion-1.11.0
Bump moshiVersion from 1.9.2 to 1.11.0
2021-03-02 09:31:02 +01:00
dependabot[bot]
38d4dd604e
Bump moshiVersion from 1.9.2 to 1.11.0
Bumps `moshiVersion` from 1.9.2 to 1.11.0.

Updates `moshi-kotlin` from 1.9.2 to 1.11.0
- [Release notes](https://github.com/square/moshi/releases)
- [Changelog](https://github.com/square/moshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/moshi/compare/moshi-parent-1.9.2...moshi-parent-1.11.0)

Updates `moshi-kotlin-codegen` from 1.9.2 to 1.11.0
- [Release notes](https://github.com/square/moshi/releases)
- [Changelog](https://github.com/square/moshi/blob/master/CHANGELOG.md)
- [Commits](https://github.com/square/moshi/compare/moshi-parent-1.9.2...moshi-parent-1.11.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-02 08:13:05 +00:00
Abel García de Prada
0a31a1d3ef
Merge pull request #375 from owncloud/dependabot/gradle/kotlinVersion-1.4.31
Bump kotlinVersion from 1.4.30 to 1.4.31
2021-03-02 09:12:20 +01:00
dependabot[bot]
97df0b655d
Bump kotlinVersion from 1.4.30 to 1.4.31
Bumps `kotlinVersion` from 1.4.30 to 1.4.31.

Updates `kotlin-gradle-plugin` from 1.4.30 to 1.4.31
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.4.31/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.4.30...v1.4.31)

Updates `kotlin-stdlib-jdk8` from 1.4.30 to 1.4.31
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/v1.4.31/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.4.30...v1.4.31)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-02 07:00:20 +00:00
Abel García de Prada
ec4c0b2a7f
Merge pull request #371 from owncloud/Dependabot
Introduce dependabot
2021-02-23 13:03:01 +01:00
Abel García de Prada
e438ded413
Merge pull request #367 from owncloud/feature/oidc_dynamic_client_registration
[FEATURE] OIDC Dynamic Client Registration
2021-02-22 17:19:08 +01:00
Hannes Achleitner
94065ae449 Introduce dependabot 2021-02-18 08:32:51 +01:00
Abel García de Prada
37250fc55c Apply CR suggestions 2021-02-10 14:04:05 +01:00
Abel García de Prada
f35f41688a Create remote operation to register clients dynamically. 2021-02-10 14:04:05 +01:00
Abel García de Prada
3b138e7c01
Merge pull request #370 from owncloud/bump/kotlin_version
Bump kotlinVersion from 1.4.21 to 1.4.30
2021-02-09 12:52:53 +01:00
Abel García de Prada
67699ffcc0 Bump kotlinVersion from 1.4.20 to 1.4.30 2021-02-09 12:19:18 +01:00
Abel García de Prada
8e38c26374
Merge pull request #369 from owncloud/Modernize
Android Studio and Gradle update
2021-02-05 08:18:32 +01:00
Hannes Achleitner
e792cf6c70 Android Studio 4.1.2 2021-02-02 17:27:36 +01:00
Hannes Achleitner
fbbb1c9adb Gradle 6.8.1 2021-02-02 17:27:13 +01:00
Abel García de Prada
0e325cabd6
Merge pull request #363 from owncloud/feature/oauth_custom_implementation
[Feature] OAuth2 - OIDC Custom implementation
2021-02-02 09:36:04 +01:00
Abel García de Prada
9ae720502f Apply Code Review suggestions 2021-01-26 17:08:28 +01:00
Abel García de Prada
0d09540f9b Apply suggestions from CR 2021-01-26 17:08:28 +01:00
Abel García de Prada
44a13f9878 Polish a little bit the code 2021-01-26 17:08:28 +01:00
Abel García de Prada
df8e10fac3 Polish code. Send only info required for each type of request 2021-01-26 17:08:28 +01:00
Abel García de Prada
9208af89fe Support refresh token with any idP 2021-01-26 17:08:28 +01:00
Abel García de Prada
d683da3602 Support refresh token with own idP 2021-01-26 17:08:28 +01:00
Abel García de Prada
44967be4e3 First draft of request token implementation 2021-01-26 17:08:28 +01:00
Abel García de Prada
f289746c2f Use ownCloud client base url to perform oidc discovery 2021-01-26 17:08:28 +01:00
Abel García de Prada
0fc3f7668d Use the same ownCloudClient across the whole login process 2021-01-26 17:08:28 +01:00
Abel García de Prada
18b271665d Get OIDC discovery config 2021-01-26 17:08:28 +01:00
Abel García de Prada
c3ffe3d916
Merge pull request #365 from owncloud/release/1.0.9
[Release] 1.0.9
2021-01-26 12:44:02 +01:00
Abel García de Prada
65a4aaac28 Release 1.0.9 Update versionName and versionCode 2021-01-18 09:21:47 +01:00
Abel García de Prada
7ccda7d249
Merge pull request #362 from owncloud/fix/ocis_size
Use constants instead of hardcoded values for dir mimetypes
2021-01-14 13:44:16 +01:00
Abel García de Prada
114a7221f3 Use constants instead of hardcoded values for dir mimetypes 2020-12-22 10:50:20 +01:00
Abel García de Prada
6253f1e198
Merge pull request #361 from hannesa2/LiveLogcat
Show logcat live
2020-12-18 10:13:49 +01:00
Hannes Achleitner
cd8878352d delete logcat history 2020-12-16 14:09:22 +01:00
Hannes Achleitner
2a4f8175da Show logcat live
It updates logcat content during observation
2020-12-16 11:33:48 +01:00
Abel García de Prada
9bef933428
Merge pull request #360 from owncloud/AndroidStudio-4.1.1
Android Studio 4.1.1
2020-12-15 11:13:57 +01:00
Abel García de Prada
102747c392 Android Studio 4.1.1 2020-12-02 15:32:31 +01:00
Abel García de Prada
ceee204399
Merge pull request #358 from owncloud/feature/redirection_callback_brandable
Move appauth dependency to ownCloudApp
2020-12-02 15:31:08 +01:00
Abel García de Prada
0eeb48f7de Move appauth dependency to ownCloudApp 2020-12-02 14:57:17 +01:00
Abel García de Prada
a18528effc
Merge pull request #355 from owncloud/fix/parse_shareid_as_string
Parse shareId as String
2020-12-01 17:28:10 +01:00
Abel García de Prada
20c7c88a1f Remove item_source and file_source 2020-11-03 18:31:51 +01:00
Abel García de Prada
3441f4048c Convert long shareId to String 2020-11-03 11:46:44 +01:00
Abel García de Prada
af579a3fd0
Merge pull request #352 from owncloud/new_arch/moshi_parse_sharees
[New arch] Use moshi to parse sharees
2020-10-29 13:15:24 +01:00
Christian Schabesberger
68b88775e6 apply changes acording to review 2020-10-29 12:37:27 +01:00
Christian Schabesberger
ce9fc3f189 apply changes acording to review 2020-10-29 12:37:27 +01:00
Christian Schabesberger
257494a9dc apply suggested changes
delete unused const values

bla
2020-10-29 12:37:27 +01:00
Christian Schabesberger
6ec1bd2bb2 move response json to resource folder 2020-10-29 12:37:26 +01:00
Christian Schabesberger
76c55c9a9c add changes according to review 2020-10-29 12:37:26 +01:00
Christian Schabesberger
db478efedc refactor ShareType 2020-10-29 12:37:26 +01:00
Christian Schabesberger
29de5aba34 disable unitTestBinaryResource as its deprecated 2020-10-29 12:37:26 +01:00
Christian Schabesberger
34bf83df30 make sharee parts non null that can't be null 2020-10-29 12:37:26 +01:00
Christian Schabesberger
90b6ff52f2 add aditional data field to ocs sharees 2020-10-29 12:37:26 +01:00
Christian Schabesberger
26def4fbe2 return sharees without exact match 2020-10-29 12:37:26 +01:00
Christian Schabesberger
7402c89a18 get flat representation from ShareeOcsResponse 2020-10-29 12:37:26 +01:00
Christian Schabesberger
fe425c8083 update shareeservice to use ShareeOcsResponse 2020-10-29 12:37:26 +01:00
Christian Schabesberger
b86638412e update GetRemoteShareesOperation to use moshi 2020-10-29 12:37:26 +01:00
Christian Schabesberger
1c08a942d1 test model 2020-10-29 12:37:26 +01:00
Christian Schabesberger
6bdb2badca add support for tests 2020-10-29 12:37:26 +01:00
Christian Schabesberger
9f1c20b418 add Sharee response model 2020-10-29 12:37:26 +01:00
Christian Schabesberger
4f72f93f8b clean run method by braking down into small functions 2020-10-29 12:37:26 +01:00
Christian Schabesberger
8a04231473 move responses models into module folder 2020-10-29 12:37:26 +01:00
Abel García de Prada
61937825b8
Merge pull request #345 from owncloud/add_network_logs
Log network calls
2020-10-28 13:18:18 +01:00
Abel García de Prada
2b64b83b89 Do not log Authorization header 2020-10-28 09:17:27 +01:00
Abel García de Prada
5e86e9f0e4 Determine if a body is loggable based on its content-type 2020-10-28 09:04:17 +01:00
Abel García de Prada
460f85f2e1 Remove binary file logs 2020-10-27 16:12:23 +01:00
Abel García de Prada
943c5ecb97 Fix typo 2020-10-27 16:09:01 +01:00
Abel García de Prada
781f958c93 Do not log chunk request body 2020-10-23 11:39:24 +02:00
Abel García de Prada
db97ed7fb3 Fix response log marked as request one 2020-10-21 18:21:39 +02:00
Abel García de Prada
197c86ec64 Add LogInterceptor as NetworkInterceptor 2020-10-21 15:59:39 +02:00
Abel García de Prada
c0d2e20bb1 Log http body if it is not binary 2020-10-21 15:39:48 +02:00
Abel García de Prada
aa665a7295 Show request headers and body properly 2020-10-20 11:31:52 +02:00
Abel García de Prada
dc39475760 Add log interceptor disabled by default 2020-10-19 09:00:26 +02:00
Abel García de Prada
b7fd663d77 Improve http logs 2020-10-19 09:00:26 +02:00
Abel García de Prada
dc215dc80e Add a new variable to enable or disable http logs 2020-10-19 09:00:26 +02:00
Abel García de Prada
a564f18f16 Http logs enabled only in debug versions 2020-10-19 09:00:26 +02:00
agarcia
775fdb080c Add first draft to log network calls 2020-10-19 09:00:26 +02:00
Abel García de Prada
e28335ae4e
Merge pull request #351 from owncloud/update_dependencies
Update dependencies and perform a little cleanup
2020-10-16 15:04:03 +02:00
Abel García de Prada
4b6946a195 Update dependencies and perform a little cleanup 2020-10-14 16:22:20 +02:00
Abel García de Prada
5d21f01f38
Merge pull request #346 from owncloud/release/1.0.8
[Release] 1.0.8
2020-10-01 13:59:27 +02:00
agarcia
4d22971de0 Upgrade version code and version name 2020-09-30 16:52:50 +02:00
Abel García de Prada
411364b378
Merge pull request #344 from owncloud/remove_single_cookie_header
Remove single cookie header
2020-09-30 16:42:12 +02:00
agarcia
a55498c64b Remove single cookie header 2020-09-30 08:36:12 +02:00
Abel García de Prada
8da24c5076
Merge pull request #340 from owncloud/release/1.0.7
[Release] 1.0.7
2020-09-04 13:47:58 +02:00
agarcia
154507773d Upgrade version code and version name 2020-09-03 13:58:28 +02:00
Abel García de Prada
925f1e79aa
Merge pull request #330 from owncloud/UpdateLogcat
Update logcat
2020-08-12 18:25:59 +02:00
Hannes Achleitner
6d5d90d58c Update logcat 2020-08-12 15:58:38 +02:00
Abel García de Prada
f184347235
Merge pull request #333 from owncloud/release/1.0.6
[Release] 1.0.6
2020-08-12 13:50:51 +02:00
agarcia
a7a269a9e4 Fix timestamps 2020-08-11 18:40:17 +02:00
agarcia
f09162b213 Fix redirections 2020-08-04 17:27:58 +02:00
agarcia
31d3bfbde9 Move RequestBody to constructor to avoid npe 2020-08-04 17:27:58 +02:00
agarcia
f89cfd91a9 Reformat some code thanks to code review 2020-08-04 17:27:58 +02:00
agarcia
69497645ec Update dav4android and fix timestamp error depending on locale 2020-08-04 17:27:58 +02:00
agarcia
c5891b0a14 Remove interceptor and fix some errors related with shares 2020-08-04 17:27:58 +02:00
agarcia
b287cb9148 Compile project with latest changes from OkHttp and dav4jvm 2020-08-04 17:27:58 +02:00
agarcia
93026e8180 First step to replace interceptor 2020-08-04 17:27:58 +02:00
agarcia
c5cf0a8c0f Migrate http methods to kotlin 2020-08-04 17:27:57 +02:00
agarcia
aebd7288cd Migrate DavUtils to kotlin and fix a compilation error 2020-08-04 17:27:57 +02:00
agarcia
7f2d94bc78 Migrate webdav wrappers to kotlin 2020-08-04 17:27:57 +02:00
agarcia
c5fd59c825 Add support for version.hide config 2020-08-04 17:27:57 +02:00
agarcia
f93887732c Fix path dav4android -> dav4jvm 2020-08-04 17:27:57 +02:00
agarcia
ffe7d9d8e3 Update dav4android and okttp versions to 4.6.0 2020-08-04 17:27:57 +02:00
agarcia
390ef9fbd7 Update versionCode and versionName 2020-08-04 17:27:57 +02:00
Abel García de Prada
6cb2642ba1
Merge pull request #337 from owncloud/AndroidStudio_4.0.1
Android Studio 4.0.1
2020-08-04 17:15:08 +02:00
agarcia
ceab9378ab Update Android Studio to 4.0.1 2020-08-04 16:17:15 +02:00
Abel García de Prada
137b417580
Merge pull request #331 from owncloud/fix/refresh_basic_credentials
[Fix] Refresh credentials
2020-07-01 08:45:36 +02:00
agarcia
23a38a7fe6 Refresh stored client credentials when needed 2020-06-30 18:32:38 +02:00
Abel García de Prada
cdd16046a8
Merge pull request #329 from owncloud/UseAndroidSeparator
Use Android separator instead of homemade one
2020-06-30 12:50:56 +02:00
Hannes Achleitner
070ac89fa9 Use Android separator instead of homemade one 2020-06-25 06:14:16 +02:00
Abel García de Prada
d28927712c
Merge pull request #327 from owncloud/new_arch/sync_user
[New Arch] Sync user profile
2020-06-22 12:17:21 +02:00
agarcia
7536ba8f3c Apply code review suggestions 2020-06-16 17:21:15 +02:00
agarcia
d6ea5800eb Take care when quota available and used are 0 2020-06-16 17:21:15 +02:00
agarcia
59229aa6ab Remove avatar dimension from Service constructor 2020-06-16 17:21:15 +02:00
agarcia
ac21650da7 Manage responses with no avatar 2020-06-16 17:21:15 +02:00
agarcia
d997c84a80 Keep working on avatar rearquitecture 2020-06-16 17:21:15 +02:00
agarcia
6f74907af6 Migrate GetRemoteUserAvatarOperation to kotlin 2020-06-16 17:21:15 +02:00
agarcia
8a88fbd938 Apply CR suggestions 2020-06-16 17:21:15 +02:00
agarcia
bbac8d0278 Polish remote operation 2020-06-16 17:21:15 +02:00
agarcia
337c57da1a Include GetQuota in UserService 2020-06-16 17:21:15 +02:00
agarcia
85782e4818 Migrate GetRemoteUserQuotaOperation to kotlin 2020-06-16 17:21:15 +02:00
Abel García de Prada
e5e226dee0
Merge pull request #325 from owncloud/feature/android10
Upgrade target version to v29
2020-06-16 17:16:34 +02:00
agarcia
76a808cb0d Use TLSv1.3 if available 2020-06-15 14:16:45 +02:00
agarcia
7710db7612 Upgrade target version to v29 2020-06-09 11:26:23 +02:00
Abel García de Prada
d157c107c8
Merge pull request #322 from owncloud/AndroidStudio-4.0
Android Studio 4.0
2020-06-09 11:24:53 +02:00
agarcia
5ef9243a53 Update gradle to 6.5 2020-06-08 09:55:36 +02:00
Hannes Achleitner
f77de321b7 Android Studio 4.0 2020-06-08 09:37:06 +02:00
Abel García de Prada
d6eb080389
Merge pull request #319 from owncloud/release/1.0.5
[Release] 1.0.5
2020-06-03 11:14:11 +02:00
agarcia
1cee1a7a65 Update versionCode and versionName 2020-05-27 12:54:34 +02:00
Abel García de Prada
8708af1cfd
Merge pull request #321 from owncloud/release/1.0.5_beta.2
[Release] 1.0.5 beta 2
2020-05-22 14:58:22 +02:00
agarcia
e2f858238b Add chunking capability 2020-05-15 10:10:18 +02:00
Abel García de Prada
0e39f949e5
Merge pull request #318 from owncloud/cleanup/remove_unused_capabilities
Removed unused capabilities
2020-05-15 08:43:46 +02:00
agarcia
837aa39b23 Removed unused capabilities 2020-05-14 09:58:28 +02:00
agarcia
fc8c256463 Update versionCode and versionName 2020-05-12 13:09:21 +02:00
Abel García de Prada
8228374d71
Merge pull request #316 from owncloud/release/1.0.5_beta.1
[Release] 1.0.5 beta 1
2020-05-06 14:57:41 +02:00
agarcia
fba6436b56 Update versionCode and versionName 2020-05-06 13:59:06 +02:00
Abel García de Prada
9e9877f2bf
Merge pull request #298 from owncloud/feature/use_moshi_to_parse_capabilities
Use Moshi to parse Capabilities
2020-05-05 10:37:40 +02:00
agarcia
42b923c3b8 Allow capabilities to be null 2020-05-05 08:51:39 +02:00
agarcia
679b91df7c Apply CR suggestions 2020-05-05 08:51:39 +02:00
agarcia
b10e74afec Use moshi to parse capabilities 2020-05-05 08:51:39 +02:00
abelgardep
7b29f8f09e Create a common response to parse json 2020-05-05 08:51:39 +02:00
abelgardep
48ee263951 First attempt to use Moshi to parse capabilities 2020-05-05 08:51:39 +02:00
Abel García de Prada
0f10c725c7
Merge pull request #317 from owncloud/AndroidStudio3.6.3
Update Android Studio to 3.6.3
2020-05-05 08:39:19 +02:00
agarcia
7f7fa0b74e Update Android Studio to 3.6.3 2020-04-30 12:18:47 +02:00
Abel García de Prada
8f62925312
Merge pull request #315 from owncloud/oidc_new_arch
Open Id Connect along with new arch in login
2020-04-29 18:31:30 +02:00
davigonz
d957d48279 Move some OAuth constants out of the library 2020-04-29 17:32:54 +02:00
davigonz
7b32f7bbe4 Move OAuthConnectionBuilder to presentation layer, along with the rest of AppAuth dependencies 2020-04-29 17:32:54 +02:00
davigonz
5371c682d4 Add oidc scope constant 2020-04-29 17:32:54 +02:00
davigonz
f20d2554bf Fix crash when response body is empty and solve issue when retrieving auth methods 2020-04-29 17:32:54 +02:00
Abel García de Prada
64bfd6a7f7
Merge pull request #314 from owncloud/fix/short_names_not_found_as_recipients
Remove search min length capability
2020-04-22 11:02:22 +02:00
agarcia
54d03cdfd5 Remove search min length capability 2020-04-22 10:07:03 +02:00
David González Verdugo
5ecd3c9311
Merge pull request #307 from owncloud/new_arch/login
[New arch] Login
2020-04-17 15:41:01 +02:00
agarcia
9e46b83901 A little cleanup 2020-04-16 14:31:08 +02:00
davigonz
18b0abb01a Apply CR changes 2020-04-16 14:31:08 +02:00
davigonz
bec5643714 Include services implementation so that can be used by library users 2020-04-16 14:31:08 +02:00
davigonz
cf06126ce1 Move account version constant to a better place within AccountUtils 2020-04-16 14:31:08 +02:00
davigonz
0028d63292 Create account version constant 2020-04-16 14:31:08 +02:00
agarcia
c6e88b127c Fix a potential null pointer exception 2020-04-16 14:31:08 +02:00
agarcia
d2ee1294f2 Rename services 2020-04-16 14:31:08 +02:00
agarcia
7e6b63db1f A little cleanup and improve some log messages 2020-04-16 14:31:08 +02:00
agarcia
1536a455a6 Move constants and utils to proper files 2020-04-16 14:31:08 +02:00
agarcia
4f07187fa2 Rename remote operations 2020-04-16 14:31:08 +02:00
Abel García de Prada
3829a1ca32 Start working on login usecase 2020-04-16 14:31:08 +02:00
abelgardep
ec5c9fc4aa Remove ugly dependency from GetRemoteStatusOperation
Create AnonymousService for operations that not require authentication
2020-04-16 14:31:08 +02:00
abelgardep
ad533c8307 Migrate GetRemoteStatusOperation to Kotlin 2020-04-16 14:31:08 +02:00
abelgardep
921983c16e Migrate ExistenceCheckRemoteOperation to Kotlin 2020-04-16 14:31:08 +02:00
abelgardep
99ced8bf41 Refactor GetRemoteUserInfoOperation
Start using Moshi to parse json responses.
Create RemoteUserInfo and UserInfoResponse.
Create UserService.
Migrate GetRemoteUserInfoOperation to kotlin.
2020-04-16 14:31:08 +02:00
Abel García de Prada
c5e64bd7ac
Merge pull request #312 from owncloud/fix/parseFileItemSourceAsString
Parse file_source and item_source as string
2020-04-16 09:28:10 +02:00
Abel García de Prada
96ea90e349
Merge pull request #305 from owncloud/verify-gradle
verify Gradle
2020-04-15 13:34:31 +02:00
agarcia
18f4775db6 Perform gradle validation only on pr 2020-04-15 11:20:42 +02:00
agarcia
9ec6e74d6e Parse file_source and item_source as string 2020-04-15 10:50:53 +02:00
Hannes Achleitner
ffcf603b8b verify Gradle 2020-04-08 10:39:22 +02:00
Abel García de Prada
9331f7e8b3
Merge pull request #310 from owncloud/AndroidStudio-3.6.1
Android Studio 3.6.2
2020-04-07 08:13:52 +02:00
agarcia
48f720011d Use last kotlin version 2020-04-06 08:52:32 +02:00
Hannes Achleitner
1945d311d7 Android Studio 3.6.1 2020-03-17 18:08:00 +01:00
Jesús Recio Rincón
1d767f1e13
Merge pull request #296 from owncloud/UpdateCopyRightYear
Update Copyright year to 2020 (library)
2020-03-17 17:51:17 +01:00
Hannes Achleitner
6803a347bf Update Copyright year to 2020 2020-03-17 15:50:50 +01:00
Abel García de Prada
e6e3af2082
Merge pull request #311 from owncloud/fix/support_for_special_username
Support for usernames with character +
2020-03-12 11:10:58 +01:00
agarcia
8d5524da75 Support for usernames with character + 2020-03-10 14:19:40 +01:00
David González Verdugo
f7a54a8218
Merge pull request #306 from owncloud/fix/sample_client
Fix sample client
2020-02-18 16:48:22 +01:00
davigonz
e343a720f7 Fix sample client 2020-02-18 12:18:02 +01:00
David González Verdugo
8f9bed2d9f
Merge pull request #300 from owncloud/new_arch/oauth_app_auth
Implement OAuth2 with AppAuth
2020-02-12 18:27:52 +01:00
davigonz
0f1f232c16 Fix crash when client is revoked from web UI 2020-02-12 10:51:49 +01:00
davigonz
4a9eb24d69 Include hostname verifier 2020-02-11 16:46:15 +01:00
David González Verdugo
b77cecedab
Merge pull request #294 from owncloud/preventCrash
prevent a crash
2020-02-11 08:39:56 +01:00
davigonz
1b4ce388b3 Apply changes requested in code review 2020-02-06 15:03:50 +01:00
davigonz
4153ee4e35 Remove no longer used OAuth classes 2020-02-05 17:16:06 +01:00
davigonz
261be8bf85 Create OAuth scope param to save it in AccountManager during OAuth process 2020-02-05 16:32:50 +01:00
davigonz
b7033e53bf Use custom connection builder to work with http requests along with AppAuth library 2020-02-05 10:16:33 +01:00
David González Verdugo
fb8dc389a4
Merge pull request #301 from owncloud/fix/oauth_multiaccount
Fix multiaccount with OAuth does not work + Owncloud Client factories cleanup
2020-02-05 09:48:26 +01:00
davigonz
b04a314478 Remove unnecessary method 2020-02-05 08:49:24 +01:00
davigonz
c7f9c9d201 Clean up owncloud client factories 2020-02-04 17:49:35 +01:00
davigonz
5b3c21ba82 Change policy name in ownCloudClientManagerFactory 2020-02-04 15:33:00 +01:00
Hannes Achleitner
e2be78c8f8 prevent a crash 2020-01-30 22:33:43 +01:00
David González Verdugo
015011b6e0
Merge pull request #297 from owncloud/BuildSampleApp
Build sample app successful
2020-01-30 14:40:34 +01:00
davigonz
ffbd4e9128 Use latest gradle version 2020-01-28 17:33:16 +01:00
Abel García de Prada
11a2ec1d3e Replace stacktrace with timber log 2020-01-21 13:11:54 +01:00
Hannes Achleitner
9beb25d019 fix lint issues 2020-01-21 13:10:01 +01:00
Hannes Achleitner
a47d6fd882 switch to Timber 2020-01-21 13:10:01 +01:00
Hannes Achleitner
4e03070641 delete old maven relict 2020-01-21 13:10:01 +01:00
Hannes Achleitner
b72353f025 Android Studio 3.5.3 2020-01-21 13:10:01 +01:00
Hannes Achleitner
2aec82b5e2 cleanup .gitignore 2020-01-21 13:10:01 +01:00
Abel García de Prada
6df51cc323
Merge pull request #286 from owncloud/remove_older_10_support
End of support for <10 servers
2020-01-20 13:28:40 +01:00
davigonz
4cd317d929 Fix build after rebasing with master 2020-01-17 11:13:21 +01:00
Abel García de Prada
03e30ae698 Fix log with old server version 2020-01-16 15:13:41 +01:00
Abel García de Prada
52463707c7 Remove unused constants 2020-01-16 15:13:41 +01:00
davigonz
20e4317bd9 Include new isServerVersionSupported parameter to log out <10 accounts 2020-01-16 15:13:41 +01:00
davigonz
8ba4fa5960 Handle specific bad request error 2020-01-16 15:13:41 +01:00
David González
495e3321e2 Fix folder creation 2020-01-16 15:11:43 +01:00
davigonz
234add959a Apply changes requested in PR 2020-01-16 15:11:11 +01:00
davigonz
bcc5a06335 Get rid of conditions for <10 servers 2020-01-16 15:09:11 +01:00
David González Verdugo
285306e1bc
Merge pull request #293 from owncloud/replace_logOC_with_timber
Replace Log_OC with timber
2020-01-15 16:18:05 +01:00
Abel García de Prada
073a91c580 Update logcat library 2020-01-15 12:20:46 +01:00
Abel García de Prada
c0a11c5d0b Remove Log_OC file 2020-01-15 12:20:46 +01:00
Abel García de Prada
c5ac449fed Replace log_oc with timber
Finish replacing logOC with timber
2020-01-15 12:20:46 +01:00
Abel García de Prada
2778762217 Remove logging initialization from Log_OC 2020-01-15 12:18:00 +01:00
David González Verdugo
a63dd63b39
Merge pull request #295 from owncloud/fixTypo
fix a typo and some lint warnings
2020-01-14 16:33:29 +01:00
David González Verdugo
d76ecc3bc6
Merge pull request #291 from owncloud/FixCompleteBuild
Finish remove Android 4.4 support
2020-01-13 10:25:28 +01:00
Hannes Achleitner
3204d5e60e fix a typo and some lint warnings 2020-01-02 12:31:20 +01:00
Hannes Achleitner
a1d4c781ae Finish remove Android 4.4 support 2019-12-19 13:03:24 +01:00
David González Verdugo
fadc578f07
Merge pull request #290 from owncloud/release_1.0.4.1
Release 1.0.4.1
2019-12-19 12:04:59 +01:00
davigonz
9a806469c5 Rename 10 version constant 2019-12-19 10:53:51 +01:00
davigonz
169836683e Update versionName and versionCode 2019-12-19 10:53:51 +01:00
davigonz
094e698e95 Include field to know servers lower than 10 2019-12-19 10:53:51 +01:00
David González Verdugo
66c8b906fa
Merge pull request #284 from owncloud/ReduceLogging
Reduce logging in ChunkFromFileRequestBody
2019-12-18 08:52:51 +01:00
Hannes Achleitner
90210949b5 Reduce logging in ChunkFromFileRequestBody
(cherry picked from commit 53a8ce122c7f0d4ef6d47e76a29b15fc68197135)
2019-12-17 18:58:00 +01:00
David González Verdugo
e5939e8b70
Merge pull request #285 from owncloud/feature/stop_supporting_android_kitkat
Get rid of Android 4.4 support
2019-12-17 17:49:16 +01:00
David González Verdugo
3262ad4c48
Merge pull request #287 from owncloud/release_1.0.4
[Release] 1.0.4
2019-12-17 12:34:58 +01:00
davigonz
fdeb504d87 Update versionName and versionCode to 1.0.4 2019-12-11 12:46:13 +01:00
Abel García de Prada
3d9d943825 Remove kitkat support 2019-12-11 12:37:30 +01:00
David González Verdugo
a708b794c0
Merge pull request #278 from owncloud/new_arch/modularization
[New arch] Modularization
2019-12-11 11:55:25 +01:00
davigonz
1aeacd62b8 Apply changes requested in code review 2019-12-05 08:50:55 +01:00
Abel García de Prada
9710cf991d Update remote capability 2019-12-05 08:50:55 +01:00
davigonz
da08f04fa1 Fix capability type 2019-12-05 08:50:54 +01:00
davigonz
f104d6842e Clean up remote objects (code review) 2019-12-05 08:50:54 +01:00
davigonz
c50e199b76 Fix null error in http interceptors 2019-12-05 08:50:54 +01:00
davigonz
c05a11a7b4 Create some service interfaces as facade for remote operations 2019-12-05 08:50:54 +01:00
davigonz
8fa6cc648b Fix add headers using interceptors 2019-12-05 08:50:54 +01:00
davigonz
27ff4dfd23 Fix upload 2019-12-05 08:50:54 +01:00
davigonz
28d93a6790 Update RemoteCapability with new search min characters field 2019-12-05 08:50:54 +01:00
davigonz
f32a3af572 Uncomplished commit 2019-12-05 08:50:54 +01:00
davigonz
9ea10e2f96 Remove dependency between the library and the domain layer 2019-12-05 08:50:54 +01:00
davigonz
2e460d9cf7 Include mapper for remote capabilities 2019-12-05 08:50:54 +01:00
davigonz
9230937a44 Keep decoupling shares and capabilities, start to use mappers 2019-12-05 08:50:54 +01:00
davigonz
d73ee43e3d Handle remote operations, both sync and non-sync 2019-12-05 08:50:54 +01:00
davigonz
9aff678fa4 Delete GetRemoteSharesOperation 2019-12-05 08:50:54 +01:00
davigonz
cc38dcd9a6 Include a new class to give data or throw remote exceptions to upper layers 2019-12-05 08:50:54 +01:00
davigonz
32ecf729c5 Keep removing more SAML stuff 2019-12-05 08:50:54 +01:00
davigonz
31868dca00 Start to use Mockk instead of Mockito since is better prepared to be used along with Kotlin 2019-12-05 08:50:54 +01:00
davigonz
66490ff2b0 Update gradle version 2019-12-05 08:50:54 +01:00
davigonz
ebf1a08508 Remove unused OwnCloudClient constructor 2019-12-05 08:50:54 +01:00
davigonz
ea34453f0a Delete unneeded extend 2019-12-05 08:50:54 +01:00
davigonz
5981dfab96 Remove OpenForTesting, no longer needed since mockk is used 2019-12-05 08:50:54 +01:00
davigonz
e28ffbac7c Make some classes opened for testing 2019-12-05 08:50:54 +01:00
David González Verdugo
3d7a04a12d
Merge pull request #283 from owncloud/BetterLogging
Better logging (on upstream)
2019-11-27 18:53:55 +01:00
davigonz
5bf99df58a Update Logcat library dependency 2019-11-26 16:47:15 +01:00
Hannes Achleitner
10a7bdbc4d delete all *.log in directory 2019-11-22 23:35:26 +01:00
Hannes Achleitner
fa4db38a41 fix progress dialog and 'No adapter attached' 2019-11-20 07:51:07 +01:00
Hannes Achleitner
b084ca7c03 introduce deprecated old and new methods 2019-11-15 08:16:14 +01:00
Hannes Achleitner
d32f35147f remove some pointless warnings 2019-11-15 07:51:01 +01:00
Hannes Achleitner
035c5fdf65 Better logging 2019-11-15 07:51:01 +01:00
Abel García de Prada
07e00a720d
Merge pull request #235 from hannesa2/cleanupCode
code cleanup
2019-11-12 12:50:18 +01:00
Hannes Achleitner
68063fa9fa apply review suggestion 2019-11-09 10:05:16 +01:00
Hannes Achleitner
fdde542f15 code cleanup 2019-11-09 10:03:02 +01:00
Jesús Recio Rincón
e2f1637c80
Merge pull request #273 from hannesa2/AndroidStudio-3.5.1
Android Studio 3.5.2
2019-11-07 13:43:43 +01:00
Hannes Achleitner
eb177543fc Android Studio 3.5.2 2019-11-06 06:25:21 +01:00
Hannes Achleitner
2913176f81 Android Studio 3.5.1 2019-10-30 23:01:52 +01:00
David González Verdugo
c67fa8b7b1
Merge pull request #270 from owncloud/min_number_of_characters_to_search
Add min number of character to search capability
2019-10-14 09:17:09 +02:00
Abel García de Prada
87d244e473 Add min number of character to search capability 2019-10-11 14:39:24 +02:00
David González Verdugo
fca43e1fb8
Merge pull request #272 from owncloud/revert_compileSdkVersion_28
Revert compileSdkVersion to 28
2019-10-10 14:28:55 +02:00
davigonz
d0eb8293fd Rever compileSdkVersion to 28 2019-10-10 14:13:13 +02:00
David González Verdugo
fc8c54f142
Merge pull request #267 from owncloud/release_1.0.3
[Release] 1.0.3
2019-09-26 12:24:38 +02:00
davigonz
bb45bc9dbb Update version number and name 2019-09-24 17:13:50 +02:00
David González Verdugo
2dcfcc2545
Merge pull request #266 from hannesa2/AndroidStudio-3.5.0
Android Studio 3.5.0
2019-09-24 09:42:09 +02:00
David González Verdugo
2b62387e80
Merge pull request #260 from owncloud/document_provider/copy
[Document Provider] Copy
2019-09-12 10:11:15 +02:00
Hannes Achleitner
b66a82e1de stay on target 28 2019-09-11 22:51:02 +02:00
Hannes Achleitner
159bc0789e Kotlin 1.3.50 2019-09-08 09:25:54 +02:00
Hannes Achleitner
36df3d9287 Android Studio 3.5.0 2019-09-08 09:25:39 +02:00
davigonz
90cef9fcf6 Use remoteId of the just copied file 2019-08-28 11:56:26 +02:00
David González Verdugo
07cdef9afa
Merge pull request #261 from owncloud/test_get_rid_of_gravis
Get rid of Travis
2019-08-28 10:34:59 +02:00
davigonz
8db0b820ff Delete .travis.yml 2019-08-26 15:28:18 +02:00
David González Verdugo
14e99551a9
Merge pull request #258 from owncloud/release_1.0.2
[Release] 1.0.2
2019-08-21 17:24:27 +02:00
davigonz
c65d8fa21f Update versionCode and versionName 2019-08-20 09:38:34 +02:00
David González Verdugo
0f15c38fc2
Merge pull request #256 from owncloud/release/1.0.2_beta.1
[Release] 1.0.2 beta 1
2019-08-08 13:20:49 +02:00
davigonz
3b552b7ea6 Update versionCode and versionName 2019-08-07 12:17:37 +02:00
David González Verdugo
f36aa8d826
Merge pull request #244 from owncloud/new_arch/shares
New arch/shares
2019-08-07 10:56:03 +02:00
davigonz
c7d0f83683 Update gradle version to fix build 2019-08-06 17:41:57 +02:00
davigonz
176de93abc Fix concurrent exception that appears from time to time 2019-08-06 16:44:13 +02:00
davigonz
91c6183090 Fix Permissions not granted in reshares do not show correct error 2019-08-06 13:44:25 +02:00
David González Verdugo
c17c60a0a3
Merge pull request #254 from owncloud/new_arch/private_shares_get_create
[New Arch] Show + search + create private shares
2019-07-05 09:55:31 +02:00
davigonz
b2b32c048b Apply CR changes 2019-07-04 10:07:20 +02:00
davigonz
c8d93400e0 Include ignoreCase for NODE_SHARE_WITH_ADDITIONAL_INFO 2019-07-04 09:47:05 +02:00
davigonz
253e69f415 Fix showAdditionalInfo not taken into account 2019-07-02 09:33:37 +02:00
davigonz
06bc2ddf6f Some lint minor changes 2019-06-28 14:55:36 +02:00
davigonz
80be123cec Make GetRemoteShareesOperation opened for testing 2019-06-26 18:11:02 +02:00
davigonz
667958c82f Convert GetRemoteShareesOperation java file into Kotlin 2019-06-25 19:01:21 +02:00
davigonz
4391f201bd Update gradle 2019-06-19 17:20:34 +02:00
davigonz
ca7a0c8ea8 Remove redundant qualifiers in RemoveRemoteShareOperation 2019-06-19 13:54:34 +02:00
davigonz
95dde86eda Apply CR changes 2019-06-19 13:54:34 +02:00
davigonz
1087f0fd46 Apply requested changes 2019-06-19 13:54:34 +02:00
davigonz
daf49d289b Fix password not updated when sharing via public link 2019-06-19 13:54:34 +02:00
davigonz
1632b237ff Update gradle version 2019-06-19 13:54:34 +02:00
davigonz
59048e8e7a Use new flag to retrieve more information about just updated shares 2019-06-19 13:54:34 +02:00
davigonz
4849be5daa Modify remote operations to create or update shares 2019-06-19 13:54:34 +02:00
davigonz
688a978b1e Rename remoteId parameter to id within RemoteShare 2019-06-19 13:54:34 +02:00
davigonz
8fa7439492 Fix typo on chunking 2019-06-19 13:54:34 +02:00
davigonz
4f57487f70 Apply changes requested in PR 2019-06-19 13:54:34 +02:00
davigonz
6bd64197b4 Convert capabilities related classes to Kotlin 2019-06-19 13:54:34 +02:00
davigonz
64f5f08ded Apply CR changes 2019-06-19 13:54:34 +02:00
davigonz
a28f58f0fe Apply changes requested 2019-06-19 13:54:34 +02:00
davigonz
0614e7a985 Solve conflicts with get public shares branch 2019-06-19 13:54:34 +02:00
davigonz
1114c38ff7 Reorder CreateRemoteShareOperation params 2019-06-19 13:54:34 +02:00
davigonz
cbb15c3626 Order CreateRemoteShareOperation and make it possible to get sharing errors with new arch 2019-06-19 13:54:34 +02:00
davigonz
c2d8e68ecc 2nd code review changes
Apply pending change
2019-06-19 13:54:34 +02:00
davigonz
af6b18e042 Apply code review changes 2019-06-19 13:54:34 +02:00
davigonz
261e7a762d Fix build 2019-06-19 13:54:34 +02:00
davigonz
418f5af783 Fix some dependencies 2019-06-19 13:54:34 +02:00
davigonz
92d57eadbe Fix tiny bug when parsing shares 2019-06-19 13:54:34 +02:00
davigonz
4e78a5f3e8 Use openfortesting for new Kotlin files needed in tests 2019-06-19 13:54:34 +02:00
davigonz
91ffc87014 Convert used classes to Kotlin 2019-06-19 13:54:33 +02:00
davigonz
3c6f476176 Fix conflicts with master 2019-06-19 13:52:00 +02:00
davigonz
0b3c8a7bf8 Make OwnCloudVersion parcelable 2019-06-19 13:52:00 +02:00
davigonz
d7b190d06b Use different type for remoteId 2019-06-19 13:52:00 +02:00
davigonz
54283c0ba9 Rename OCShare to RemoteShare 2019-06-19 13:52:00 +02:00
David González Verdugo
f11cab39bb
Merge pull request #252 from owncloud/release_1.0.1
[Release] 1.0.1
2019-06-13 13:08:21 +02:00
davigonz
1b727ae71d Update versionCode and versionName 2019-06-11 11:01:15 +02:00
David González Verdugo
24111a95d5
Merge pull request #251 from owncloud/release/1.0.1_beta.1
[Release] 1.0.1 beta v1
2019-05-23 14:24:35 +02:00
davigonz
f16ac0de97 Update version code and name in build.gradle 2019-05-23 10:15:59 +02:00
David González Verdugo
4660322eb0
Merge pull request #249 from owncloud/fix/login_fails_§
Fix "Login fails with "§" in password "
2019-05-14 18:14:11 +02:00
davigonz
b5efb1d664 Use UTF-8 when encoding authorization headers 2019-05-14 18:04:41 +02:00
David González Verdugo
a7ad9d4152
Merge pull request #248 from owncloud/fix/content_folder_brackets
Fix/content folder brackets
2019-05-09 14:59:30 +02:00
davigonz
87841a55d0 Update dav4android tag 2019-05-02 12:29:45 +02:00
davigonz
e233fe0587 Use api instead of implementation to export dav4android dependency so the app can use it as well 2019-05-02 10:58:06 +02:00
David González Verdugo
1f220013f1
Merge pull request #243 from owncloud/release_1.0.0_oem
Release 1.0.0 oem
2019-04-08 08:52:49 +02:00
davigonz
510ec1798e Get rid of TLS support for 16 to 18 API versions 2019-03-26 17:43:42 +01:00
davigonz
ec01a21137 Include TLSv1.2 support and make it work on 16 to 19 devices 2019-03-26 17:43:42 +01:00
David González Verdugo
e4d893d150
Merge pull request #233 from hannesa2/betterLogging
add log level to output
2019-03-13 11:00:17 +01:00
Hannes Achleitner
79283cd6ed increase cache size 2019-03-10 11:37:01 +01:00
Hannes Achleitner
446ac7c489 split log into debug and release 2019-03-10 11:37:01 +01:00
Hannes Achleitner
6b61e66318 add log level to output
this is a pre-task to colorize log output and add ability to filter on loglevel
2019-03-10 11:37:01 +01:00
David González Verdugo
4323c3a89b
Merge pull request #242 from owncloud/AndroidStudio-3.3.2
Android Studio 3.3.2
2019-03-08 09:20:10 +01:00
Hannes Achleitner
4b0510d791 Android Studio 3.3.2
see what's changed https://androidstudio.googleblog.com/2019/03/android-studio-332-available.html
2019-03-07 10:07:09 +01:00
David González Verdugo
b22e389f1f
Merge pull request #241 from owncloud/release_1.0.0
Release 1.0
2019-03-07 09:14:37 +01:00
davigonz
04819cc714 Upgrade min sdk version in sample client 2019-03-07 08:43:41 +01:00
davigonz
239e920d56 Update min version to 19 2019-03-04 09:56:44 +01:00
davigonz
87a8b418de Fix some indentation issues 2019-02-26 17:04:20 +01:00
davigonz
59ed7e42ec Include and parse shareWithAdditionalInfo to be used in shares autocompletion and list 2019-02-26 17:04:20 +01:00
davigonz
249e25768b Read enforced_for capability 2019-02-20 18:45:01 +01:00
Hannes Achleitner
78e4d167d2 change 2018 to 2019 in comments 2019-02-13 18:26:18 +01:00
David González Verdugo
ebd08d6a2d
Merge pull request #231 from hannesa2/AndroidX-lib
Android X
2019-02-13 18:17:06 +01:00
Hannes Achleitner
f249d2dc11 Android X
only compileSdk increase was needed
2019-02-13 17:43:44 +01:00
David González Verdugo
42d530eb95
Merge pull request #232 from hannesa2/feature/AndroidStudio-3.3.1
Android Studio 3.3.1
2019-02-13 17:33:20 +01:00
Hannes Achleitner
f8279ab70f Android Studio 3.3.1 2019-02-11 19:39:14 +01:00
David González Verdugo
490fbde496
Merge pull request #203 from hannesa2/ApplySomeLintsFixes
apply some Lint fixes
2019-02-11 07:43:42 +00:00
Hannes Achleitner
2f64bc0b89 apply some Lint fixes 2019-02-05 20:55:38 +01:00
David González Verdugo
82a207cb62
Merge pull request #228 from hannesa2/AndroidStudio-3.3
Android Studio 3.3
2019-02-05 08:26:24 +00:00
Hannes Achleitner
fdfd30d8ba Android Studio 3.3 2019-02-02 23:22:28 +01:00
Michael Stingl
c99e2fb7b3
Merge pull request #224 from hannesa2/Codestyle
Codestyle
2019-02-02 15:55:36 +01:00
Hannes Achleitner
40690df5fa apply codestyle everywhere 2019-01-23 06:19:08 +01:00
Hannes Achleitner
6d05856fb7 apply codestyle 2019-01-23 06:17:37 +01:00
David González Verdugo
5f579fbb24
Merge pull request #225 from hannesa2/compactLogfile
compact logfile
2019-01-22 11:06:05 +00:00
Hannes Achleitner
940f0b9bb0 adapt variable name 2019-01-19 23:35:25 +01:00
Hannes Achleitner
6560aa987d apply codestyle request for complete file 2019-01-19 23:28:22 +01:00
Hannes Achleitner
dffd5bed9f Log delete logfile result 2018-12-28 19:38:17 +01:00
Hannes Achleitner
7954bdbcdd compact logfile
time and text in same line, no empty lines
2018-12-19 18:06:30 +01:00
David González Verdugo
1aae034b70
Merge pull request #226 from owncloud/fix/final_module_names
Rename library module from lib to owncloudComLibrary
2018-12-19 18:01:52 +01:00
davigonz
badc15b741 Rename library module from lib to owncloudComLibrary 2018-12-19 16:58:08 +01:00
David González Verdugo
8a8906154c
Merge pull request #223 from owncloud/fix/rename_library_module
Rename library module from owncloud-android-library to lib
2018-12-17 13:50:36 +01:00
davigonz
8c6a325e06 Rename library module from owncloud-android-library to lib 2018-12-17 13:41:34 +01:00
David González Verdugo
c9337dc251
Merge pull request #180 from hannesa2/update_android_tool4removeEclipse
remove Eclipse structure
2018-12-14 12:37:39 +01:00
Hannes Achleitner
982dbb2a93 revert to android 26
on review request
2018-12-14 11:12:54 +01:00
Hannes Achleitner
0eb071b762 fix packages 2018-12-14 10:16:30 +01:00
Hannes Achleitner
9fb69ce38d apply codereviews 2018-12-13 18:44:57 +01:00
Hannes Achleitner
56e003139f change to Gradle file structure 2018-12-12 20:17:27 +01:00
Hannes Achleitner
137e489008 remove Eclipse only files 2018-12-12 20:16:49 +01:00
David González Verdugo
7dc611cd14
Merge pull request #220 from owncloud/cleanup/old_libraries
Get rid of old libraries dependencies
2018-12-03 12:03:19 +01:00
davigonz
dbeb4b33de Get rid of old libraries dependencies 2018-11-30 15:14:38 +01:00
David González Verdugo
9502498245
Merge pull request #198 from hannesa2/AndroidStudio-3.2.1
Android Studio 3.2.1
2018-11-29 10:16:11 +01:00
Hannes Achleitner
94f3c377e4 apply review comment concerning targetSdkVersion
https://github.com/owncloud/android-library/pull/198#discussion_r228050760
2018-11-27 11:39:36 +01:00
Hannes Achleitner
6eba501c4b Android Studio 3.2.1 2018-11-27 11:39:36 +01:00
David González Verdugo
c85fe7549c
Merge pull request #216 from owncloud/release_0.9.24
Release 0.9.24
2018-11-26 12:37:51 +01:00
davigonz
b523062740 Fix browse files with username containing @ character 2018-11-21 17:10:55 +01:00
David González Verdugo
3b551ea439
Merge pull request #213 from owncloud/release_0.9.23
Release 0.9.23
2018-11-19 12:09:38 +01:00
davigonz
f09c851210 Fix remote path from url with usernames containing spaces 2018-11-13 14:09:49 +01:00
Thomas Müller
e1b09a5ff5
Merge pull request #211 from owncloud/cleanup/old_tests
Get rid of old ant tests
2018-11-09 08:47:35 +01:00
davigonz
d367348217 Get rid of old ant tests 2018-11-08 12:46:14 +01:00
David González Verdugo
5ede3c037b
Merge pull request #210 from owncloud/release_0.9.22
Release 0.9.22
2018-11-08 08:50:03 +01:00
davigonz
f3e8374429 Use LDAP user ids when creating local files 2018-11-07 17:09:42 +01:00
davigonz
2c5ceeb555 Use user id in LDAP requests 2018-11-07 14:31:03 +01:00
David González Verdugo
7a50007ba3
Merge pull request #208 from owncloud/release_0.9.21
Release 0.9.21
2018-11-06 10:44:24 +01:00
davigonz
e857853a58 Fix wrong error message when sharing a file with same user as the active account 2018-10-31 09:30:45 +01:00
David González Verdugo
e0a6c68c66
Merge pull request #207 from sd1998/Fix-2247
Changes for handling HTTP_METHOD_NOT_FOUND responses
2018-10-29 14:37:39 +01:00
sd1998
106b4fd9e5 Code review changes 2018-10-26 18:05:29 +05:30
sd1998
69c7a24ebb Changes for handling HTTP_METHOD_NOT_FOUND responses 2018-10-26 14:40:44 +05:30
David González Verdugo
f6471b66ca
Merge pull request #196 from owncloud/fix/av_offline_jobs
Av. offline with jobs
2018-10-25 14:37:35 +02:00
davigonz
44372f211c Fix av. offline files are neither uploaded nor conflicted 2018-10-25 14:30:54 +02:00
David González Verdugo
4c9b63bded
Merge pull request #206 from owncloud/cleanup/jackrabbit_dependencies
Delete jackrabbit dependencies and include OkHttp/Dav4Android ones
2018-10-25 13:47:25 +02:00
davigonz
a69177bce4 Delete jackrabbit dependencies and include OkHttp/Dav4Android ones 2018-10-25 10:56:23 +02:00
David González Verdugo
b57212890c
Merge pull request #201 from hannesa2/FixWrongUsed-OC_X_REQUEST_ID
fix a bug with wrong used OC_X_REQUEST_ID
2018-10-25 09:01:28 +02:00
Hannes Achleitner
c3cecfc7b9 fix a bug with wrong used OC_X_REQUEST_ID 2018-10-25 06:44:33 +02:00
David González Verdugo
d49814c195
Merge pull request #197 from owncloud/fix/crash_public_share
Fix crash when creating public links
2018-10-24 16:59:33 +02:00
davigonz
7238c5c04b Fix dependency issue in Travis 2018-10-24 16:39:55 +02:00
davigonz
1b72e2bad8 Delete duplicated header set 2018-10-23 10:11:16 +02:00
David González Verdugo
9526038503
Merge pull request #195 from owncloud/feature/request_id
Use UUID v4 to represent request ids and log it
2018-10-22 14:42:43 +02:00
davigonz
2723924b5d Use UUID v4 to represent request ids and log it 2018-10-10 09:47:17 +02:00
David González Verdugo
2fdf724eab
Merge pull request #192 from owncloud/replace_network_library
Replace network library
2018-10-09 15:59:41 +02:00
davigonz
fabf8d55f0 Fix some downloads by disabling encoding 2018-10-08 15:04:55 +02:00
davigonz
14ec6cb1ee Fix bug when restoring SAML cookies after expiring a SAML session 2018-10-08 10:57:56 +02:00
davigonz
8841a0fcb7 Include setup.xml for sample client 2018-10-02 15:29:51 +02:00
davigonz
33fd1037a3 Update sample client to use new library 2018-10-02 10:53:52 +02:00
davigonz
096d037f94 Clean up some dependencies 2018-10-01 13:21:55 +02:00
davigonz
c36a71caf2 Avoid duplicated cookies 2018-10-01 13:07:33 +02:00
davigonz
d195b2ff89 Include fix to switch credentials properly 2018-10-01 11:54:19 +02:00
davigonz
5d3bba65e2 Fix SAML with new cookies handling 2018-10-01 10:16:12 +02:00
davigonz
549cc32703 Make cookies handling more efficient 2018-09-28 13:42:01 +02:00
davigonz
f2ccc62b88 Reimplement cookies handling 2018-09-28 12:30:14 +02:00
davigonz
ae7be42ec3 Remove dav4android subproject 2018-09-25 15:52:16 +02:00
davigonz
fef62aaf74 Include dav4android via jitpack 2018-09-25 15:37:03 +02:00
davigonz
817e3c894b Crash when restoring cookies 2018-09-12 09:40:36 +02:00
davigonz
81f1804917 Fix remote file creation using username instead of display name 2018-09-05 13:44:43 +02:00
davigonz
cc612f8712 Use header constants instead of plain text 2018-09-04 17:24:05 +02:00
davigonz
800c075bd1 Fix renewal of OAuth2 token 2018-09-04 16:44:58 +02:00
davigonz
eaa645ab3c Fix upload colissions 2018-09-04 15:59:25 +02:00
davigonz
8a04392bfc Fix follow redirections 2018-09-04 15:59:25 +02:00
davigonz
f3eb0c4431 Fix credentials in switch accounts 2018-09-04 15:59:25 +02:00
davigonz
782361267d Fix file downloaded each time is tapped 2018-09-04 15:59:25 +02:00
davigonz
d30a5578f3 Fix antivirus message 2018-09-04 15:59:25 +02:00
davigonz
eb7cac064f Prepare wrapper to handle response bodies after exceptions 2018-09-04 15:59:25 +02:00
davigonz
e3db308825 Fix some problems in authentication 2018-09-04 15:59:25 +02:00
davigonz
50fda001ce Send unique ID header for all requests 2018-09-04 15:59:25 +02:00
davigonz
7627f75aa9 Get mEtag again 2018-09-04 15:59:25 +02:00
davigonz
b0fa6ae1d0 Apply requested changes 2018-09-04 15:59:25 +02:00
davigonz
9944f30d3f Remove the ignored sample client setup.xml 2018-09-04 15:58:58 +02:00
davigonz
d944c500dd Remove some unneeded dependencies 2018-09-04 15:58:58 +02:00
theScrabi
fd6628e38f fix type error 2018-09-04 15:58:58 +02:00
theScrabi
c5a1df417f fixed barear authentication 2018-09-04 15:58:58 +02:00
davigonz
096d3b9165 Fix problem with certificate exception catching 2018-09-04 15:58:58 +02:00
davigonz
7d0c79876c Implement cancel calls for webdav methods 2018-09-04 15:58:58 +02:00
theScrabi
c34c8ead1a rebse changes from bitfire 2018-09-04 15:58:58 +02:00
davigonz
e0e6d3da49 Use callback to get okhttp response 2018-09-04 15:58:58 +02:00
theScrabi
4968ca6e62 make the new merged changes from bitfire compile 2018-09-04 15:58:58 +02:00
theScrabi
7bc9a885b0 use compiletime polymorphism over runtime polymorphism 2018-09-04 15:58:58 +02:00
theScrabi
06ec99aead replace httpUrl with URL outside the wrapper 2018-09-04 15:58:11 +02:00
theScrabi
c33c7c551d make redirection actually work ... finaly 2018-09-04 15:50:24 +02:00
theScrabi
bd5dc20842 make automatic login with session timeout on saml work 2018-09-04 15:50:24 +02:00
davigonz
f1c6726d30 Delete remote chunks folder when canceling upload 2018-09-04 15:50:24 +02:00
davigonz
78613ed4bc Cancel chunk upload and implement move files after uploading 2018-09-04 15:50:24 +02:00
davigonz
c8a0451e06 Implement move method and finish basic chunked uploads 2018-09-04 15:50:24 +02:00
davigonz
1d80067f85 Refactor interceptors and include move headers 2018-09-04 15:50:24 +02:00
davigonz
ed073d6db0 Add timeout to last chunk 2018-09-04 15:50:24 +02:00
davigonz
762ae7eb62 Move file after upload with chunks 2018-09-04 15:50:24 +02:00
theScrabi
e6bdfab11a make redirect more or less work 2018-09-04 15:50:24 +02:00
davigonz
0b9a79491f Upload chunks 2018-09-04 15:50:24 +02:00
theScrabi
b99723205b remove jackrabit 2018-09-04 15:50:24 +02:00
theScrabi
0d0b711556 remove apache httpclient imports 2018-09-04 15:50:24 +02:00
theScrabi
6e4ded84d9 make OwnCloudClient extend the warpper HttpClient 2018-09-04 15:50:24 +02:00
theScrabi
75905b5f74 add disable redict handling by davresource 2018-09-04 15:50:24 +02:00
davigonz
153c0a10ff Basic upload with chunks [WIP] 2018-09-04 15:50:24 +02:00
theScrabi
366459699e fix missing semicolon 2018-09-04 15:50:24 +02:00
theScrabi
266dc37da2 add stetho 2018-09-04 15:50:24 +02:00
davigonz
297e8d1848 Chunked uploads, create chunks folder 2018-09-04 15:50:24 +02:00
davigonz
2d54ece72e Chunked uploads, create chunks folder [WIP] 2018-09-04 15:50:24 +02:00
davigonz
f218a60611 Include more methods to custom dav connections + chunked uploads [WIP] 2018-09-04 15:50:24 +02:00
davigonz
d013d93ac9 Retry uploads 2018-09-04 15:50:24 +02:00
theScrabi
c2bdea1c91 make https connection work with new library 2018-09-04 15:50:24 +02:00
davigonz
45e4b98510 Abort uploads with no chunking working 2018-09-04 15:50:24 +02:00
theScrabi
804b31da39 make saml work with new library 2018-09-04 15:50:24 +02:00
davigonz
e261b1df2f Abort upload [WIP] 2018-09-04 15:50:24 +02:00
theScrabi
f110992489 make oauth work 2018-09-04 15:50:24 +02:00
theScrabi
8540eed348 add oauth operations 2018-09-04 15:50:24 +02:00
davigonz
b1f2c0cbef Implement upload progress 2018-09-04 15:50:24 +02:00
theScrabi
9caa79becc remove ApacheHttp imports from downloadoperation 2018-09-04 15:50:24 +02:00
theScrabi
60c1be2c0c add DownloadRemoteFileOperation 2018-09-04 15:50:24 +02:00
davigonz
82fce2944b Fix read remote file operation 2018-09-04 15:50:24 +02:00
davigonz
ff17ab6837 Working on having the upload progress 2018-09-04 15:50:24 +02:00
theScrabi
2041fb1962 add untestet protoype of new ReadRemoteFileOperation 2018-09-04 15:50:24 +02:00
theScrabi
e78b96348b fix crash when calling getOkHttpInterceptor 2018-09-04 15:50:24 +02:00
theScrabi
019383378d add crete remote folder operation 2018-09-04 15:50:24 +02:00
theScrabi
cb08fe32a4 set timeout in move/localmove operation 2018-09-04 15:50:24 +02:00
davigonz
6a375dcb93 Include timeouts and short refactoring 2018-09-04 15:50:24 +02:00
theScrabi
73b4ffe0b9 remove furhter httpclinet constraints from move/copy operation 2018-09-04 15:50:24 +02:00
theScrabi
af5228a425 fix created snack bar showing up 2018-09-04 15:50:24 +02:00
davigonz
0387ceb1d4 Implement remove file operation 2018-09-04 15:50:24 +02:00
theScrabi
b183e3f08a add support for copy methode 2018-09-04 15:50:24 +02:00
davigonz
e4e8a5a5e3 Implement basic upload using the new wrapper 2018-09-04 15:50:23 +02:00
davigonz
524dc587db Refactor wrapper constructors and start to implement uploadoperations in library 2018-09-04 15:47:29 +02:00
davigonz
c676f694d6 Upload [WIP] 2018-09-04 15:42:01 +02:00
davigonz
a0478826b4 Update GetRemoteUserQuotaOperation to use the recent wrapper with propfind 2018-09-04 15:42:01 +02:00
davigonz
1631b9b55a Get rid of OkHttp dependencies in OwnCloudClient 2018-09-04 15:42:01 +02:00
davigonz
f5795d1c03 Keep refactoring wrapper 2018-09-04 15:38:04 +02:00
davigonz
7fe2c02fc1 Include methot to make a result successful 2018-09-04 15:38:04 +02:00
davigonz
bcc8a78bcf Move OkHttp and dav4android dependencies to the new wrapper 2018-09-04 15:38:04 +02:00
davigonz
08777c0265 Get rid of refactor classes, use methods wrapper 2018-09-04 13:57:25 +02:00
davigonz
226e332460 Implement update share using the new wrapper methods in library 2018-09-04 13:56:32 +02:00
davigonz
6d1e2d0434 Implement remove share using the new wrapper methods 2018-09-04 13:52:43 +02:00
davigonz
7d534c90ab Implement get shares operations using the new wrapper methods 2018-09-04 13:48:46 +02:00
davigonz
1a7e6a475d Use the new wrapper methods with CreateRemoteShareOperation and GetRemoteShareOperation 2018-09-04 13:41:54 +02:00
davigonz
3b7950ae59 Fix problem when showing size 2018-09-04 13:38:31 +02:00
davigonz
944a1186d9 Use new wrapper in GetRemoteUserAvatar operation 2018-09-04 13:38:31 +02:00
davigonz
82b7bef113 Implement GetRemoteCapabilities using new wrapper 2018-09-04 13:38:31 +02:00
davigonz
a730980c34 Implement GetRemoteStatusOperation using new wrapper 2018-09-04 13:38:31 +02:00
davigonz
01d4592de0 Refactor httm methods to return response instead of response code 2018-09-04 13:38:31 +02:00
davigonz
25bba85ee1 Implement get quota with new architecture and refactoring 2018-09-04 13:38:31 +02:00
davigonz
bd82537045 Fix read remote folder 2018-09-04 13:38:31 +02:00
theScrabi
ac869690fc change dav4droid repository to the ownclouders one 2018-09-04 13:38:31 +02:00
davigonz
e7c5391ac5 Fix new webdav uri build 2018-09-04 13:38:31 +02:00
davigonz
dc9a37db28 Update GetMethod to be used in GetRemoteUserInfoOperation 2018-09-04 13:38:31 +02:00
davigonz
1cf44a9fff Code refactoring 2018-09-04 13:38:30 +02:00
davigonz
dfab453e6b Working on authentication operations 2018-09-04 13:38:30 +02:00
davigonz
4f0cd82a7d Clear basic credentials before applying new ones 2018-09-04 13:38:30 +02:00
davigonz
81aa417cbf Custom interceptors to include user agent and authorization 2018-09-04 13:38:30 +02:00
davigonz
d67a41d5cc Include credentials [WIP] 2018-09-04 13:38:30 +02:00
davigonz
11938a1fcc Create http + webdav methods wrapeer 2018-09-04 13:38:30 +02:00
davigonz
b9ba124541 Keep previous owncloudclient implementation 2018-09-04 13:38:30 +02:00
davigonz
275a0f0f10 Update ownCloucClient to use OkHttpClient [WIP] 2018-09-04 13:38:30 +02:00
davigonz
2b333b8ff0 Update dav4droid dependency 2018-09-04 13:38:30 +02:00
davigonz
81cea2788d Upload file operation [WIP] 2018-09-04 13:38:30 +02:00
theScrabi
81d3d832e9 restructure path to operation resources 2018-09-04 13:38:30 +02:00
theScrabi
ce86ebac8a make propfind compatible with frontend 2018-09-04 13:38:30 +02:00
davigonz
74c9430382 Create RemoveRemoteFileOperation and use it 2018-09-04 13:38:30 +02:00
davigonz
81120ac7ad Create DownloadRemoteFileOperation and reorder classes 2018-09-04 13:38:30 +02:00
davigonz
0f14e89d7c Check upload file result 2018-09-04 13:38:30 +02:00
davigonz
5d0362dc4d Use DavOCResource again 2018-09-04 13:38:30 +02:00
DerSchabi
dae28aee48 refactor RemoteOperationResult 2018-09-04 13:38:30 +02:00
davigonz
63c917c979 Include upload headers in interceptor and finish upload file operation 2018-09-04 13:38:30 +02:00
davigonz
75ce8e186f Implement UploadRemoteFileOperation with dav4droid 2018-09-04 13:38:30 +02:00
davigonz
2ef51dd5f6 Move webdav path constant and refactor some Remote operation methods 2018-09-04 13:38:30 +02:00
davigonz
2ba891df15 Include user agent in OCContext and start implementing the generic put operation 2018-09-04 13:38:30 +02:00
davigonz
77c7c5195b Create DAVOCResource and http constants file in dav4android 2018-09-04 13:38:30 +02:00
davigonz
68fae46240 Register new WebDAV properties in dav4android 2018-09-04 13:38:30 +02:00
davigonz
7cb9189fce Keep completing the propfind 2018-09-04 13:38:30 +02:00
davigonz
a4678557d8 Remove unneeded slahes in url 2018-09-04 13:38:30 +02:00
DerSchabi
ca2eff6647 make propfind operation run without errors 2018-09-04 13:38:30 +02:00
DerSchabi
d593474113 make dav4android as submodule 2018-09-04 13:38:30 +02:00
davigonz
ff6adc4cf9 Solve conflicts 2018-09-04 13:38:30 +02:00
davigonz
3125c8047c First propfind using dav4droid and new architecture 2018-09-04 13:38:30 +02:00
DerSchabi
1249e205d6 add OCAccount
add OCAccount
2018-09-04 13:38:30 +02:00
DerSchabi
e354a716cb ren owncloud to OC 2018-09-04 13:38:30 +02:00
DerSchabi
cd3d20db07 add dav4droid support part1 2018-09-04 13:38:30 +02:00
David González Verdugo
9ab1b40682
Merge pull request #194 from owncloud/show_reshares
Show reshares
2018-08-09 10:56:40 +02:00
davigonz
d4908e4172 Switch to v2.php 2018-08-01 12:53:56 +02:00
davigonz
7bed924ff8 Refactor uri builds in shares 2018-08-01 11:10:16 +02:00
David González Verdugo
8e357d7811
Merge pull request #191 from karakayasemi/master
check for PROPERTY_VERSIONING is exist when learning capabilities
2018-06-22 10:37:28 +02:00
Semih Serhat Karakaya
813900d600 check for PROPERTY_VERSIONING is exist when learning capabilities 2018-05-23 10:30:18 +03:00
David González Verdugo
38c84ed377
Merge pull request #189 from owncloud/user_quota
User quota
2018-05-18 09:44:44 +02:00
davigonz
fdbe23923e Fix Incorrect output with Other option 2018-05-18 09:28:14 +02:00
David González
f3566d667e Handle case with quota 0 2018-05-18 09:28:13 +02:00
davigonz
a21614fd5a Handle pending, unknown and unlimited quota 2018-05-18 09:28:13 +02:00
davigonz
ec08bfbd7a Fix get quota test 2018-05-18 09:28:13 +02:00
davigonz
12429b7ab9 Update operation to get remote user quota 2018-05-18 09:28:13 +02:00
David González Verdugo
ad0adaaf5c
Merge pull request #188 from owncloud/upgrade_gradle
Upgrade gradle to 3.1.2
2018-05-18 09:27:06 +02:00
davigonz
2888b2d55e Update minSdkVersion 2018-04-30 12:55:10 +02:00
davigonz
bf225b275f Replace compile with api 2018-04-30 12:50:39 +02:00
davigonz
2ccd681d2f Fix merge dex error and delete redundant dependencies 2018-04-30 10:16:37 +02:00
davigonz
9a2fb4cd0a Fix Could not find com.android.tools.lint:lint-gradle:26.1.2. 2018-04-26 10:37:08 +02:00
davigonz
35ea9dfd20 Fix okHttp not found 2018-04-25 17:48:17 +02:00
davigonz
91f509a119 Fix failed Travis test 2018-04-25 17:30:53 +02:00
davigonz
b1ef9ec44b Solve google repository issue 2018-04-25 17:18:36 +02:00
davigonz
1ff922af6a Get rid of some warnings 2018-04-25 16:38:51 +02:00
davigonz
3bd29307a5 Upgrade gradle and fix some conflicts 2018-04-25 11:23:06 +02:00
David González Verdugo
41fed5d9f0
Merge pull request #187 from owncloud/test_ok_http
Test OkHttp and new endpoint before network library replacement
2018-04-20 12:55:34 +02:00
davigonz
e6835b1518 Reorder variables 2018-04-20 12:40:52 +02:00
davigonz
d0d26b7a3b Fix uploads 2018-04-20 12:35:06 +02:00
davigonz
872c82b79a Test remote deletion 2018-04-19 13:57:49 +02:00
davigonz
bc32ddda0f Test download 2018-04-19 13:22:27 +02:00
davigonz
f3a080e9a8 Keep working on uploads 2018-04-18 13:32:38 +02:00
davigonz
bdd6a1be0c Refactor MainActivity and start implementing upload 2018-04-18 11:03:28 +02:00
davigonz
d79bdb7893 Test PROPFIND with new endpoind and new network library 2018-04-17 18:37:00 +02:00
davigonz
ede34920c2 Include feature to check server connections 2018-04-17 16:48:49 +02:00
davigonz
e6640d395b Testing network library 2018-04-17 16:48:49 +02:00
Christian Schabesberger
a2a1b0204a
Merge pull request #185 from theScrabi/fix_empty_screen
fix empty screen for guest users
2018-04-13 12:54:10 +02:00
theScrabi
0abc3a6b29 fix empty screen 2018-04-13 08:59:58 +02:00
David González Verdugo
0e7fd8ee8f
Merge pull request #175 from owncloud/private_link_in_webdav
Add privatelink property support to processing of WebDAV responses
2017-11-10 15:17:56 +01:00
davigonz
7c7cad7e99 Apply requested changes 2017-10-30 10:53:33 +01:00
David A. Velasco
9fe3e11c52 Add privatelink property support to webdav reponses 2017-10-30 10:53:33 +01:00
David González Verdugo
c18329efd6
Merge pull request #179 from owncloud/migrate_android_o
Migrate to Android O
2017-10-30 10:44:53 +01:00
davigonz
a61d287bf1 Update emulator version 2017-10-18 17:30:11 +02:00
davigonz
848d9db763 Upgrade target sdk version to 26, including it also in Travis configuration 2017-10-18 13:09:53 +02:00
davigonz
1b34e9bd49 Upgrade compileSdkToos to 26 2017-10-18 12:39:10 +02:00
David González Verdugo
98eda17cba Merge pull request #167 from owncloud/update_android_tools
[WIP] Update Android tools
2017-10-18 10:16:18 +02:00
davigonz
826abcfae4 Check tools and dependencies installed 2017-10-18 09:27:42 +02:00
davigonz
132e173078 Use sdkmanager command to install Android SDK components 2017-10-18 08:48:04 +02:00
David A. Velasco
e0a6926608 pdate Android SDK Tools to the really last version 2017-10-10 18:11:00 +02:00
David A. Velasco
2109ab98a1 Update build tools to 26.0.2 2017-10-10 18:11:00 +02:00
David A. Velasco
2dde542356 Disable automated tests until ported to current Android testing environment 2017-10-10 18:11:00 +02:00
David A. Velasco
19cea29faf Delete duplicated update of Android Tools component - no needed anymore, Travis updated Android base environment 2017-10-10 18:11:00 +02:00
David A. Velasco
2418abf85e Update Travis config to install Android build tools 26.0.0 2017-10-10 18:11:00 +02:00
David A. Velasco
40af731eb0 Update build tools to 26.0.0, for future support of Android O 2017-10-10 18:11:00 +02:00
David A. Velasco
c560f4fb4b Merge pull request #174 from owncloud/oauth2_support_bugfixing
Oauth2 support - bugfixing
2017-09-01 15:20:57 +02:00
davigonz
f389207713 Update tests with the proper constants 2017-09-01 11:31:13 +02:00
David A. Velasco
f3a2c05efa Prevent NPE parsing NULL queries in OAuth2 redirected URIs 2017-09-01 11:30:04 +02:00
David A. Velasco
2d35b00273 Move constants for main endpoints from AccountUtils to OwnCloudClient 2017-09-01 11:29:45 +02:00
davigonz
3072507972 Fix login loop when disabling OAuth2 2017-08-28 08:57:08 +02:00
David A. Velasco
2289358775 Merge pull request #173 from owncloud/oauth2_support
OAuth2 support
2017-08-23 16:56:13 +02:00
davigonz
75821de7a3 Changes to invalidate SAML credentials properly 2017-08-23 13:39:40 +02:00
davigonz
12d04bb63c Ensure that SAML credentials will be invalidated if appropriate 2017-08-17 10:45:01 +02:00
David A. Velasco
e466bac6b1 Move responsibility for refreshing expired credentials from RemoteOperation to OwnCloudClient 2017-08-17 09:22:30 +02:00
David A. Velasco
dd2d3b8996 Extend chance of silent refresh of auth token in RemoteOperations that are run with execute(...) methods receiving OwnCloudClients 2017-08-14 14:46:08 +02:00
David A. Velasco
c7ade613c6 Clean-up and minor refactor after review 2017-08-04 14:48:39 +02:00
David A. Velasco
3ea5ad32f6 Update imports in automated tests after moving OwnCloudCredentialsFactory to a different package 2017-08-04 13:44:01 +02:00
David A. Velasco
ae4b463478 Update Sample Client and Test Project after moving OwnCloudCredentialsFactory to a different pacakge 2017-08-04 12:04:52 +02:00
David A. Velasco
02f35d5f5e Remove deprecated methods for update to version 1.0 2017-08-04 11:11:37 +02:00
David A. Velasco
a4386bb4fe Allow client objects to decide if RemoteOperations should silently refresh access token when expired 2017-08-02 18:43:07 +02:00
davigonz
c04f6e3463 Create new method to retry synchronous and asynchronous remote operations 2017-08-02 12:25:38 +02:00
davigonz
7f98b3804c Include refresh token grantype before throwing an exception when building oauth2 operation 2017-08-01 17:09:04 +02:00
davigonz
99334c2e45 Include refresh token operation in library, builder 2017-08-01 11:55:47 +02:00
davigonz
aa717b3e7b Use proper grant type to get new access token using refresh token 2017-07-31 10:47:20 +02:00
David A. Velasco
ae8e3ca904 Simplify operation to refresh OAuth2 access token 2017-07-25 19:04:59 +02:00
davigonz
95fdf75d38 Rename get refreshed access token operation 2017-07-25 12:17:32 +02:00
davigonz
c6f8430876 Move OAuth2GetRefreshedAccessTokenOperation to the library and prepare RemoteOperation to retry the last failed operation when access token expires 2017-07-25 12:14:22 +02:00
David A. Velasco
a06af810d0 Invalidate stored auth token directly from RemoteOperation when request results UNAUTHORIZED 2017-07-25 09:35:22 +02:00
David A. Velasco
0dc859c071 Move OAuth2 support classes from app to library 2017-07-21 13:30:29 +02:00
davigonz
a1b1c2f9ed Invalidate the client token when access token expires and try the last operation [WIP] 2017-07-20 11:10:13 +02:00
davigonz
fe947194c5 Add constant to save refresh token in account 2017-07-20 11:10:13 +02:00
davigonz
2df2cde466 Rename getAuthernticateHeader method 2017-07-20 11:10:13 +02:00
davigonz
f6ee1a15cb Reading several authenticate headers from http response 2017-07-20 11:10:13 +02:00
David A. Velasco
e4b57e8063 WIP 2017-07-20 11:10:13 +02:00
David A. Velasco
312b21cb1e Merge pull request #172 from owncloud/update_gradle_plugin
Update Gradle Plugin to last stable version - 2.3.3
2017-07-20 11:03:40 +02:00
David A. Velasco
c75efa81ba Update Gradle Plugin to last stable version - 2.3.3 2017-07-20 10:05:27 +02:00
David González Verdugo
0a4c3773b2 Merge pull request #166 from owncloud/antivirus_improve_feedback
Improve feedback when uploading virus files
2017-07-11 10:35:28 +02:00
davigonz
b074c34cbc Refactor code 2017-07-11 09:29:33 +02:00
davigonz
4b2c32511b Improve feedback when uploading virus files 2017-07-11 09:29:33 +02:00
David González Verdugo
cfd43dc058 Merge pull request #171 from owncloud/Fix_get_upload_only_capability
Include support_upload_only capability in get capabilities operation
2017-06-28 11:55:09 +02:00
davigonz
5d99c9db32 Include support_upload_only capability in get capabilities operation 2017-06-28 09:56:48 +02:00
David González Verdugo
6842cd6968 Merge pull request #170 from owncloud/fix_write_only_10.0.0
Fix write only 10.0.0
2017-06-28 09:28:03 +02:00
davigonz
7b1a5cdee9 Include a new minimun version with write only public sharing 2017-06-26 09:16:09 +02:00
David González Verdugo
33390ff09c Merge pull request #168 from owncloud/write_only_share
Write only share
2017-06-21 09:29:14 +02:00
davigonz
137a892d2e Improve comments 2017-06-16 11:43:18 +02:00
davigonz
bcb6c2c106 Update permissions when updating share via link 2017-06-16 11:07:06 +02:00
davigonz
e7b2dde940 Adding support upload only field to OCCapability 2017-06-14 11:15:16 +02:00
davigonz
5493227dd6 Adding supports_upload_only capability [WIP] 2017-06-09 11:51:03 +02:00
David González Verdugo
bac38d13ef Merge pull request #163 from owncloud/multiple_public_shares
Support in library for multiple public shares per file
2017-05-15 10:42:40 +02:00
David A. Velasco
defbfc8d0e Revert "Add support for capability to show optional warning about public shares"
This reverts commit 6d0773cf34122a4a7fcf4f06da1a6fec7a64e32d.
2017-05-11 09:57:47 +02:00
David A. Velasco
c9a06fc5e4 Fix NullPointerException in update of public shares while keeping compatibility of the operation with servers not supporting 'name' property in shares 2017-05-10 15:34:22 +02:00
davigonz
a034338290 Fix wrong or no update parameter given in servers < 10 2017-05-09 18:18:22 +02:00
davigonz
beb9be05de Fix hide + button to create a public share in servers <10 2017-05-09 09:05:21 +02:00
David A. Velasco
8f5ac456ab Prevent send of empty value for expiration date and link name when public share is created 2017-05-05 13:26:47 +02:00
David A. Velasco
6d0773cf34 Add support for capability to show optional warning about public shares 2017-05-05 13:26:47 +02:00
davigonz
8ae4dd137d Added multiple share links to the capabilities 2017-05-05 13:26:47 +02:00
davigonz
e80b50d4de Get public share name instead of token when using public share getName method and there's no name 2017-05-05 13:26:47 +02:00
davigonz
8f3aeb30ed Use the token instead of the path when a public link has been created with no name 2017-05-05 13:26:47 +02:00
David A. Velasco
ee726119cb Clarify absence and patch of URL field of OCShares 2017-05-05 13:26:47 +02:00
davigonz
dda1429581 Create public link [WIP] 2017-05-05 13:26:47 +02:00
David A. Velasco
188ce07155 Add support for optional name in public shares (WIP) 2017-05-05 13:26:47 +02:00
David A. Velasco
0dce40b160 Merge pull request #159 from owncloud/retry_transfers_after_lost_network
Improve support for unexpected loss of network connection.
2017-04-25 18:10:10 +02:00
David A. Velasco
11363adedb Clean up after CR 2017-04-25 12:31:04 +02:00
David A. Velasco
0e5cf18d8c Update build version to Java 7 2017-04-25 11:34:49 +02:00
David A. Velasco
9fe7c995dd Add write timeout if socket implementation supports it, so that chances of blocking and upload if network is removed are minimized 2017-04-21 16:10:16 +02:00
David A. Velasco
02e3a90df3 Release input stream on IO exceptions so that next download in the queue does not get stucked 2017-04-20 11:30:29 +02:00
David A. Velasco
e6f9eb43d9 Merge pull request #157 from owncloud/update_gradle_version_and_plugin
Update version of build tools and gradle dependencies
2017-04-19 11:06:39 +02:00
David A. Velasco
096b46ca3c Update build tools version 2017-04-19 10:19:38 +02:00
David A. Velasco
24041deb6d Update version of gradle dependencies 2017-04-18 18:56:42 +02:00
David A. Velasco
7d49e20258 Merge pull request #156 from owncloud/support_hidden_version_in_status_php
Allow the usage of OwnCloudVersion instances for invalid server versions
2017-04-17 14:25:27 +02:00
David A. Velasco
1f69348cc6 Updated tests for OwnCloudClient after removing path constant ODAV_PATH 2017-04-17 13:49:00 +02:00
David A. Velasco
f42a9f8c61 Constants and comments after crossed review 2017-04-17 10:25:58 +02:00
David A. Velasco
825ef70cef Allow the usage of OwnCloudVersion instances for invalid server versions, and removed some really old or never used endpoint paths 2017-04-07 14:57:01 +02:00
David González Verdugo
ef49035784 Merge pull request #155 from owncloud/release_0.9.16
Release 0.9.16
2017-03-08 11:23:36 +01:00
davigonz
d7f453f0e3 Deleted <p> 2017-03-07 09:22:08 +01:00
davigonz
29493f1983 Change MAINTENANCE_MODE ResultCode to SERVICE_UNAVAILABLE 2017-03-06 12:36:40 +01:00
David González
f0b8cf1b66 Merge pull request #151 from owncloud/prevent_access_to_accounts_of_other_apps
Prevent access to accounts of other apps with the same name as an OC …
2017-02-21 10:41:10 +01:00
David A. Velasco
1535be3876 Prevent access to accounts of other apps with the same name as an OC account 2017-02-20 11:08:44 +01:00
jabarros
5d17bbb88d Merge pull request #154 from owncloud/ext_storage
Ext storage
2017-02-20 09:56:40 +01:00
David González
9854ef6f60 Update RemoteOperationResult.java 2017-02-20 09:19:48 +01:00
davigonz
4dea8debb4 Merge branch 'master' into ext_storage 2017-02-14 14:15:53 +01:00
David González
71bdd1d035 Merge pull request #149 from owncloud/recover_preemptive_authentication
Use preemptive authentication except in server versions where it is n…
2017-02-13 10:42:34 +01:00
David A. Velasco
d5e179d7a2 Use preemptive authentication except in server versions where it is not compatible with session tracking 2017-02-13 09:34:40 +01:00
davigonz
06f907294a Change HEAD method to PROPFIND method while checking path existence before starting an upload 2017-02-10 12:17:57 +01:00
davigonz
21d1265ca5 Show error message when there is an external storage error 2017-02-09 18:07:44 +01:00
David González
28d228b296 Merge pull request #152 from owncloud/firewall_error_messages
Firewall error messages
2017-02-09 14:17:52 +01:00
davigonz
1f58cfc941 Update comment 2017-02-07 13:11:06 +01:00
davigonz
626e2f0efa Added changes requested in PR 2017-02-07 08:53:14 +01:00
davigonz
12e7af8af5 Reformat code 2017-02-06 12:13:22 +01:00
davigonz
6a3d97a474 Added forbidden exception parser 2017-02-03 14:58:40 +01:00
David A. Velasco
d7a707293d Prevent that connection manager cleans up response buffer of failed downloads 2017-02-03 14:56:40 +01:00
davigonz
67e5ccd4af Exhaust response if status is different from 403 2017-02-03 14:56:40 +01:00
davigonz
1aba54d0f9 Handle specific forbidden error 2017-02-03 14:56:40 +01:00
davigonz
21121e0189 Added forbidden exception parser 2017-02-03 14:56:40 +01:00
David A. Velasco
769116a7d1 Merge pull request #148 from owncloud/update_path_to_user_info_entry_point
Update entry point to get user info
2017-01-26 12:20:42 +01:00
David A. Velasco
1c25cc7835 Update entry point to get user info 2017-01-25 17:48:30 +01:00
David A. Velasco
bdcab895a5 Merge pull request #146 from owncloud/improve_error_feedback
Keep HTTP phrase in RemoteOperationResult as fallback user message
2017-01-13 14:44:51 +01:00
David A. Velasco
14d646ea1d Keep http phrase in RemoteOperationResult as last chance for a detailed user message 2017-01-12 17:32:50 +01:00
David A. Velasco
67665b8691 Merge pull request #144 from owncloud/bug_1722_maintenance_mode
Handle 503 code error
2017-01-10 18:57:54 +01:00
davigonz
65c7fb1305 Update serialVersionUID 2017-01-10 08:57:40 +01:00
davigonz
0fdc5694f1 Handle 503 code error 2016-12-23 10:50:51 +01:00
David A. Velasco
45e70f5906 Merge pull request #143 from owncloud/release_0.9.15
Release 0.9.15
2016-12-20 16:31:25 +01:00
David A. Velasco
457d4f3d2f Merge pull request #142 from owncloud/crash_invalid_port
Fix crash with invalid TCP port
2016-12-20 13:01:37 +01:00
David A. Velasco
d7561264b5 Apply changes after CR 2016-12-20 12:17:05 +01:00
David A. Velasco
4c27395609 Fix crash with invalid TCP port 2016-12-20 11:05:10 +01:00
David A. Velasco
8ced17a930 Merge pull request #141 from owncloud/maintain_session_with_server
Maintain session with server
2016-12-16 10:07:27 +01:00
David A. Velasco
b2034e1be2 Rename confusing vars after CR 2016-12-16 09:45:25 +01:00
David A. Velasco
455cabb72b Add new OwnCloudClientManagerFactory implementation to get OwnCloudClient instances that keep session or not depending on the server version 2016-12-15 14:17:08 +01:00
David A. Velasco
7b88fb4e6c Adapt authentication with basic credentials to reuse server sessions for server >= 9.1 2016-12-15 14:17:08 +01:00
David González
7647a4974b Merge pull request #140 from owncloud/761_file_modification_date_lost
File modification date lost when uploading file
2016-12-15 14:14:13 +01:00
davigonz
b9492966a5 Updated test with needed params 2016-12-15 13:51:12 +01:00
davigonz
576231023b Decrease some lines length 2016-12-14 13:39:18 +01:00
davigonz
274e0ec47b Set modification date from the file in filesystem to the file to upload 2016-12-14 11:40:11 +01:00
davigonz
0fef17a609 Add line breaks 2016-12-13 10:48:24 +01:00
davigonz
09612b2dd9 Delete not needed import 2016-12-13 10:46:33 +01:00
davigonz
53a5818688 Delete unnecessary line 2016-12-13 10:44:52 +01:00
davigonz
4c1f91e9ef Fix bug in chunked upload (work in progress) 2016-12-13 09:01:41 +01:00
David González Verdugo
3d8ec568ec Fixed bug with normal update operation (not chunked) 2016-12-12 10:56:54 +01:00
David A. Velasco
fd9067ef4a Merge pull request #139 from owncloud/available_offline_folder
Close streams in GetRemoteUserAvatarOperation
2016-12-09 12:32:04 +01:00
David A. Velasco
fdebb05a13 Update test for GetRemoteUserAvatarOperation after retrieval conditioned by ETag was disabled 2016-12-09 10:15:30 +01:00
David A. Velasco
67d7217d13 Revert "Allow conditional read of list of files in a folder based on ETag"; server does not work that way
This reverts commit 5ff9062ea8fefb1bf2b3952b9d64daa4f9922a39.
2016-11-22 17:04:33 +01:00
David A. Velasco
b87d2c9e7c Prevent conditional update of remote avatar to work around bug breaking refesh of root folder 2016-11-22 16:48:26 +01:00
David A. Velasco
5ff9062ea8 Allow conditional read of list of files in a folder based on ETag 2016-11-11 09:10:26 +01:00
David A. Velasco
e0f0416c9e Merge pull request #136 from owncloud/upload_bigfiles
Increase the last chunk timeout in uploads
2016-10-31 10:23:57 +01:00
jabarros
5404b5c2c3 Increase the last chunk timeout in uploads 2016-10-31 09:58:25 +01:00
David A. Velasco
a13b5ec17c Merge pull request #138 from owncloud/1556_access_to_avatars
Add GetRemoteUserAvatarOperation to get data and metadata of current user avatar.
2016-10-18 12:59:50 +02:00
David A. Velasco
0b945f8676 Removed secret vars to access test server from .travis.yml - now in settings 2016-10-18 12:34:37 +02:00
David A. Velasco
4cf779e444 Add GetRemoteUserAvatarOperation to get data and metadata of current user avatar 2016-10-18 12:10:27 +02:00
David A. Velasco
dc14474c51 Merge pull request #137 from owncloud/update_tools
Update gradle plugin & Jackrabbit-Webdav
2016-09-27 20:12:11 +02:00
David A. Velasco
1440809fc7 Update Jackrabbit-WebDAV version 2016-09-27 11:46:36 +02:00
David A. Velasco
61b033b1d9 Removed problematic emulator options 2016-09-27 11:42:11 +02:00
David A. Velasco
410c4bd5b5 Update gradle plugin and remove buildscript entry from build.gradle in modules level 2016-09-27 09:12:26 +02:00
David A. Velasco
1bbc67b704 Merge pull request #133 from owncloud/update_sdk_tools_versions
Update Android SDK Build Tools to version 24.0.2
2016-08-29 13:54:59 +02:00
David A. Velasco
855a06045e Update Android SDK Build Tools to version 24.0.2 2016-08-29 10:45:06 +02:00
David A. Velasco
ebcaf1ddfc Merge pull request #96 from owncloud/bring_back_logging_arguments
Bring back logging arguments
2016-08-18 17:10:07 +02:00
Bartosz Przybylski
45650d2307 Sychronize methods for logging starting and stopping.
First of, this will prevent logs mixing, sencondly this will allow user to safely migrate data even when other thread will call logging functions
2016-08-17 18:56:19 +02:00
Bartosz Przybylski
17325dd43f Update Log_OC.java
Fix typos
2016-08-17 18:56:19 +02:00
Bartosz Przybylski
080b3f56fc Stop logging in exception free way 2016-08-17 18:56:19 +02:00
Bartosz Przybylski
9cbf572510 Add stopLogging method to Log_OC 2016-08-17 18:56:19 +02:00
Bartosz Przybylski
9adb155f7e Bring back storagePath argument in startLogging 2016-08-17 18:56:19 +02:00
David A. Velasco
5dde382fbb Merge pull request #131 from owncloud/update_graddle_tools_and_wrapper_versions
Updated graddle wrapper and plugin versions from security recommendation
2016-08-17 18:54:03 +02:00
David A. Velasco
df199beb1b Update Jackrabbit-webdav version also for ant-based build 2016-08-17 18:22:11 +02:00
David A. Velasco
71fefb286c Set jcenter as source of dependencies; build tools updated all the way; Jackrabbit-webdav updated to last stable 2016-08-17 18:22:11 +02:00
David A. Velasco
50a4a0f09e Updated graddle wrapper and plugin versions from security recommendation 2016-08-17 18:22:11 +02:00
David A. Velasco
9e30147161 Merge pull request #102 from owncloud/userQuota
User quota
2016-08-17 18:13:19 +02:00
David A. Velasco
477a99e243 Renamed operation to get quota following scheme of rest of operations, and some clean-up 2016-08-17 10:54:53 +02:00
David A. Velasco
b8aa7b6119 Changes after CR 2016-08-17 10:17:29 +02:00
Bartosz Przybylski
46b5d5a4b9 Add test to fetching user quota, add more handy return data object from remote operation 2016-08-17 09:56:35 +02:00
MMMarcy
8d11a519db Commit that introduces a new Remote Operation that fetches users' quota
statistics
2016-08-17 09:56:35 +02:00
David A. Velasco
7458e16d62 Merge pull request #130 from owncloud/ChangesForAndroidN
Target API level 24 (Android N)
2016-08-12 12:03:36 +02:00
Gurpreet
2e17ca3e34 - added target=android-24 in in file test_client/tests/project.properties 2016-08-12 11:04:37 +02:00
Gurpreet
445cbef3aa - changed project.properties files. 2016-08-12 11:04:37 +02:00
Gurpreet
8145e6c080 - changes made to .travis.yml file. 2016-08-12 11:04:37 +02:00
Gurpreet
15c6ab6ded - changes made to .travis.yml file. 2016-08-12 11:04:37 +02:00
Gurpreet
9fa3c5bb4f - changed the buildVersions and target SDK to 24. 2016-08-12 11:04:37 +02:00
David A. Velasco
bd33e65090 Merge pull request #77 from mendhak/master
Allow asynchronous execution without handler
2016-08-11 09:26:07 +02:00
mendhak
df743af8c5 Merge branch 'master' into master 2016-08-10 18:11:28 +01:00
David A. Velasco
02cb6749da Merge pull request #101 from owncloud/fix_project_setup
Fixed lint setup
2016-08-10 13:16:35 +02:00
Bartosz Przybylski
34d1ce986b Correctly setup lint options 2016-08-10 12:54:18 +02:00
David A. Velasco
1b191151ed Merge pull request #129 from owncloud/release_0.9.13
Release 0.9.13
2016-08-09 11:20:28 +02:00
David A. Velasco
70e38cda59 Fix Share parser: share type is not determined by existance of <url> element in share 2016-08-04 16:37:47 +02:00
David A. Velasco
20c9830922 Updated copyright 2016-08-02 13:31:56 +02:00
David A. Velasco
f0b649ecd6 Merge pull request #127 from owncloud/add_check_for_unshareable_federated_shares
Add check to OwnCloudVersion for not-reshareable federated shares support
2016-08-01 13:11:04 +02:00
David A. Velasco
46ec581740 Fix permissions for federated folders 2016-07-29 12:18:00 +02:00
David A. Velasco
e4fc7ea25b Add method to OwnCloudVersion to check if not-reshareable federated shares are supported 2016-07-26 12:53:59 +02:00
David A. Velasco
0ce18350cf Merge pull request #125 from owncloud/1639_show_display_name_instead_of_login_name
Support to access display name of stored accounts
2016-06-16 14:32:00 +02:00
David A. Velasco
f679e55933 Updated OwnCloudAccount#getDisplayName with better fallbacks 2016-06-16 12:14:47 +02:00
David A. Velasco
4d80ca096d Removed annoying NONE value from OwnCloudAccount#getDisplayName 2016-06-15 10:21:20 +02:00
David A. Velasco
75667c67f4 Renamed GetRemoteUserNameOperation to GetRemoteUserInfoOperation 2016-06-13 13:49:04 +02:00
David A. Velasco
06f27a7c79 Undo buggy refactoring; too much to do in that sense to get it works 2016-06-09 10:54:08 +02:00
David A. Velasco
afe65bdc3f Return user name when display name is unknown 2016-06-09 10:02:32 +02:00
David A. Velasco
743661ca90 Added field 'displayName' to OwnCloudAccount, and refactoring load of account from storage 2016-06-09 10:02:32 +02:00
David A. Velasco
48f35c14b4 Merge pull request #124 from owncloud/stable
Merge release 0.9.12 from stable to master
2016-06-08 16:58:09 +02:00
David A. Velasco
954f69de99 Merge pull request #122 from owncloud/release_0.9.12
Release 0.9.12 , supporting release 2.0.1 of OC for Android
2016-06-08 09:21:44 +02:00
David A. Velasco
cdce258a3f Fixed case of 'no update of upload permission' in operation updating public shares 2016-06-07 13:09:12 +02:00
David A. Velasco
785562038e Merge pull request #119 from owncloud/fix_non_alphanumeric_chars_in_password
Fixed support of non alphanumeric chars in password
2016-05-03 10:37:21 +02:00
David A. Velasco
0666f08ea6 Moved credentials charset constant out of interface, so that it's correctly initialized 2016-04-28 14:00:44 +02:00
Andy Scherzinger
3f89bf20a4 make "UTF-8" String a constant 2016-04-28 12:22:52 +02:00
Luke Owncloud
f69814f574 allows special chars in password 2016-04-28 12:22:52 +02:00
Luke Owncloud
256c607da8 allow special chars in password 2016-04-28 12:22:52 +02:00
David A. Velasco
5e5aac5fe1 Merge pull request #120 from owncloud/studio21Update
Update gradle android plugin to 2.1.0
2016-04-28 10:54:32 +02:00
Andy Scherzinger
5a2674516a Update gradle android plugin to 2.1.0 2016-04-27 14:40:44 +02:00
David A. Velasco
0d95b0ce24 Merge pull request #117 from owncloud/Studio2Update
Support Android Studio 2.0 (build tools 23.0.3 + gradle 2.10 + gradle plugin 2.0)
2016-04-26 16:45:13 +02:00
Andy Scherzinger
037b1baadf removed support lib updates in travis build since support lib isn't used/referenced 2016-04-25 16:08:08 +02:00
Andy Scherzinger
95b57e7b3d removed unused support lib dependency 2016-04-25 16:06:17 +02:00
Andy Scherzinger
0a941691bd Android Studio 2.0 Update, gradle 2.10 update, build tools 23.0.3 and support lib update in travis 2016-04-25 15:34:24 +02:00
David A. Velasco
f53ebc09b2 Merge pull request #118 from owncloud/stable
Release 0.9.11
2016-04-21 12:53:16 +02:00
David A. Velasco
19e30a6236 Added util method to extract username from saved Account 2016-04-01 14:58:23 +02:00
David A. Velasco
740f0deb82 Fixed bug resulting in false success when one of multiple Share properties are updated 2016-04-01 14:57:46 +02:00
David A. Velasco
39e3ddaa07 Merge pull request #112 from owncloud/reliable_uploads_actions_uploads_view
Update to support changes for uploads view in OC app
2016-03-30 13:45:23 +02:00
David A. Velasco
0bfc385707 Improved detection of exceptions in uplaods due to local errors 2016-03-21 17:07:23 +01:00
David A. Velasco
78b9aa6247 Redirections to the Identity Provider (IdP) are translated into ResultCode.UNAUTHORIZED 2016-03-21 16:48:12 +01:00
masensio
d36fa0b38b Clean code 2016-03-21 16:48:12 +01:00
Juan Carlos González Cabrero
023d8107ca New Result code added to RemoteOperationResult 2016-03-21 16:48:12 +01:00
David A. Velasco
e6eb4b6e53 Added DELAYED_FOR_WIFI to RemoteOperationResult 2016-03-21 16:48:12 +01:00
David A. Velasco
e7891c4acb Merge pull request #113 from owncloud/edit_public_share_permission
Edit public share permission
2016-03-21 09:35:05 +01:00
Juan Carlos González Cabrero
573afa1538 Update comment, error handling and indentation in the automatic test 2016-03-21 09:05:47 +01:00
Juan Carlos González Cabrero
57aa370be0 Update public share tests and refactored publicUpload permission handling 2016-03-21 09:05:47 +01:00
Juan Carlos González Cabrero
5c68c3f605 Added automated test for creation of the share operation with edit permission enabled 2016-03-21 09:05:47 +01:00
Juan Carlos González Cabrero
46f930f6cf Add new PUT argument for the public upload permission and include in the operation 2016-03-21 09:05:47 +01:00
David A. Velasco
cf3baa6cd5 Merge pull request #111 from owncloud/federated_sharing
Support for federated sharing
2016-03-16 10:05:11 +01:00
Juan Carlos González Cabrero
996660b88c Fix indentation errors 2016-03-16 09:50:18 +01:00
Juan Carlos González Cabrero
547f7116ac Merge branch 'federated_sharing' of https://github.com/owncloud/android-library into federated_sharing 2016-03-16 09:48:21 +01:00
Juan Carlos González Cabrero
3fd4e3b898 Added new encrypted variable referencing the new QA server to travis config 2016-03-16 09:16:52 +01:00
Juan Carlos González Cabrero
6c90e79c53 Added setup variable for a new QA server path 2016-03-16 09:14:50 +01:00
Juan Carlos González Cabrero
add2aab31e New tests for the federated sharing 2016-03-16 09:13:20 +01:00
Juan Carlos González Cabrero
4d524100d5 Added new encrypted variable referencing the new QA server to travis config 2016-03-09 14:01:41 +01:00
Juan Carlos González Cabrero
5dfd4cac5e Added setup variable for a new QA server path 2016-03-09 13:18:59 +01:00
Juan Carlos González Cabrero
0689213e72 New tests for the federated sharing 2016-03-09 10:32:12 +01:00
Juan Carlos González Cabrero
1e1d424ffb Fix comparison of share type in the GetShareesTest 2016-03-07 13:55:18 +01:00
Juan Carlos González Cabrero
b13e584ac3 Remove the share type constants from GetRemoteShareesOperation 2016-03-07 09:07:51 +01:00
Juan Carlos González Cabrero
36da2a2336 Parse the lists of remote users from the JSON response of the server 2016-03-03 12:45:05 +01:00
Juan Carlos González Cabrero
23643ad28e Added new share permissions for the federated shares 2016-03-01 13:24:05 +01:00
Maria Asensio
1007a80534 Merge pull request #109 from owncloud/target_marshmallow
Updated build target to Android APIv23
2016-02-19 11:19:49 +01:00
David A. Velasco
27237576ef Fixed wrong test case for shares, and warnings in test cases 2016-02-16 13:31:55 +01:00
David A. Velasco
d17d8b9a52 Moved target folder for download test to private storage, to fix problems with runtime check of permissions in Android 6 2016-02-16 12:45:26 +01:00
David A. Velasco
8b91c71d6f Updated build target to Android APIv23 2016-02-13 21:24:10 +01:00
David A. Velasco
4eb15976ea Merge pull request #108 from owncloud/stable
Update master with release 0.9.10
2016-02-10 11:33:32 +01:00
David A. Velasco
a953a890d3 Added FEDERATED as an acceptable ShareType 2016-02-05 14:23:41 +01:00
mendhak
59af0394ec Allow asynchronous execution without handler 2016-01-30 09:26:15 +00:00
mendhak
31836d3f4a Merge remote-tracking branch 'upstream/master' 2016-01-30 08:34:24 +00:00
Maria Asensio
95919c9005 Merge pull request #105 from owncloud/share__edit_privileges
Share  edit privileges
2016-01-27 11:06:38 +01:00
David A. Velasco
ac9771ea3a Migration to different test server 2016-01-27 10:52:15 +01:00
David A. Velasco
b3535a3678 Updated automatic tests to cover share permissions updates 2016-01-26 18:39:01 +01:00
David A. Velasco
275c042f78 Added constants for maximum Share permissions 2016-01-18 13:55:35 +01:00
David A. Velasco
249cb901eb Added support to update share permissions 2016-01-11 12:13:19 +01:00
David A. Velasco
dad5cd115a Added constants to analyze share permissions 2016-01-11 12:13:17 +01:00
David A. Velasco
1b7a569040 Merge pull request #68 from owncloud/close-resource
Close resource in finally block
2015-12-16 18:19:42 +01:00
Lukas Reschke
d39d26f842 Close in finally block 2015-12-16 18:08:36 +01:00
Lukas Reschke
5c87414390 Close resource in finally block
I don't quite get the reason for `mBuf` here as in `com.owncloud.android.lib.common.utils.Log_OC#appendLog` anyways a new `BufferedWriter` is started but it might make sense to close this here as this will otherwise cause warnings in static code scanners.

Didn't test this as I don't have a Java device and so it requires extensive testing.
2015-12-16 18:08:35 +01:00
David A. Velasco
715a519523 Merge pull request #100 from owncloud/stable
Fix bug related with sharee with special characters
2015-12-09 16:19:45 +01:00
masensio
77c0d785c9 Fix bug related with sharee with special characters 2015-11-26 13:26:24 +01:00
David A. Velasco
9e5c44ddb5 Merge pull request #98 from owncloud/share_with_password_and_expiration_time
Changes to support update of password and expiration time in public shares
2015-11-25 09:28:32 +01:00
David A. Velasco
9cf96a10ce Fixed lost of share link when token exists 2015-11-24 13:44:42 +01:00
masensio
1e3060633d Add test for UpdateRemoteShareOperation 2015-11-23 17:51:33 +01:00
David A. Velasco
f6bd45b2a7 Added support to update expiration date in an existing share 2015-11-23 17:51:32 +01:00
David A. Velasco
206c7abf10 Fixed unit tests 2015-11-23 17:51:31 +01:00
David A. Velasco
90615fc4ab Added operation to update properties of exising share via link 2015-11-23 17:51:30 +01:00
David A. Velasco
0238e51903 Prevent null values in OCShare members 2015-11-23 17:51:29 +01:00
David A. Velasco
b09969d078 Merge pull request #92 from owncloud/read_capabilities_for_showing_share_options
Added resource Capabilities and operation to get them
2015-11-12 10:26:26 +01:00
masensio
75581c18a4 Read capabilities to show the Share Options 2015-11-11 10:17:58 +01:00
David A. Velasco
7bd4dc96db Merge pull request #94 from owncloud/setup-coverity
Setup coverity
2015-11-10 17:55:31 +01:00
Lukas Reschke
92b13d2414 Run Coverity on library
Limit to coverity_scan branch
2015-11-10 17:44:14 +01:00
David A. Velasco
c2b8b3625d Merge pull request #93 from owncloud/DeepDiver1975-patch-1
Enable push job only on master
2015-11-10 17:20:48 +01:00
Thomas Müller
b89246a656 Enable push job only on master 2015-11-10 16:54:59 +01:00
Maria Asensio
32ab89fc30 Merge pull request #90 from owncloud/share_with_users
Added operations to allow apps share with OC users, including GetRemoteShareesOperation
2015-11-05 13:10:33 +01:00
Maria Asensio
fe62a9fd20 Merge pull request #89 from owncloud/share_with_users__unit_tests
Unit tests updated to share with users
2015-11-03 09:35:20 +01:00
David A. Velasco
5c48817712 Update unit tests with cases for creating private shares 2015-11-02 14:59:01 +01:00
David A. Velasco
b5074f4381 Migrate Travis build to container-based infrastructure 2015-10-30 14:55:31 +01:00
David A. Velasco
96825b43b9 Updated test server 2015-10-30 14:55:30 +01:00
David A. Velasco
caa9bb3d01 Added test for GetRemoteShareesOperation 2015-10-30 14:55:29 +01:00
David A. Velasco
875fce9f9c Added constant to let server decide share permissions 2015-10-30 14:55:10 +01:00
masensio
642051cf45 Remove commented code 2015-10-30 14:55:09 +01:00
masensio
ea26e43c0d GetRemoteShareeOperation returns ArrayList<JSonObject> with Users and Groups 2015-10-30 14:55:08 +01:00
masensio
a9ada0b508 Fix problem searching users on Shibboleth Server. Add OC_API_HEADER to GetRemoteShareesOperation 2015-10-30 14:55:07 +01:00
masensio
0acd17d8ac Fix: user whose name includes @ are not found 2015-10-30 14:55:06 +01:00
David A. Velasco
bfe4fcd977 Changes after cr 2015-10-30 14:55:05 +01:00
David A. Velasco
4d9ff3e022 Refactoed operations on Shares 2015-10-30 14:55:04 +01:00
David A. Velasco
ad60bc9e8e Complete error handling and add error message from server to response 2015-10-30 14:55:03 +01:00
David A. Velasco
3d34e504ff Refactored resources.users.GetRemoteUsersAndGroupsOperation to resources.shares.GetRemoteShareesOperation 2015-10-30 14:55:02 +01:00
David A. Velasco
68e0633b74 Add option to retrieve share details in CreateRemoteShareOperation; by default the server only returns the share id 2015-10-30 14:55:01 +01:00
David A. Velasco
3b3b992a79 Get users or groups available to share with via SHAREE API 2015-10-30 14:55:00 +01:00
masensio
0793d3fca7 Fix NODE_SHARE_WITH_DISPLAY_NAME tag in ShareXMLParser 2015-10-30 14:54:58 +01:00
David A. Velasco
d9eb3655fd Removed constrain to parse only public shares 2015-10-30 14:54:57 +01:00
masensio
cea7054a3d Add Get Groups Operation to the library 2015-10-30 14:54:56 +01:00
masensio
fa17c6947e Remove unused constants 2015-10-30 14:54:55 +01:00
masensio
0c6dfef908 Add operation to get users from the server 2015-10-30 14:54:54 +01:00
masensio
c3f24e817e Add method to know if server supports search users function 2015-10-30 14:54:53 +01:00
Maria Asensio
f02dffb1d3 Merge pull request #83 from owncloud/sync_full_folder
Minor changes to support synchronization of full folders in OC app
2015-10-30 14:06:48 +01:00
David A. Velasco
eb4f8a7234 Added constructors to grant that upload operations only succeed if the remote copy keeps a given ETag 2015-09-28 11:13:44 +02:00
David A. Velasco
f61b466124 Improved ETag parsing 2015-09-28 10:49:45 +02:00
David A. Velasco
092c790030 Add capability to reatin ETag value in download operations 2015-09-25 15:10:34 +02:00
David A. Velasco
522ea30da0 Simplified flow of interruption of uploads in cancellations 2015-09-25 15:10:33 +02:00
David A. Velasco
8bf276377c Minor improvements for upload cancelation and conflicts in synchronization 2015-09-25 15:10:31 +02:00
David A. Velasco
5985ba9a9f Merge pull request #85 from owncloud/update_share_link_for_OC_8.2
Update share link for oc 8.2
2015-09-14 14:58:13 +02:00
masensio
ecc3415e3e Fix bug: Sharing an already shared file generates the old link 2015-09-14 13:21:00 +02:00
masensio
30df7c33fb Build the share link of a file if it isn't in the response of the server 2015-09-11 14:48:19 +02:00
masensio
17bb724b42 Merge pull request #82 from owncloud/copy
Copy operation
2015-09-04 10:59:31 +02:00
root
ef07416c6a Updated target server for automatic tests 2015-09-01 15:46:14 +00:00
David A. Velasco
27b0308e06 //This extra check is unnecessary after https://github.com/owncloud/core/pull/14505 2015-09-01 16:01:41 +02:00
David A. Velasco
5ac5c80809 Return FILE_NOT_FOUND error only if the file is not found in the server, not in case of any other error checking its existence 2015-08-18 18:06:06 +02:00
David A. Velasco
b15fb19399 Fixed broken copy test 2015-08-18 14:18:37 +02:00
David A. Velasco
819b465385 Recovered error when file to copy doesn't exist but still keeping dependency on Context out 2015-08-18 14:07:59 +02:00
David A. Velasco
b281585c93 Updated CopyRemoteFileOperation constructor 2015-08-18 13:27:44 +02:00
Jorge Antonio Diaz-Benito Soriano
6f12324930 Added some missing imports 2015-08-18 13:14:23 +02:00
Jorge Antonio Diaz-Benito Soriano
ed720d0a65 Cleanup 2015-08-18 13:14:22 +02:00
Jorge Antonio Diaz-Benito Soriano
2970b54e7c Updated CopyRemoteFileOperation and verified with the unit tests 2015-08-18 13:14:21 +02:00
Jorge Antonio Diaz-Benito Soriano
8633efbb49 Added some neccesities for the copy operation 2015-08-18 13:14:20 +02:00
Jorge Antonio Diaz-Benito Soriano
b53c8ccf9d Updated some dependencies 2015-08-18 13:14:19 +02:00
Jorge Antonio Diaz-Benito Soriano
97b133b36a Updated .gitignore 2015-08-18 13:14:18 +02:00
Jorge Antonio Diaz-Benito Soriano
b8830e0faf Disabled abort-build-on-lint-error check (all modules have errors). 2015-08-18 13:14:17 +02:00
Jorge Antonio Diaz-Benito Soriano
25ec49acfb Replaced obsolete Android plugins and updated Gradle plugin version to 0.13 2015-08-18 13:14:16 +02:00
Jorge Antonio Diaz-Benito Soriano
775fb5b1f2 Updated build.gradle to allow Android Studio to properly identify test_client as a module 2015-08-18 13:14:14 +02:00
Jorge Antonio Diaz-Benito Soriano
8e0739aed0 Added gradle folder to .gitignore 2015-08-18 13:14:13 +02:00
Jorge Antonio Diaz-Benito Soriano
f753b1bde8 Added INVALID_COPY_INTO_DESCENDANT code 2015-08-18 13:14:12 +02:00
Jorge Antonio Diaz-Benito Soriano
542e596bf5 Removed unnecessary command 2015-08-18 13:12:27 +02:00
Jorge Antonio Diaz-Benito Soriano
3e28768d8f Updated some dependencies 2015-08-18 13:12:25 +02:00
Jorge Antonio Diaz-Benito Soriano
43e82df560 New Travis-CI conf test 2015-08-18 13:12:24 +02:00
Jorge Antonio Diaz-Benito Soriano
0842c4c407 Added some neccesities for the copy operation 2015-08-18 13:11:31 +02:00
Jorge Antonio Diaz-Benito Soriano
5f66b204bb Updated .gitignore 2015-08-18 13:04:06 +02:00
Jorge Antonio Diaz-Benito Soriano
c3478eb8d4 Disabled abort-build-on-lint-error check (all modules have errors). 2015-08-18 13:04:05 +02:00
Jorge Antonio Diaz-Benito Soriano
4a76d429ab Updated build.gradle to allow Android Studio to properly identify test_client as a module 2015-08-18 13:04:04 +02:00
Jorge Antonio Diaz-Benito Soriano
7fd0028cc9 Added sample_client build.gradle 2015-08-18 13:04:03 +02:00
Jorge Antonio Diaz-Benito Soriano
39b3f376e2 Added gradle folder to .gitignore 2015-08-18 13:04:02 +02:00
Jorge Antonio Diaz-Benito Soriano
d73180ab67 Added build.gradle 2015-08-18 13:04:01 +02:00
David A. Velasco
dbc8c325d7 Merge branch 'develop' 2015-08-07 10:13:01 +02:00
David A. Velasco
e3dddbdcc7 Merge pull request #81 from owncloud/updated_readme_about_target_of_PRs
Updated README.md with new policy: PRs should go to master, no more t…
2015-08-07 10:10:50 +02:00
David A. Velasco
e71ba7faee Removed reference to git branching model to avoid confussion 2015-08-07 09:09:20 +02:00
David A. Velasco
0ae4d1dac9 Updated README.md with new policy: PRs should go to master, no more to develop 2015-08-06 12:40:59 +02:00
masensio
c8f6e5ad57 Merge pull request #80 from owncloud/username_in_saml_sso
Added username to SAML SSO credentials
2015-08-06 10:39:32 +02:00
David A. Velasco
1fa8e79b3f Fixed unit tests 2015-08-06 09:34:42 +02:00
David A. Velasco
6752b25b8d Added username to OwnCloudSamlSsoCredentials 2015-08-06 09:34:41 +02:00
David A. Velasco
3b9777c5b6 Merge pull request #79 from owncloud/update_buildTools_to_22_0_1
Update buildTools version to 22.0.1
2015-08-04 12:27:03 +02:00
David A. Velasco
3ecefdfbcc Updated buildTools in all the Gradle files 2015-08-04 11:49:07 +02:00
David A. Velasco
8d9e0bf682 Fixed build tools dependency in Travis 2015-08-04 11:33:18 +02:00
masensio
dc057816d3 Update buildTools version to 22.0.1 2015-08-04 11:14:07 +02:00
David A. Velasco
bfa5e4c6ba Merge pull request #78 from owncloud/update_jackrabbit_library
Update JackRabbit library to 2.10.1
2015-08-03 14:28:22 +02:00
masensio
482a70fba1 Replace jackrabbit 2.7.2 jar file by jackrabbit 2.10.1 jar file 2015-07-31 15:20:23 +02:00
masensio
4b1c9725c6 Replace jackrabbit 2.7.2 jar file by jackrabbit 2.10.1 jar file 2015-07-31 15:19:38 +02:00
masensio
d89387b8df Update build.gradle with jackrabbit version 2.10.1 2015-07-31 11:22:04 +02:00
mendhak
defe460a0a Allow asynchronous execution without handler 2015-07-04 23:30:54 +01:00
David A. Velasco
02c24c8a3b Fixed existence check on files when automatic redirections are explicitly disabled (SAML SSO) 2015-07-02 14:02:31 +02:00
masensio
f5fbca24be Merge pull request #74 from owncloud/auto_grid_only_with_all_pictures
Added check of support of remote thumbnails to OwnCloudVersion
2015-06-25 12:52:28 +02:00
David A. Velasco
c84530d359 Added helper method to check if a server version supports remote thumbnails 2015-06-23 10:44:09 +02:00
David A. Velasco
5d1f069003 Merge pull request #73 from owncloud/fix_shared_by_link_for_server_without_uploads
Fix shared by link for server without public uploads
2015-06-22 14:53:29 +02:00
masensio
8f87ad78f7 Merge branch 'develop' into fix_shared_by_link_for_server_without_uploads 2015-06-22 14:01:27 +02:00
David A. Velasco
ff85ff2eef Merge branch 'master' into develop 2015-06-22 11:15:46 +02:00
David A. Velasco
08831dfef5 Merge pull request #67 from owncloud/fix-code-that-never-worked
Use .equals instead of !=
2015-06-22 09:37:59 +02:00
masensio
a22b1da16b Don't send public_upload value in createShare 2015-06-19 15:10:36 +02:00
David A. Velasco
344d5b22e4 Merge pull request #71 from owncloud/forbidden_characters_from_server
Support check of forbidden characters in server, for OC >= 8.1
2015-06-17 09:13:12 +02:00
masensio
58deabb773 Changes from comments in Code Review 2015-06-16 15:15:36 +02:00
masensio
dcad9157aa Prevent NullPointerException when OwncloudVersion is null in MoveRemoteFileOperation and RenameRemoteFileOperation 2015-06-16 10:51:50 +02:00
masensio
1811be1b52 Prevent NullPointException when OwncloudVersion is null in CreateRemoteFolderOperation 2015-06-16 10:39:40 +02:00
masensio
060ca75f17 Merge branch 'develop' into forbidden_characters_from_server
Conflicts:
	src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java
	src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java
2015-06-15 14:41:27 +02:00
masensio
639cb7eacd Merge pull request #70 from owncloud/keep_permanent_redirection_in_existence_check
Get that ExistenceCheckRemoteOperation remembers the sequence of foll…
2015-06-15 13:14:36 +02:00
David A. Velasco
41dcc33730 Get that ExistenceCheckRemoteOperation remembers the sequence of followed redirections after its execution
Conflicts fixed:
	src/com/owncloud/android/lib/common/operations/RemoteOperationResult.java
	src/com/owncloud/android/lib/resources/files/RenameRemoteFileOperation.java
2015-06-11 10:32:05 +02:00
masensio
4ca0ff2203 Parse error 500 and InvalidPathException for Uploads 2015-06-03 11:09:58 +02:00
masensio
b8a3eb059c Remove exhaust response in RenameRemoteFileOperation 2015-06-03 11:09:32 +02:00
masensio
16c9147383 Parse and show the error of invalid characters coming from the server side: Move, Rename, Uploads 2015-06-03 00:32:19 +02:00
Lukas Reschke
b102d1cdf9 Change the order to prevent NullPointerExceptions 2015-06-02 16:56:35 +02:00
Lukas Reschke
267c7cfd08 Use .equals instead of !=
This code never worked. Please consider adding unit tests.
2015-06-02 16:51:25 +02:00
masensio
2b09aa2a89 Parse and show the error of invalid characters coming from the server side. Show new message in CreationFolder 2015-06-02 13:07:43 +02:00
masensio
9fc332eef9 Filter only '/' character in user input when version of server is 8.1 or later 2015-06-02 09:37:46 +02:00
David A. Velasco
e48aa9c304 Merge pull request #65 from owncloud/fix_nullPointerException_quota
Fix problems reading quota values: NullPointerException
2015-05-27 08:33:11 +02:00
masensio
409e8d6671 Fix problems reading quota values: NullPointerException 2015-05-26 13:43:30 +02:00
David A. Velasco
67d800027c Merge pull request #63 from owncloud/fix_refresh_large_default_storage
Fixed refresh when quota response holds an unexpected value or format
2015-05-18 14:46:58 +02:00
masensio
0449645fca Changes from comments in PR#63 2015-05-15 10:51:34 +02:00
masensio
0e7319e4ed Adapt WebDav parser for receiving exponential values in QUOTAS 2015-05-11 14:29:55 +02:00
David A. Velasco
e73e4a56d3 Merge pull request #61 from owncloud/loging_different_servers_same_pattern
Support for new name scheme for accounts.
2015-04-22 09:29:08 +02:00
masensio
8ca001af3e Merge pull request #60 from owncloud/adding_account_versions
Adding account versions
2015-04-15 13:06:33 +02:00
David A. Velasco
ddb8648809 Added version for OC accounts 2015-04-15 12:50:33 +02:00
David A. Velasco
2e993f9893 Merge branch 'develop' into adding_account_versions 2015-04-15 12:14:44 +02:00
David A. Velasco
9e761387a0 Merge pull request #59 from owncloud/add_header_OC-TOTAL-LENGHT_to_put_request
Add OC-Total-Length header to ChunkedUploadRemoteFileOperation
2015-04-14 09:30:20 +02:00
masensio
21c329aa12 Set new pattern for account name 2015-04-13 13:30:31 +02:00
masensio
aaebdefe56 Add OC-Total-Length to UploadRemoteFileOperation 2015-04-10 09:21:05 +02:00
masensio
8f068a2849 Add OC-Total-Length header to ChunkedUploadRemoteFileOperation 2015-04-09 18:19:22 +02:00
David A. Velasco
8850a81222 Merge pull request #58 from owncloud/extra_log_message
Extra log message (originally in #48)
2015-04-09 14:20:26 +02:00
David A. Velasco
415d059f95 Merge branch 'develop' of https://github.com/LukeOwnCloud/android-library into LukeOwncloud-develop 2015-04-09 13:26:16 +02:00
LukeOwncloud
4f52b875d1 added log message for ResultCode.FILE_NOT_FOUND 2014-12-12 14:39:22 +01:00
309 changed files with 13386 additions and 14258 deletions

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

5
.editorconfig Normal file
View File

@ -0,0 +1,5 @@
[*]
max_line_length = 150
[*.{kt, kts}]
disabled_rules=no-consecutive-blank-lines,no-wildcard-imports,max-line-length,no-blank-line-before-rbrace,final-newline,indent,no-multi-spaces,comment-spacing,parameter-list-wrapping

17
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,17 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gradle"
directory: "/" # Location of package manifests
schedule:
interval: "daily"
labels:
- "dependencies"
- package-ecosystem: "github-actions"
directory: "/" # Location of package manifests
schedule:
interval: "weekly"

View File

@ -0,0 +1,10 @@
name: "Validate Gradle Wrapper"
on: [pull_request]
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1

15
.gitignore vendored
View File

@ -2,6 +2,9 @@
*.apk *.apk
*.ap_ *.ap_
.idea/*
!.idea/codeStyles/
# files for the dex VM # files for the dex VM
*.dex *.dex
@ -9,25 +12,13 @@
*.class *.class
# generated files # generated files
bin/
build/ build/
gen/ gen/
target/
*.iml *.iml
# Local configuration files (sdk path, etc) # Local configuration files (sdk path, etc)
.idea/
.gradle/ .gradle/
local.properties local.properties
sample_client/local.properties
tests/local.properties
tests/test_cases/local.properties
# Mac .DS_Store files # Mac .DS_Store files
.DS_Store .DS_Store
# Proguard README
proguard-project.txt
sample_client/proguard-project.txt
tests/proguard-project.txt
tests/test_cases/proguard-project.txt

378
.idea/codeStyles/Project.xml generated Normal file
View File

@ -0,0 +1,378 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="RIGHT_MARGIN" value="150" />
<JavaCodeStyleSettings>
<option name="FIELD_NAME_PREFIX" value="m" />
<option name="STATIC_FIELD_NAME_PREFIX" value="s" />
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99999" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99999" />
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
</value>
</option>
</JavaCodeStyleSettings>
<JetCodeStyleSettings>
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
<value>
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
</value>
</option>
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<XML>
<option name="XML_ATTRIBUTE_WRAP" value="0" />
<option name="XML_KEEP_BLANK_LINES" value="1" />
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="150" />
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
<option name="IF_BRACE_FORCE" value="3" />
<option name="DOWHILE_BRACE_FORCE" value="3" />
<option name="WHILE_BRACE_FORCE" value="3" />
<option name="FOR_BRACE_FORCE" value="3" />
<option name="WRAP_LONG_LINES" value="true" />
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<FIELD>true</FIELD>
</match>
</rule>
</section>
<section>
<rule>
<match>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CONSTRUCTOR>true</CONSTRUCTOR>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD>true</METHOD>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<METHOD>true</METHOD>
</match>
</rule>
</section>
<section>
<rule>
<match>
<ENUM>true</ENUM>
</match>
</rule>
</section>
<section>
<rule>
<match>
<INTERFACE>true</INTERFACE>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<CLASS>true</CLASS>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CLASS>true</CLASS>
</match>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ownCloud Android Library</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -1,4 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -1,34 +0,0 @@
language: android
android:
components:
- build-tools-20.0.0
- android-19
- android-17
- android-14
- extra-android-support
licenses:
- 'android-sdk-license-5be876d5'
- 'android-sdk-license-598b93a6'
jdk: oraclejdk7
before_install:
- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI -c 20M
- emulator -avd test -no-skin -no-audio -no-window &
- rm pom.xml
- android update project -p .
before_script:
- chmod +x ./wait_for_emulator.sh
- ./wait_for_emulator.sh
script:
- ant clean
- ant debug
- cd test_client/tests
- ant acceptance-test
- cd ../..
- ./gradlew clean build
env:
global:
- secure: f4Kms/mzkYRG4Kp8k6hsvG3Y0ztbJnA2J79OBw3VdqJOKVTzwsxMd1Yh325YDYO7I4HeHxGXy0H4p3rAPzIWr/nrOJ4wmcDwQYDQtVjF7S1ARWsX51FrCEV6A9ec2LAqNCQ8ZC0SoGb+HsmpFCE3uKAxRQt+B5MzOZvKNcvYpMA=
- secure: aF4U20Xlu/rfrbxCmoJAiGh1doYTAZ10UEDmajuinT+ZGSJLivuqD7DDY/00sI6IXWg+J1vL+7jJm4JSYusHPg38UHZ4q92k6RmZycW2ATUzZnGT54O5FRnY67MfVwgVpIMK9UOL/6NEciBHEjlIOL0wbKQiJB++1YtBZOQLGL4=
- secure: N+ECSwNg8v2GsAFJ2y/tCiffauHDpN76zuFI2pDqf0fjmCtJZHu4BH5ArXBHjyHKmgn20a/8eZXcwJaH1HsJ80bo7vDJ2miShjGIQ90hPcdmUiB2XVJcew4f04CtvMDH5o7DRt4ykWArlbPL2rhVag0jotlSidolHBwRFnbDhDY=
matrix:
- ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- ownCloud Android Library is available under MIT license
Copyright (C) 2015 ownCloud Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.owncloud.android.lib"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
</manifest>

View File

@ -2,7 +2,7 @@
ownCloud Android Library is available under MIT license ownCloud Android Library is available under MIT license
Copyright (C) 2014 ownCloud Inc. Copyright (C) 2020 ownCloud GmbH.
Copyright (C) 2012 Bartek Przybylski Copyright (C) 2012 Bartek Przybylski
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -19,14 +19,14 @@ __Step 2.__ Define a dependency within your project. For that, access to Propert
The repository holds two main branches with an infinite lifetime: The repository holds two main branches with an infinite lifetime:
- master - stable
- develop - master
Branch __origin/master__ is considered the main branch where the source code of HEAD always reflects a production-ready state. Branch __origin/stable__ is considered the main branch where the source code of HEAD always reflects a production-ready state.
Branch __origin/develop__ is considered the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release. Branch __origin/master__ is considered the main branch where the source code of HEAD always reflects a state with the latest delivered development changes for the next release.
When the source code in the develop branch reaches a stable point and is ready to be released, all of the changes should be merged back into master somehow and then tagged with a release number. When the source code in the master branch reaches a stable point and is ready to be released, all of the changes should be merged back into stable somehow and then tagged with a release number.
Other branches, some supporting branches are used to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually. Other branches, some supporting branches are used to aid parallel development between team members, ease tracking of features, prepare for production releases and to assist in quickly fixing live production problems. Unlike the main branches, these branches always have a limited life time, since they will be removed eventually.
@ -35,9 +35,8 @@ The different types of branches we may use are:
- Branch __perNewFeature__ - Branch __perNewFeature__
- Branch __releaseBranches__ - Branch __releaseBranches__
Both of them branch off from develop and must merge back into develop branch through a Pull Request in Github. Once the PR is approved and merged, the US branch may be deleted. Both of them branch off from master and must merge back into master branch through a Pull Request in Github. Once the PR is approved and merged, the US branch may be deleted.
Source: http://nvie.com/posts/a-successful-git-branching-model
### License ### License
@ -45,13 +44,11 @@ ownCloud Android Library is available under MIT license. See the file LICENSE.md
#### Third party libraries #### Third party libraries
ownCloud Android Library uses Apache JackRabbit, version 2.2.5. Copyright (C) 2004-2010 The Apache Software Foundation. Licensed under Apache License, Version 2.0. ownCloud Android Library uses OkHttp version 4.6.0, licensed under Apache License and version 2.0. Besides, it uses Dav4Android, licensed under Mozilla Public License, v. 2.0
Apache JackRabbit depends on Commons HTTPClient version 3.1 and SLF4j version 1.7.5; both included also. Copyright (C) 2004-2010 The Apache Software Foundation. Licensed under Apache License, Version 2.0.
### Compatibility ### Compatibility
ownCloud Android Library is valid for Android systems from version Android 2.2 (android:minSdkVersion="8" android:targetSdkVersion="19"). ownCloud Android Library is valid for Android systems from version Android 6 (android:minSdkVersion="23" android:targetSdkVersion="33").
ownCloud Android library supports ownCloud server from version 4.5. ownCloud Android library supports ownCloud server from version 4.5.

View File

@ -1,54 +1,34 @@
buildscript { buildscript {
ext {
orgJetbrainsKotlin = '1.8.10'
comSquareupMoshi = '1.14.0'
}
repositories { repositories {
google()
mavenCentral() mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.0.0' classpath "org.jlleitschuh.gradle:ktlint-gradle:11.1.0"
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$orgJetbrainsKotlin"
} }
} }
apply plugin: 'com.android.library'
repositories { plugins {
mavenCentral() id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false
} }
dependencies { allprojects {
compile 'commons-httpclient:commons-httpclient:3.1' repositories {
compile 'org.apache.jackrabbit:jackrabbit-webdav:2.7.2' google()
compile 'org.slf4j:slf4j-api:1.7.5' mavenCentral()
} maven { url 'https://jitpack.io' }
android {
compileSdkVersion 19
buildToolsVersion "20.0.0"
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
// Move the tests to tests/java, tests/res, etc...
instrumentTest.setRoot('tests')
// Move the build types to build-types/<type>
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
// This moves them out of them default location under src/<type>/... which would
// conflict with src/ being used by the main source set.
// Adding new build types or product flavors should be accompanied
// by a similar customization.
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
android {
lintOptions {
abortOnError false
}
} }
} }
subprojects {
apply plugin: "org.jlleitschuh.gradle.ktlint"
apply plugin: "com.google.devtools.ksp"
}

View File

@ -1,92 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="owncloud-android-library" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

15
check_code_script.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
check_license_in_file() {
if ! head -n 20 $FILE | grep -q "Permission is hereby granted, free of charge, to any person obtaining a copy"
then
echo "$FILE does not contain a current copyright header"
fi
}
for FILE in $(find owncloudComLibrary/src -name "*.java" -o -name "*.kt")
do
check_license_in_file
done
./gradlew ktlintFormat

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules">
<target name="-post-compile">
<echo>Copying jar file for binary distribution</echo>
<copy file="${out.absolute.dir}/classes.jar" toFile="${out.absolute.dir}/${ant.project.name}.jar" />
</target>
</project>

3
gradle.properties Normal file
View File

@ -0,0 +1,3 @@
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M

Binary file not shown.

View File

@ -1,6 +1,5 @@
#Mon Jan 19 11:03:11 CET 2015
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip

302
gradlew vendored
View File

@ -1,79 +1,129 @@
#!/usr/bin/env bash #!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## #
## Gradle start up script for UN*X # Gradle start up script for POSIX generated by Gradle.
## #
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
############################################################################## ##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Attempt to set APP_HOME
DEFAULT_JVM_OPTS=""
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle" APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD=maximum
warn ( ) { warn () {
echo "$*" echo "$*"
} } >&2
die ( ) { die () {
echo echo
echo "$*" echo "$*"
echo echo
exit 1 exit 1
} } >&2
# OS specific support (must be 'true' or 'false'). # OS specific support (must be 'true' or 'false').
cygwin=false cygwin=false
msys=false msys=false
darwin=false darwin=false
case "`uname`" in nonstop=false
CYGWIN* ) case "$( uname )" in #(
cygwin=true CYGWIN* ) cygwin=true ;; #(
;; Darwin* ) darwin=true ;; #(
Darwin* ) MSYS* | MINGW* ) msys=true ;; #(
darwin=true NONSTOP* ) nonstop=true ;;
;;
MINGW* )
msys=true
;;
esac esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables # IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java" JAVACMD=$JAVA_HOME/jre/sh/java
else else
JAVACMD="$JAVA_HOME/bin/java" JAVACMD=$JAVA_HOME/bin/java
fi fi
if [ ! -x "$JAVACMD" ] ; then if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@ -82,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation." location of your Java installation."
fi fi
else else
JAVACMD="java" JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the Please set the JAVA_HOME variable in your environment to match the
@ -90,75 +140,95 @@ location of your Java installation."
fi fi
# Increase the maximum file descriptors if we can. # Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
MAX_FD_LIMIT=`ulimit -H -n` case $MAX_FD in #(
if [ $? -eq 0 ] ; then max*)
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD=$( ulimit -H -n ) ||
MAX_FD="$MAX_FD_LIMIT" warn "Could not query maximum file descriptor limit"
fi esac
ulimit -n $MAX_FD case $MAX_FD in #(
if [ $? -ne 0 ] ; then '' | soft) :;; #(
warn "Could not set maximum file descriptor limit: $MAX_FD" *)
fi ulimit -n "$MAX_FD" ||
else warn "Could not set maximum file descriptor limit to $MAX_FD"
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules # Collect all arguments for the java command, stacking in reverse order:
function splitJvmOpts() { # * args from the command line
JVM_OPTS=("$@") # * the main class name
} # * -classpath
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS # * -D...appname settings
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" # * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

53
gradlew.bat vendored
View File

@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@ -8,20 +24,23 @@
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@ -45,34 +64,14 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,43 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.devtools.ksp'
apply plugin: 'kotlin-parcelize'
dependencies {
api 'com.squareup.okhttp3:okhttp:4.6.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$orgJetbrainsKotlin"
api 'com.gitlab.ownclouders:dav4android:oc_support_2.1.5'
api 'com.github.AppDevNext.Logcat:LogcatCore:2.2.2'
// Moshi
implementation("com.squareup.moshi:moshi-kotlin:$comSquareupMoshi") {
exclude module: "kotlin-reflect"
}
implementation 'org.apache.commons:commons-lang3:3.12.0'
ksp "com.squareup.moshi:moshi-kotlin-codegen:$comSquareupMoshi"
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.robolectric:robolectric:4.10'
debugImplementation 'com.facebook.stetho:stetho-okhttp3:1.6.0'
}
android {
compileSdkVersion 33
defaultConfig {
minSdkVersion 23
targetSdkVersion 33
}
lint {
abortOnError false
ignoreWarnings true
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
namespace 'com.owncloud.android.lib'
}

View File

@ -0,0 +1,30 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.owncloud.android.lib.common.http
import com.facebook.stetho.okhttp3.StethoInterceptor
object DebugInterceptorFactory {
fun getInterceptor() = StethoInterceptor()
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- ownCloud Android Library is available under MIT license <!-- ownCloud Android Library is available under MIT license
Copyright (C) 2015 ownCloud Inc. Copyright (C) 2023 ownCloud GmbH.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@ -22,9 +22,10 @@
THE SOFTWARE. THE SOFTWARE.
--> -->
<resources>
<string name="app_name">Oc_framework-testTest</string> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
</resources>

View File

@ -0,0 +1,221 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2016 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common
import android.accounts.AccountManager
import android.accounts.AccountsException
import android.content.Context
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.resources.files.CheckPathExistenceRemoteOperation
import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation
import com.owncloud.android.lib.resources.status.RemoteServerInfo
import org.apache.commons.lang3.exception.ExceptionUtils
import timber.log.Timber
import java.io.IOException
/**
* ConnectionValidator
*
* @author Christian Schabesberger
*/
class ConnectionValidator(
val context: Context,
private val clearCookiesOnValidation: Boolean
) {
fun validate(baseClient: OwnCloudClient, singleSessionManager: SingleSessionManager, context: Context): Boolean {
try {
var validationRetryCount = 0
val client = OwnCloudClient(baseClient.baseUri, null, false, singleSessionManager, context)
if (clearCookiesOnValidation) {
client.clearCookies()
} else {
client.cookiesForBaseUri = baseClient.cookiesForBaseUri
}
client.account = baseClient.account
client.credentials = baseClient.credentials
while (validationRetryCount < VALIDATION_RETRY_COUNT) {
Timber.d("validationRetryCount %d", validationRetryCount)
var successCounter = 0
var failCounter = 0
client.setFollowRedirects(true)
if (isOwnCloudStatusOk(client)) {
successCounter++
} else {
failCounter++
}
// Skip the part where we try to check if we can access the parts where we have to be logged in... if we are not logged in
if (baseClient.credentials !is OwnCloudAnonymousCredentials) {
client.setFollowRedirects(false)
val contentReply = canAccessRootFolder(client)
if (contentReply.httpCode == HttpConstants.HTTP_OK) {
if (contentReply.data == true) { //if data is true it means that the content reply was ok
successCounter++
} else {
failCounter++
}
} else {
failCounter++
if (contentReply.httpCode == HttpConstants.HTTP_UNAUTHORIZED) {
checkUnauthorizedAccess(client, singleSessionManager, contentReply.httpCode)
}
}
}
if (successCounter >= failCounter) {
baseClient.credentials = client.credentials
baseClient.cookiesForBaseUri = client.cookiesForBaseUri
return true
}
validationRetryCount++
}
Timber.d("Could not authenticate or get valid data from owncloud")
} catch (e: Exception) {
Timber.d(ExceptionUtils.getStackTrace(e))
}
return false
}
private fun isOwnCloudStatusOk(client: OwnCloudClient): Boolean {
val reply = getOwnCloudStatus(client)
// dont check status code. It currently relais on the broken redirect code of the owncloud client
// TODO: Use okhttp redirect and add this check again
// return reply.httpCode == HttpConstants.HTTP_OK &&
return !reply.isException &&
reply.data != null
}
private fun getOwnCloudStatus(client: OwnCloudClient): RemoteOperationResult<RemoteServerInfo> {
val remoteStatusOperation = GetRemoteStatusOperation()
return remoteStatusOperation.execute(client)
}
private fun canAccessRootFolder(client: OwnCloudClient): RemoteOperationResult<Boolean> {
val checkPathExistenceRemoteOperation = CheckPathExistenceRemoteOperation("/", true)
return checkPathExistenceRemoteOperation.execute(client)
}
/**
* Determines if credentials should be invalidated according the to the HTTPS status
* of a network request just performed.
*
* @param httpStatusCode Result of the last request ran with the 'credentials' belows.
* @return 'True' if credentials should and might be invalidated, 'false' if shouldn't or
* cannot be invalidated with the given arguments.
*/
private fun shouldInvalidateAccountCredentials(credentials: OwnCloudCredentials, account: OwnCloudAccount, httpStatusCode: Int): Boolean {
var shouldInvalidateAccountCredentials = httpStatusCode == HttpConstants.HTTP_UNAUTHORIZED
shouldInvalidateAccountCredentials = shouldInvalidateAccountCredentials and // real credentials
(credentials !is OwnCloudAnonymousCredentials)
// test if have all the needed to effectively invalidate ...
shouldInvalidateAccountCredentials =
shouldInvalidateAccountCredentials and (account.savedAccount != null)
Timber.d(
"""Received error: $httpStatusCode,
account: ${account.name}
credentials are real: ${credentials !is OwnCloudAnonymousCredentials},
so we need to invalidate credentials for account ${account.name} : $shouldInvalidateAccountCredentials"""
)
return shouldInvalidateAccountCredentials
}
/**
* Invalidates credentials stored for the given account in the system [AccountManager] and in
* current [SingleSessionManager.getDefaultSingleton] instance.
*
*
* [.shouldInvalidateAccountCredentials] should be called first.
*
*/
private fun invalidateAccountCredentials(account: OwnCloudAccount, credentials: OwnCloudCredentials) {
Timber.i("Invalidating account credentials for account $account")
val am = AccountManager.get(context)
am.invalidateAuthToken(
account.savedAccount.type,
credentials.authToken
)
am.clearPassword(account.savedAccount) // being strict, only needed for Basic Auth credentials
}
/**
* Checks the status code of an execution and decides if should be repeated with fresh credentials.
*
*
* Invalidates current credentials if the request failed as anauthorized.
*
*
* Refresh current credentials if possible, and marks a retry.
*
* @return
*/
private fun checkUnauthorizedAccess(client: OwnCloudClient, singleSessionManager: SingleSessionManager, status: Int): Boolean {
var credentialsWereRefreshed = false
val account = client.account
val credentials = account.credentials
if (shouldInvalidateAccountCredentials(credentials, account, status)) {
invalidateAccountCredentials(account, credentials)
if (credentials.authTokenCanBeRefreshed()) {
try {
// This command does the actual refresh
Timber.i("Trying to refresh auth token for account $account")
account.loadCredentials(context)
// if mAccount.getCredentials().length() == 0 --> refresh failed
client.credentials = account.credentials
credentialsWereRefreshed = true
} catch (e: AccountsException) {
Timber.e(
e, "Error while trying to refresh auth token for %s\ntrace: %s",
account.savedAccount.name,
ExceptionUtils.getStackTrace(e)
)
} catch (e: IOException) {
Timber.e(
e, "Error while trying to refresh auth token for %s\ntrace: %s",
account.savedAccount.name,
ExceptionUtils.getStackTrace(e)
)
}
if (!credentialsWereRefreshed) {
// if credentials are not refreshed, client must be removed
// from the OwnCloudClientManager to prevent it is reused once and again
Timber.w("Credentials were not refreshed, client will be removed from the Session Manager to prevent using it over and over")
singleSessionManager.removeClientFor(account)
}
}
// else: onExecute will finish with status 401
}
return credentialsWereRefreshed
}
companion object {
private const val VALIDATION_RETRY_COUNT = 3
}
}

View File

@ -1,5 +1,5 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -24,37 +24,40 @@
package com.owncloud.android.lib.common; package com.owncloud.android.lib.common;
import java.io.IOException;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
import android.accounts.Account; import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorException; import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException; import android.accounts.OperationCanceledException;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
import java.io.IOException;
/** /**
* OwnCloud Account * OwnCloud Account
* *
* @author David A. Velasco * @author David A. Velasco
*/ */
public class OwnCloudAccount { public class OwnCloudAccount {
private Uri mBaseUri; private Uri mBaseUri;
private OwnCloudCredentials mCredentials; private OwnCloudCredentials mCredentials;
private String mDisplayName;
private String mSavedAccountName; private String mSavedAccountName;
private Account mSavedAccount; private Account mSavedAccount;
/** /**
* Constructor for already saved OC accounts. * Constructor for already saved OC accounts.
* * <p>
* Do not use for anonymous credentials. * Do not use for anonymous credentials.
*/ */
public OwnCloudAccount(Account savedAccount, Context context) throws AccountNotFoundException { public OwnCloudAccount(Account savedAccount, Context context) throws AccountNotFoundException {
@ -68,58 +71,22 @@ public class OwnCloudAccount {
mSavedAccount = savedAccount; mSavedAccount = savedAccount;
mSavedAccountName = savedAccount.name; mSavedAccountName = savedAccount.name;
mCredentials = null; // load of credentials is delayed
AccountManager ama = AccountManager.get(context.getApplicationContext());
String baseUrl = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_OC_BASE_URL);
if (baseUrl == null) {
throw new AccountNotFoundException(mSavedAccount, "Account not found", null);
}
mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, mSavedAccount)); mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, mSavedAccount));
mCredentials = null; mDisplayName = ama.getUserData(mSavedAccount, AccountUtils.Constants.KEY_DISPLAY_NAME);
} }
/**
* Method for deferred load of account attributes from AccountManager
*
* @param context
* @throws AccountNotFoundException
* @throws AuthenticatorException
* @throws IOException
* @throws OperationCanceledException
*/
public void loadCredentials(Context context)
throws AccountNotFoundException, AuthenticatorException,
IOException, OperationCanceledException {
if (context == null) {
throw new IllegalArgumentException("Parameter 'context' cannot be null");
}
if (mSavedAccount != null) {
mCredentials = AccountUtils.getCredentialsForAccount(context, mSavedAccount);
}
}
/*
public OwnCloudAccount(Account savedAccount, Context context)
throws AccountNotFoundException, AuthenticatorException,
IOException, OperationCanceledException {
if (savedAccount == null) {
throw new IllegalArgumentException("Parameter 'savedAccount' cannot be null");
}
if (context == null) {
throw new IllegalArgumentException("Parameter 'context' cannot be null");
}
mSavedAccountName = savedAccount.name;
mBaseUri = Uri.parse(AccountUtils.getBaseUrlForAccount(context, savedAccount));
mCredentials = AccountUtils.getCredentialsForAccount(context, savedAccount);
if (mCredentials == null) {
mCredentials = OwnCloudCredentialsFactory.getAnonymousCredentials();
}
}
*/
/** /**
* Constructor for non yet saved OC accounts. * Constructor for non yet saved OC accounts.
* *
* @param baseUri URI to the OC server to get access to. * @param baseUri URI to the OC server to get access to.
* @param credentials Credentials to authenticate in the server. NULL is valid for anonymous credentials. * @param credentials Credentials to authenticate in the server. NULL is valid for anonymous credentials.
*/ */
public OwnCloudAccount(Uri baseUri, OwnCloudCredentials credentials) { public OwnCloudAccount(Uri baseUri, OwnCloudCredentials credentials) {
if (baseUri == null) { if (baseUri == null) {
@ -128,30 +95,58 @@ public class OwnCloudAccount {
mSavedAccount = null; mSavedAccount = null;
mSavedAccountName = null; mSavedAccountName = null;
mBaseUri = baseUri; mBaseUri = baseUri;
mCredentials = credentials != null ? mCredentials = credentials != null ?
credentials : OwnCloudCredentialsFactory.getAnonymousCredentials(); credentials : OwnCloudCredentialsFactory.getAnonymousCredentials();
String username = mCredentials.getUsername(); String username = mCredentials.getUsername();
if (username != null) { if (username != null) {
mSavedAccountName = AccountUtils.buildAccountName(mBaseUri, username); mSavedAccountName = AccountUtils.buildAccountName(mBaseUri, username);
}
}
/**
* Method for deferred load of account attributes from AccountManager
*
* @param context
* @throws AuthenticatorException
* @throws IOException
* @throws OperationCanceledException
*/
public void loadCredentials(Context context) throws AuthenticatorException, IOException, OperationCanceledException {
if (context == null) {
throw new IllegalArgumentException("Parameter 'context' cannot be null");
}
if (mSavedAccount != null) {
mCredentials = AccountUtils.getCredentialsForAccount(context, mSavedAccount);
} }
} }
public boolean isAnonymous() {
return (mCredentials == null);
} // TODO no more
public Uri getBaseUri() { public Uri getBaseUri() {
return mBaseUri; return mBaseUri;
} }
public OwnCloudCredentials getCredentials() { public OwnCloudCredentials getCredentials() {
return mCredentials; return mCredentials;
} }
public String getName() { public String getName() {
return mSavedAccountName; return mSavedAccountName;
} }
public Account getSavedAccount() {
return mSavedAccount;
}
public String getDisplayName() {
if (mDisplayName != null && mDisplayName.length() > 0) {
return mDisplayName;
} else if (mCredentials != null) {
return mCredentials.getUsername();
} else if (mSavedAccount != null) {
return AccountUtils.getUsernameForAccount(mSavedAccount);
} else {
return null;
}
}
} }

View File

@ -0,0 +1,255 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
* Copyright (C) 2012 Bartek Przybylski
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common;
import android.content.Context;
import android.net.Uri;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials;
import com.owncloud.android.lib.common.http.HttpClient;
import com.owncloud.android.lib.common.http.HttpConstants;
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
import com.owncloud.android.lib.common.utils.RandomUtils;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
import timber.log.Timber;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Locale;
import static com.owncloud.android.lib.common.http.HttpConstants.AUTHORIZATION_HEADER;
import static com.owncloud.android.lib.common.http.HttpConstants.HTTP_MOVED_PERMANENTLY;
public class OwnCloudClient extends HttpClient {
public static final String WEBDAV_FILES_PATH_4_0 = "/remote.php/dav/files/";
public static final String STATUS_PATH = "/status.php";
private static final String WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/";
private static final int MAX_RETRY_COUNT = 2;
private static int sIntanceCounter = 0;
private OwnCloudCredentials mCredentials = null;
private int mInstanceNumber;
private Uri mBaseUri;
private OwnCloudAccount mAccount;
private final ConnectionValidator mConnectionValidator;
private Object mRequestMutex = new Object();
// If set to true a mutex will be used to prevent parallel execution of the execute() method
// if false the execute() method can be called even though the mutex is already aquired.
// This is used for the ConnectionValidator, which has to be able to execute OperationsWhile all "normal" operations net
// to be set on hold.
private final Boolean mSynchronizeRequests;
private SingleSessionManager mSingleSessionManager = null;
private boolean mFollowRedirects = false;
public OwnCloudClient(Uri baseUri,
ConnectionValidator connectionValidator,
boolean synchronizeRequests,
SingleSessionManager singleSessionManager,
Context context) {
super(context);
if (baseUri == null) {
throw new IllegalArgumentException("Parameter 'baseUri' cannot be NULL");
}
mBaseUri = baseUri;
mSynchronizeRequests = synchronizeRequests;
mSingleSessionManager = singleSessionManager;
mInstanceNumber = sIntanceCounter++;
Timber.d("#" + mInstanceNumber + "Creating OwnCloudClient");
clearCredentials();
clearCookies();
mConnectionValidator = connectionValidator;
}
public void clearCredentials() {
if (!(mCredentials instanceof OwnCloudAnonymousCredentials)) {
mCredentials = OwnCloudCredentialsFactory.getAnonymousCredentials();
}
}
public int executeHttpMethod(HttpBaseMethod method) throws Exception {
if (mSynchronizeRequests) {
synchronized (mRequestMutex) {
return saveExecuteHttpMethod(method);
}
} else {
return saveExecuteHttpMethod(method);
}
}
private int saveExecuteHttpMethod(HttpBaseMethod method) throws Exception {
int repeatCounter = 0;
int status;
if (mFollowRedirects) {
method.setFollowRedirects(true);
}
boolean retry;
do {
repeatCounter++;
retry = false;
String requestId = RandomUtils.generateRandomUUID();
// Header to allow tracing requests in apache and ownCloud logs
Timber.d("Executing in request with id %s", requestId);
method.setRequestHeader(HttpConstants.OC_X_REQUEST_ID, requestId);
method.setRequestHeader(HttpConstants.USER_AGENT_HEADER, SingleSessionManager.getUserAgent());
method.setRequestHeader(HttpConstants.ACCEPT_LANGUAGE_HEADER, Locale.getDefault().getLanguage());
method.setRequestHeader(HttpConstants.ACCEPT_ENCODING_HEADER, HttpConstants.ACCEPT_ENCODING_IDENTITY);
if (mCredentials.getHeaderAuth() != null && !mCredentials.getHeaderAuth().isEmpty()) {
method.setRequestHeader(AUTHORIZATION_HEADER, mCredentials.getHeaderAuth());
}
status = method.execute(this);
if (shouldConnectionValidatorBeCalled(method, status)) {
retry = mConnectionValidator.validate(this, mSingleSessionManager, getContext()); // retry on success fail on no success
} else if (method.getFollowPermanentRedirects() && status == HTTP_MOVED_PERMANENTLY) {
retry = true;
method.setFollowRedirects(true);
}
} while (retry && repeatCounter < MAX_RETRY_COUNT);
return status;
}
private boolean shouldConnectionValidatorBeCalled(HttpBaseMethod method, int status) {
return mConnectionValidator != null && (
(!(mCredentials instanceof OwnCloudAnonymousCredentials) &&
status == HttpConstants.HTTP_UNAUTHORIZED
) || (!mFollowRedirects &&
!method.getFollowRedirects() &&
status == HttpConstants.HTTP_MOVED_TEMPORARILY
)
);
}
/**
* Exhausts a not interesting HTTP response. Encouraged by HttpClient documentation.
*
* @param responseBodyAsStream InputStream with the HTTP response to exhaust.
*/
public void exhaustResponse(InputStream responseBodyAsStream) {
if (responseBodyAsStream != null) {
try {
responseBodyAsStream.close();
} catch (IOException io) {
Timber.e(io, "Unexpected exception while exhausting not interesting HTTP response; will be IGNORED");
}
}
}
public Uri getBaseFilesWebDavUri() {
return Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0);
}
public Uri getUserFilesWebDavUri() {
return (mCredentials instanceof OwnCloudAnonymousCredentials || mAccount == null)
? Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0)
: Uri.parse(mBaseUri + WEBDAV_FILES_PATH_4_0 + AccountUtils.getUserId(
mAccount.getSavedAccount(), getContext()
)
);
}
public Uri getUploadsWebDavUri() {
return mCredentials instanceof OwnCloudAnonymousCredentials
? Uri.parse(mBaseUri + WEBDAV_UPLOADS_PATH_4_0)
: Uri.parse(mBaseUri + WEBDAV_UPLOADS_PATH_4_0 + AccountUtils.getUserId(
mAccount.getSavedAccount(), getContext()
)
);
}
public Uri getBaseUri() {
return mBaseUri;
}
/**
* Sets the root URI to the ownCloud server.
* <p>
* Use with care.
*
* @param uri
*/
public void setBaseUri(Uri uri) {
if (uri == null) {
throw new IllegalArgumentException("URI cannot be NULL");
}
mBaseUri = uri;
}
public final OwnCloudCredentials getCredentials() {
return mCredentials;
}
public void setCredentials(OwnCloudCredentials credentials) {
if (credentials != null) {
mCredentials = credentials;
} else {
clearCredentials();
}
}
public void setCookiesForBaseUri(List<Cookie> cookies) {
getOkHttpClient().cookieJar().saveFromResponse(
HttpUrl.parse(mBaseUri.toString()),
cookies
);
}
public List<Cookie> getCookiesForBaseUri() {
return getOkHttpClient().cookieJar().loadForRequest(
HttpUrl.parse(mBaseUri.toString()));
}
public OwnCloudAccount getAccount() {
return mAccount;
}
public void setAccount(OwnCloudAccount account) {
this.mAccount = account;
}
public void setFollowRedirects(boolean followRedirects) {
this.mFollowRedirects = followRedirects;
}
}

View File

@ -0,0 +1,225 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.net.Uri;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
import timber.log.Timber;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author David A. Velasco
* @author masensio
* @author Christian Schabesberger
* @author David González Verdugo
*/
public class SingleSessionManager {
private static SingleSessionManager sDefaultSingleton;
private static String sUserAgent;
private static ConnectionValidator sConnectionValidator;
private ConcurrentMap<String, OwnCloudClient> mClientsWithKnownUsername = new ConcurrentHashMap<>();
private ConcurrentMap<String, OwnCloudClient> mClientsWithUnknownUsername = new ConcurrentHashMap<>();
public static SingleSessionManager getDefaultSingleton() {
if (sDefaultSingleton == null) {
sDefaultSingleton = new SingleSessionManager();
}
return sDefaultSingleton;
}
public static void setConnectionValidator(ConnectionValidator connectionValidator) {
sConnectionValidator = connectionValidator;
}
public static ConnectionValidator getConnectionValidator() {
return sConnectionValidator;
}
public static String getUserAgent() {
return sUserAgent;
}
public static void setUserAgent(String userAgent) {
sUserAgent = userAgent;
}
private static OwnCloudClient createOwnCloudClient(Uri uri,
Context context,
ConnectionValidator connectionValidator,
SingleSessionManager singleSessionManager) {
OwnCloudClient client = new OwnCloudClient(uri, connectionValidator, true, singleSessionManager, context);
return client;
}
public OwnCloudClient getClientFor(OwnCloudAccount account,
Context context) throws OperationCanceledException,
AuthenticatorException, IOException {
return getClientFor(account, context, getConnectionValidator());
}
public OwnCloudClient getClientFor(OwnCloudAccount account,
Context context,
ConnectionValidator connectionValidator) throws OperationCanceledException,
AuthenticatorException, IOException {
Timber.d("getClientFor starting ");
if (account == null) {
throw new IllegalArgumentException("Cannot get an OwnCloudClient for a null account");
}
OwnCloudClient client = null;
String accountName = account.getName();
String sessionName = account.getCredentials() == null ? "" :
AccountUtils.buildAccountName(account.getBaseUri(), account.getCredentials().getAuthToken());
if (accountName != null) {
client = mClientsWithKnownUsername.get(accountName);
}
boolean reusingKnown = false; // just for logs
if (client == null) {
if (accountName != null) {
client = mClientsWithUnknownUsername.remove(sessionName);
if (client != null) {
Timber.v("reusing client for session %s", sessionName);
mClientsWithKnownUsername.put(accountName, client);
Timber.v("moved client to account %s", accountName);
}
} else {
client = mClientsWithUnknownUsername.get(sessionName);
}
} else {
Timber.v("reusing client for account %s", accountName);
if (client.getAccount() != null &&
client.getAccount().getCredentials() != null &&
(client.getAccount().getCredentials().getAuthToken() == null || client.getAccount().getCredentials().getAuthToken().isEmpty())
) {
Timber.i("Client " + client.getAccount().getName() + " needs to refresh credentials");
//the next two lines are a hack because okHttpclient is used as a singleton instead of being an
//injected instance that can be deleted when required
client.clearCookies();
client.clearCredentials();
client.setAccount(account);
account.loadCredentials(context);
client.setCredentials(account.getCredentials());
Timber.i("Client " + account.getName() + " with credentials size" + client.getAccount().getCredentials().getAuthToken().length());
}
reusingKnown = true;
}
if (client == null) {
// no client to reuse - create a new one
client = createOwnCloudClient(
account.getBaseUri(),
context,
connectionValidator,
this); // TODO remove dependency on OwnCloudClientFactory
//the next two lines are a hack because okHttpclient is used as a singleton instead of being an
//injected instance that can be deleted when required
client.clearCookies();
client.clearCredentials();
client.setAccount(account);
account.loadCredentials(context);
client.setCredentials(account.getCredentials());
if (accountName != null) {
mClientsWithKnownUsername.put(accountName, client);
Timber.v("new client for account %s", accountName);
} else {
mClientsWithUnknownUsername.put(sessionName, client);
Timber.v("new client for session %s", sessionName);
}
} else {
if (!reusingKnown) {
Timber.v("reusing client for session %s", sessionName);
}
keepUriUpdated(account, client);
}
Timber.d("getClientFor finishing ");
return client;
}
public void removeClientFor(OwnCloudAccount account) {
Timber.d("removeClientFor starting ");
if (account == null) {
return;
}
OwnCloudClient client;
String accountName = account.getName();
if (accountName != null) {
client = mClientsWithKnownUsername.remove(accountName);
if (client != null) {
Timber.v("Removed client for account %s", accountName);
return;
} else {
Timber.v("No client tracked for account %s", accountName);
}
}
mClientsWithUnknownUsername.clear();
Timber.d("removeClientFor finishing ");
}
public void refreshCredentialsForAccount(String accountName, OwnCloudCredentials credentials) {
OwnCloudClient ownCloudClient = mClientsWithKnownUsername.get(accountName);
if (ownCloudClient == null) {
return;
}
ownCloudClient.setCredentials(credentials);
mClientsWithKnownUsername.replace(accountName, ownCloudClient);
}
// this method is just a patch; we need to distinguish accounts in the same host but
// different paths; but that requires updating the accountNames for apps upgrading
private void keepUriUpdated(OwnCloudAccount account, OwnCloudClient reusedClient) {
Uri recentUri = account.getBaseUri();
if (!recentUri.equals(reusedClient.getBaseUri())) {
reusedClient.setBaseUri(recentUri);
}
}
}

View File

@ -1,22 +1,22 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2020 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
@ -33,17 +33,12 @@ public class AccountTypeUtils {
public static String getAuthTokenTypePass(String accountType) { public static String getAuthTokenTypePass(String accountType) {
return accountType + ".password"; return accountType + ".password";
} }
public static String getAuthTokenTypeAccessToken(String accountType) { public static String getAuthTokenTypeAccessToken(String accountType) {
return accountType + ".oauth2.access_token"; return accountType + ".oauth2.access_token";
} }
public static String getAuthTokenTypeRefreshToken(String accountType) { public static String getAuthTokenTypeRefreshToken(String accountType) {
return accountType + ".oauth2.refresh_token"; return accountType + ".oauth2.refresh_token";
} }
public static String getAuthTokenTypeSamlSessionCookie(String accountType) {
return accountType + ".saml.web_sso.session_cookie";
}
} }

View File

@ -0,0 +1,224 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
* Copyright (C) 2012 Bartek Przybylski
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.accounts;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountsException;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.net.Uri;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
import timber.log.Timber;
import java.io.IOException;
public class AccountUtils {
/**
* Constructs full url to host and webdav resource basing on host version
*
* @param context Valid Android {@link Context}, needed to access the {@link AccountManager}
* @param account A stored ownCloud {@link Account}
* @return Full URL to WebDAV endpoint in the server corresponding to 'account'.
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
*/
public static String getWebDavUrlForAccount(Context context, Account account)
throws AccountNotFoundException {
return getBaseUrlForAccount(context, account) + OwnCloudClient.WEBDAV_FILES_PATH_4_0
+ AccountUtils.getUserId(account, context);
}
/**
* Extracts url server from the account
*
* @param context Valid Android {@link Context}, needed to access the {@link AccountManager}
* @param account A stored ownCloud {@link Account}
* @return Full URL to the server corresponding to 'account', ending in the base path
* common to all API endpoints.
* @throws AccountNotFoundException When 'account' is unknown for the AccountManager
*/
public static String getBaseUrlForAccount(Context context, Account account)
throws AccountNotFoundException {
AccountManager ama = AccountManager.get(context.getApplicationContext());
String baseurl = ama.getUserData(account, Constants.KEY_OC_BASE_URL);
if (baseurl == null) {
throw new AccountNotFoundException(account, "Account not found", null);
}
return baseurl;
}
/**
* Get the username corresponding to an OC account.
*
* @param account An OC account
* @return Username for the given account, extracted from the account.name
*/
public static String getUsernameForAccount(Account account) {
String username = null;
try {
username = account.name.substring(0, account.name.lastIndexOf('@'));
} catch (Exception e) {
Timber.e(e, "Couldn't get a username for the given account");
}
return username;
}
/**
* @return
* @throws IOException
* @throws AuthenticatorException
* @throws OperationCanceledException
*/
public static OwnCloudCredentials getCredentialsForAccount(Context context, Account account)
throws OperationCanceledException, AuthenticatorException, IOException {
OwnCloudCredentials credentials;
AccountManager am = AccountManager.get(context);
String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2);
boolean isOauth2 = supportsOAuth2 != null && supportsOAuth2.equals(Constants.OAUTH_SUPPORTED_TRUE);
String username = AccountUtils.getUsernameForAccount(account);
if (isOauth2) {
Timber.i("Trying to retrieve credentials for oAuth account" + account.name);
String accessToken = am.blockingGetAuthToken(
account,
AccountTypeUtils.getAuthTokenTypeAccessToken(account.type),
false);
credentials = OwnCloudCredentialsFactory.newBearerCredentials(username, accessToken);
} else {
String password = am.blockingGetAuthToken(
account,
AccountTypeUtils.getAuthTokenTypePass(account.type),
false);
credentials = OwnCloudCredentialsFactory.newBasicCredentials(
username,
password
);
}
return credentials;
}
/**
* Get the user id corresponding to an OC account.
*
* @param account ownCloud account
* @return user id
*/
public static String getUserId(Account account, Context context) {
AccountManager accountMgr = AccountManager.get(context);
return accountMgr.getUserData(account, Constants.KEY_ID);
}
public static String buildAccountNameOld(Uri serverBaseUrl, String username) {
if (serverBaseUrl.getScheme() == null) {
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
}
String accountName = username + "@" + serverBaseUrl.getHost();
if (serverBaseUrl.getPort() >= 0) {
accountName += ":" + serverBaseUrl.getPort();
}
return accountName;
}
public static String buildAccountName(Uri serverBaseUrl, String username) {
if (serverBaseUrl.getScheme() == null) {
serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
}
// Remove http:// or https://
String url = serverBaseUrl.toString();
if (url.contains("://")) {
url = url.substring(serverBaseUrl.toString().indexOf("://") + 3);
}
return username + "@" + url;
}
public static class AccountNotFoundException extends AccountsException {
/**
* Generated - should be refreshed every time the class changes!!
*/
private static final long serialVersionUID = -1684392454798508693L;
private Account mFailedAccount;
public AccountNotFoundException(Account failedAccount, String message, Throwable cause) {
super(message, cause);
mFailedAccount = failedAccount;
}
public Account getFailedAccount() {
return mFailedAccount;
}
}
public static class Constants {
/**
* Base url should point to owncloud installation without trailing / ie:
* http://server/path or https://owncloud.server
*/
public static final String KEY_OC_BASE_URL = "oc_base_url";
/**
* Flag signaling if the ownCloud server can be accessed with OAuth2 access tokens.
*/
// TODO Please review this constants, move them out of the library, the rest of OAuth variables are in data layer
public static final String KEY_SUPPORTS_OAUTH2 = "oc_supports_oauth2";
public static final String OAUTH_SUPPORTED_TRUE = "TRUE";
/**
* OC account version
*/
public static final String KEY_OC_ACCOUNT_VERSION = "oc_account_version";
/**
* User's id
*/
public static final String KEY_ID = "oc_id";
/**
* User's display name
*/
public static final String KEY_DISPLAY_NAME = "oc_display_name";
public static final int ACCOUNT_VERSION = 1;
}
}

View File

@ -1,5 +1,5 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2020 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -21,51 +21,44 @@
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
package com.owncloud.android.lib.common; package com.owncloud.android.lib.common.authentication;
import java.util.ArrayList; import okhttp3.Credentials;
import java.util.List;
import org.apache.commons.httpclient.UsernamePasswordCredentials; import static java.nio.charset.StandardCharsets.UTF_8;
import org.apache.commons.httpclient.auth.AuthPolicy;
import org.apache.commons.httpclient.auth.AuthScope;
public class OwnCloudBasicCredentials implements OwnCloudCredentials { public class OwnCloudBasicCredentials implements OwnCloudCredentials {
private String mUsername; private String mUsername;
private String mPassword; private String mPassword;
public OwnCloudBasicCredentials(String username, String password) { public OwnCloudBasicCredentials(String username, String password) {
mUsername = username != null ? username : ""; mUsername = username != null ? username : "";
mPassword = password != null ? password : ""; mPassword = password != null ? password : "";
} }
@Override @Override
public void applyTo(OwnCloudClient client) { public String getUsername() {
List<String> authPrefs = new ArrayList<String>(1); return mUsername;
authPrefs.add(AuthPolicy.BASIC); }
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(
AuthScope.ANY,
new UsernamePasswordCredentials(mUsername, mPassword)
);
}
@Override @Override
public String getUsername() { public String getAuthToken() {
return mUsername; return mPassword;
} }
@Override @Override
public String getAuthToken() { public String getHeaderAuth() {
return mPassword; return Credentials.basic(mUsername, mPassword, UTF_8);
} }
@Override @Override
public boolean authTokenExpires() { public boolean authTokenExpires() {
return false; return false;
} }
} @Override
public boolean authTokenCanBeRefreshed() {
return false;
}
}

View File

@ -0,0 +1,63 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.authentication;
import com.owncloud.android.lib.common.http.HttpConstants;
public class OwnCloudBearerCredentials implements OwnCloudCredentials {
private String mUsername;
private String mAccessToken;
public OwnCloudBearerCredentials(String username, String accessToken) {
mUsername = username != null ? username : "";
mAccessToken = accessToken != null ? accessToken : "";
}
@Override
public String getUsername() {
// not relevant for authentication, but relevant for informational purposes
return mUsername;
}
@Override
public String getAuthToken() {
return mAccessToken;
}
@Override
public String getHeaderAuth() {
return HttpConstants.BEARER_AUTHORIZATION_KEY + mAccessToken;
}
@Override
public boolean authTokenExpires() {
return true;
}
@Override
public boolean authTokenCanBeRefreshed() {
return true;
}
}

View File

@ -1,5 +1,5 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -22,16 +22,17 @@
* *
*/ */
package com.owncloud.android.lib.common; package com.owncloud.android.lib.common.authentication;
public interface OwnCloudCredentials { public interface OwnCloudCredentials {
public void applyTo(OwnCloudClient ownCloudClient); String getUsername();
public String getUsername(); String getAuthToken();
public String getAuthToken(); String getHeaderAuth();
public boolean authTokenExpires(); boolean authTokenExpires();
boolean authTokenCanBeRefreshed();
} }

View File

@ -0,0 +1,79 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.authentication;
public class OwnCloudCredentialsFactory {
public static final String CREDENTIAL_CHARSET = "UTF-8";
private static OwnCloudAnonymousCredentials sAnonymousCredentials;
public static OwnCloudCredentials newBasicCredentials(String username, String password) {
return new OwnCloudBasicCredentials(username, password);
}
public static OwnCloudCredentials newBearerCredentials(String username, String authToken) {
return new OwnCloudBearerCredentials(username, authToken);
}
public static final OwnCloudCredentials getAnonymousCredentials() {
if (sAnonymousCredentials == null) {
sAnonymousCredentials = new OwnCloudAnonymousCredentials();
}
return sAnonymousCredentials;
}
public static final class OwnCloudAnonymousCredentials implements OwnCloudCredentials {
protected OwnCloudAnonymousCredentials() {
}
@Override
public String getAuthToken() {
return "";
}
@Override
public String getHeaderAuth() {
return "";
}
@Override
public boolean authTokenExpires() {
return false;
}
@Override
public boolean authTokenCanBeRefreshed() {
return false;
}
@Override
public String getUsername() {
// no user name
return null;
}
}
}

View File

@ -0,0 +1,62 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2021 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.HttpUrl
class CookieJarImpl(
private val cookieStore: HashMap<String, List<Cookie>>
) : CookieJar {
fun containsCookieWithName(cookies: List<Cookie>, name: String): Boolean {
for (cookie: Cookie in cookies) {
if (cookie.name == name) {
return true
}
}
return false
}
fun getUpdatedCookies(oldCookies: List<Cookie>, newCookies: List<Cookie>): List<Cookie> {
val updatedList = ArrayList<Cookie>(newCookies)
for (oldCookie: Cookie in oldCookies) {
if (!containsCookieWithName(updatedList, oldCookie.name)) {
updatedList.add(oldCookie)
}
}
return updatedList
}
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
// Avoid duplicated cookies but update
val currentCookies: List<Cookie> = cookieStore[url.host] ?: ArrayList()
val updatedCookies: List<Cookie> = getUpdatedCookies(currentCookies, cookies)
cookieStore[url.host] = updatedCookies
}
override fun loadForRequest(url: HttpUrl) =
cookieStore[url.host] ?: ArrayList()
}

View File

@ -0,0 +1,31 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http
import okhttp3.Interceptor
class DummyInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain) = chain.proceed(chain.request())
}

View File

@ -0,0 +1,147 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http;
import android.content.Context;
import com.owncloud.android.lib.common.network.AdvancedX509TrustManager;
import com.owncloud.android.lib.common.network.NetworkUtils;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.TlsVersion;
import timber.log.Timber;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* Client used to perform network operations
*
* @author David González Verdugo
*/
public class HttpClient {
private Context mContext;
private HashMap<String, List<Cookie>> mCookieStore = new HashMap<>();
private LogInterceptor mLogInterceptor = new LogInterceptor();
private OkHttpClient mOkHttpClient = null;
protected HttpClient(Context context) {
if (context == null) {
Timber.e("Context may not be NULL!");
throw new NullPointerException("Context may not be NULL!");
}
mContext = context;
}
public OkHttpClient getOkHttpClient() {
if (mOkHttpClient == null) {
try {
final X509TrustManager trustManager = new AdvancedX509TrustManager(
NetworkUtils.getKnownServersStore(mContext));
final SSLContext sslContext = buildSSLContext();
sslContext.init(null, new TrustManager[]{trustManager}, null);
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
// Automatic cookie handling, NOT PERSISTENT
final CookieJar cookieJar = new CookieJarImpl(mCookieStore);
mOkHttpClient = buildNewOkHttpClient(sslSocketFactory, trustManager, cookieJar);
} catch (NoSuchAlgorithmException nsae) {
Timber.e(nsae, "Could not setup SSL system.");
throw new RuntimeException("Could not setup okHttp client.", nsae);
} catch (Exception e) {
Timber.e(e, "Could not setup okHttp client.");
throw new RuntimeException("Could not setup okHttp client.", e);
}
}
return mOkHttpClient;
}
private SSLContext buildSSLContext() throws NoSuchAlgorithmException {
try {
return SSLContext.getInstance(TlsVersion.TLS_1_3.javaName());
} catch (NoSuchAlgorithmException tlsv13Exception) {
try {
Timber.w("TLSv1.3 is not supported in this device; falling through TLSv1.2");
return SSLContext.getInstance(TlsVersion.TLS_1_2.javaName());
} catch (NoSuchAlgorithmException tlsv12Exception) {
try {
Timber.w("TLSv1.2 is not supported in this device; falling through TLSv1.1");
return SSLContext.getInstance(TlsVersion.TLS_1_1.javaName());
} catch (NoSuchAlgorithmException tlsv11Exception) {
Timber.w("TLSv1.1 is not supported in this device; falling through TLSv1.0");
return SSLContext.getInstance(TlsVersion.TLS_1_0.javaName());
// should be available in any device; see reference of supported protocols in
// http://developer.android.com/reference/javax/net/ssl/SSLSocket.html
}
}
}
}
private OkHttpClient buildNewOkHttpClient(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager,
CookieJar cookieJar) {
return new OkHttpClient.Builder()
.addNetworkInterceptor(getLogInterceptor())
.addNetworkInterceptor(DebugInterceptorFactory.INSTANCE.getInterceptor())
.protocols(Collections.singletonList(Protocol.HTTP_1_1))
.readTimeout(HttpConstants.DEFAULT_DATA_TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(HttpConstants.DEFAULT_DATA_TIMEOUT, TimeUnit.MILLISECONDS)
.connectTimeout(HttpConstants.DEFAULT_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
.followRedirects(false)
.sslSocketFactory(sslSocketFactory, trustManager)
.hostnameVerifier((asdf, usdf) -> true)
.cookieJar(cookieJar)
.build();
}
public Context getContext() {
return mContext;
}
public LogInterceptor getLogInterceptor() {
return mLogInterceptor;
}
public List<Cookie> getCookiesFromUrl(HttpUrl httpUrl) {
return mCookieStore.get(httpUrl.host());
}
public void clearCookies() {
mCookieStore.clear();
}
}

View File

@ -0,0 +1,222 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http;
/**
* @author David González Verdugo
*/
public class HttpConstants {
/***********************************************************************************************************
*************************************************** HEADERS ***********************************************
***********************************************************************************************************/
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String COOKIE_HEADER = "Cookie";
public static final String BEARER_AUTHORIZATION_KEY = "Bearer ";
public static final String USER_AGENT_HEADER = "User-Agent";
public static final String IF_MATCH_HEADER = "If-Match";
public static final String IF_NONE_MATCH_HEADER = "If-None-Match";
public static final String CONTENT_TYPE_HEADER = "Content-Type";
public static final String ACCEPT_LANGUAGE_HEADER = "Accept-Language";
public static final String CONTENT_LENGTH_HEADER = "Content-Length";
public static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length";
public static final String OC_X_OC_MTIME_HEADER = "X-OC-Mtime";
public static final String OC_X_REQUEST_ID = "X-Request-ID";
public static final String LOCATION_HEADER = "Location";
public static final String LOCATION_HEADER_LOWER = "location";
public static final String CONTENT_TYPE_URLENCODED_UTF8 = "application/x-www-form-urlencoded; charset=utf-8";
public static final String ACCEPT_ENCODING_HEADER = "Accept-Encoding";
public static final String ACCEPT_ENCODING_IDENTITY = "identity";
public static final String OC_FILE_REMOTE_ID = "OC-FileId";
// OAuth
public static final String OAUTH_HEADER_AUTHORIZATION_CODE = "code";
public static final String OAUTH_HEADER_GRANT_TYPE = "grant_type";
public static final String OAUTH_HEADER_REDIRECT_URI = "redirect_uri";
public static final String OAUTH_HEADER_REFRESH_TOKEN = "refresh_token";
public static final String OAUTH_HEADER_CODE_VERIFIER = "code_verifier";
/***********************************************************************************************************
************************************************ CONTENT TYPES ********************************************
***********************************************************************************************************/
public static final String CONTENT_TYPE_XML = "application/xml";
public static final String CONTENT_TYPE_JSON = "application/json";
public static final String CONTENT_TYPE_WWW_FORM = "application/x-www-form-urlencoded";
/***********************************************************************************************************
************************************************ ARGUMENTS NAMES ********************************************
***********************************************************************************************************/
public static final String PARAM_FORMAT = "format";
/***********************************************************************************************************
************************************************ ARGUMENTS VALUES ********************************************
***********************************************************************************************************/
public static final String VALUE_FORMAT = "json";
/***********************************************************************************************************
************************************************ STATUS CODES *********************************************
***********************************************************************************************************/
/**
* 1xx Informational
*/
// 100 Continue (HTTP/1.1 - RFC 2616)
public static final int HTTP_CONTINUE = 100;
// 101 Switching Protocols (HTTP/1.1 - RFC 2616)
public static final int HTTP_SWITCHING_PROTOCOLS = 101;
// 102 Processing (WebDAV - RFC 2518)
public static final int HTTP_PROCESSING = 102;
/**
* 2xx Success
*/
// 200 OK (HTTP/1.0 - RFC 1945)
public static final int HTTP_OK = 200;
// 201 Created (HTTP/1.0 - RFC 1945)
public static final int HTTP_CREATED = 201;
// 202 Accepted (HTTP/1.0 - RFC 1945)
public static final int HTTP_ACCEPTED = 202;
// 203 Non Authoritative Information (HTTP/1.1 - RFC 2616)
public static final int HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
// 204 No Content</tt> (HTTP/1.0 - RFC 1945)
public static final int HTTP_NO_CONTENT = 204;
// 205 Reset Content</tt> (HTTP/1.1 - RFC 2616)
public static final int HTTP_RESET_CONTENT = 205;
// 206 Partial Content</tt> (HTTP/1.1 - RFC 2616)
public static final int HTTP_PARTIAL_CONTENT = 206;
//207 Multi-Status (WebDAV - RFC 2518) or 207 Partial Update OK (HTTP/1.1 - draft-ietf-http-v11-spec-rev-01?)
public static final int HTTP_MULTI_STATUS = 207;
/**
* 3xx Redirection
*/
// 300 Mutliple Choices</tt> (HTTP/1.1 - RFC 2616)
public static final int HTTP_MULTIPLE_CHOICES = 300;
// 301 Moved Permanently</tt> (HTTP/1.0 - RFC 1945)
public static final int HTTP_MOVED_PERMANENTLY = 301;
// 302 Moved Temporarily</tt> (Sometimes <tt>Found) (HTTP/1.0 - RFC 1945)
public static final int HTTP_MOVED_TEMPORARILY = 302;
// 303 See Other (HTTP/1.1 - RFC 2616)
public static final int HTTP_SEE_OTHER = 303;
// 304 Not Modified (HTTP/1.0 - RFC 1945)
public static final int HTTP_NOT_MODIFIED = 304;
// 305 Use Proxy (HTTP/1.1 - RFC 2616)
public static final int HTTP_USE_PROXY = 305;
// 307 Temporary Redirect (HTTP/1.1 - RFC 2616)
public static final int HTTP_TEMPORARY_REDIRECT = 307;
/**
* 4xx Client Error
*/
// 400 Bad Request (HTTP/1.1 - RFC 2616)
public static final int HTTP_BAD_REQUEST = 400;
// 401 Unauthorized (HTTP/1.0 - RFC 1945)
public static final int HTTP_UNAUTHORIZED = 401;
// 402 Payment Required (HTTP/1.1 - RFC 2616)
public static final int HTTP_PAYMENT_REQUIRED = 402;
// 403 Forbidden (HTTP/1.0 - RFC 1945)
public static final int HTTP_FORBIDDEN = 403;
// 404 Not Found (HTTP/1.0 - RFC 1945)
public static final int HTTP_NOT_FOUND = 404;
// 405 Method Not Allowed (HTTP/1.1 - RFC 2616)
public static final int HTTP_METHOD_NOT_ALLOWED = 405;
// 406 Not Acceptable (HTTP/1.1 - RFC 2616)
public static final int HTTP_NOT_ACCEPTABLE = 406;
// 407 Proxy Authentication Required (HTTP/1.1 - RFC 2616)
public static final int HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
// 408 Request Timeout (HTTP/1.1 - RFC 2616)
public static final int HTTP_REQUEST_TIMEOUT = 408;
// 409 Conflict (HTTP/1.1 - RFC 2616)
public static final int HTTP_CONFLICT = 409;
// 410 Gone (HTTP/1.1 - RFC 2616)
public static final int HTTP_GONE = 410;
// 411 Length Required (HTTP/1.1 - RFC 2616)
public static final int HTTP_LENGTH_REQUIRED = 411;
// 412 Precondition Failed (HTTP/1.1 - RFC 2616)
public static final int HTTP_PRECONDITION_FAILED = 412;
// 413 Request Entity Too Large (HTTP/1.1 - RFC 2616)
public static final int HTTP_REQUEST_TOO_LONG = 413;
// 414 Request-URI Too Long (HTTP/1.1 - RFC 2616)
public static final int HTTP_REQUEST_URI_TOO_LONG = 414;
// 415 Unsupported Media Type (HTTP/1.1 - RFC 2616)
public static final int HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
// 416 Requested Range Not Satisfiable (HTTP/1.1 - RFC 2616)
public static final int HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
// 417 Expectation Failed (HTTP/1.1 - RFC 2616)
public static final int HTTP_EXPECTATION_FAILED = 417;
// 419 Insufficient Space on Resource (WebDAV - draft-ietf-webdav-protocol-05?)
// or <tt>419 Proxy Reauthentication Required (HTTP/1.1 drafts?)
public static final int HTTP_INSUFFICIENT_SPACE_ON_RESOURCE = 419;
// 420 Method Failure (WebDAV - draft-ietf-webdav-protocol-05?)
public static final int HTTP_METHOD_FAILURE = 420;
// 422 Unprocessable Entity (WebDAV - RFC 2518)
public static final int HTTP_UNPROCESSABLE_ENTITY = 422;
// 423 Locked (WebDAV - RFC 2518)
public static final int HTTP_LOCKED = 423;
// 424 Failed Dependency (WebDAV - RFC 2518)
public static final int HTTP_FAILED_DEPENDENCY = 424;
public static final int HTTP_TOO_EARLY = 425;
/**
* 5xx Client Error
*/
// 500 Server Error (HTTP/1.0 - RFC 1945)
public static final int HTTP_INTERNAL_SERVER_ERROR = 500;
// 501 Not Implemented (HTTP/1.0 - RFC 1945)
public static final int HTTP_NOT_IMPLEMENTED = 501;
// 502 Bad Gateway (HTTP/1.0 - RFC 1945)
public static final int HTTP_BAD_GATEWAY = 502;
// 503 Service Unavailable (HTTP/1.0 - RFC 1945)
public static final int HTTP_SERVICE_UNAVAILABLE = 503;
// 504 Gateway Timeout (HTTP/1.1 - RFC 2616)
public static final int HTTP_GATEWAY_TIMEOUT = 504;
// 505 HTTP Version Not Supported (HTTP/1.1 - RFC 2616)
public static final int HTTP_HTTP_VERSION_NOT_SUPPORTED = 505;
// 507 Insufficient Storage (WebDAV - RFC 2518)
public static final int HTTP_INSUFFICIENT_STORAGE = 507;
/***********************************************************************************************************
*************************************************** TIMEOUTS **********************************************
***********************************************************************************************************/
/**
* Default timeout for waiting data from the server
*/
public static final int DEFAULT_DATA_TIMEOUT = 60000;
/**
* Default timeout for establishing a connection
*/
public static final int DEFAULT_CONNECTION_TIMEOUT = 60000;
}

View File

@ -0,0 +1,65 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.owncloud.android.lib.common.http
import com.owncloud.android.lib.common.http.HttpConstants.CONTENT_TYPE_JSON
import com.owncloud.android.lib.common.http.HttpConstants.CONTENT_TYPE_WWW_FORM
import com.owncloud.android.lib.common.http.HttpConstants.CONTENT_TYPE_XML
import okhttp3.MediaType
import timber.log.Timber
import java.util.Locale
object LogBuilder {
fun logHttp(
networkPetition: NetworkPetition,
networkNode: NetworkNode,
requestId: String? = "",
description: String
) = Timber.d("[Network, $networkPetition] [$networkNode] [$requestId] $description")
}
enum class NetworkPetition {
REQUEST, RESPONSE;
override fun toString(): String = super.toString().lowercase(Locale.ROOT)
}
enum class NetworkNode {
INFO, HEADER, BODY;
override fun toString(): String = super.toString().lowercase(Locale.ROOT)
}
/**
* Check whether a media type is loggable.
*
* @return true if its type is text, xml, json, or x-www-form-urlencoded.
*/
fun MediaType?.isLoggable(): Boolean =
this?.let { mediaType ->
val mediaTypeString = mediaType.toString()
(mediaType.type == "text" ||
mediaTypeString.contains(CONTENT_TYPE_XML) ||
mediaTypeString.contains(CONTENT_TYPE_JSON) ||
mediaTypeString.contains(CONTENT_TYPE_WWW_FORM))
} ?: false

View File

@ -0,0 +1,179 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http
import com.owncloud.android.lib.common.http.HttpConstants.AUTHORIZATION_HEADER
import com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID
import com.owncloud.android.lib.common.http.LogBuilder.logHttp
import com.owncloud.android.lib.common.http.NetworkNode.BODY
import com.owncloud.android.lib.common.http.NetworkNode.HEADER
import com.owncloud.android.lib.common.http.NetworkNode.INFO
import com.owncloud.android.lib.common.http.NetworkPetition.REQUEST
import com.owncloud.android.lib.common.http.NetworkPetition.RESPONSE
import okhttp3.Headers
import okhttp3.Interceptor
import okhttp3.RequestBody
import okhttp3.Response
import okhttp3.ResponseBody
import okio.Buffer
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import kotlin.math.max
class LogInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
if (!httpLogsEnabled) {
return chain.proceed(chain.request())
}
val request = chain.request().also {
val requestId = it.headers[OC_X_REQUEST_ID]
logHttp(REQUEST, INFO, requestId, "Method: ${it.method} URL: ${it.url}")
logHeaders(requestId, it.headers, REQUEST)
logRequestBody(requestId, it.body)
}
val response = chain.proceed(request)
return response.also {
val requestId = it.request.headers[OC_X_REQUEST_ID]
logHttp(
RESPONSE,
INFO,
requestId,
"Method: ${request.method} URL: ${request.url} Code: ${it.code} Message: ${it.message}"
)
logHeaders(requestId, it.headers, RESPONSE)
logResponseBody(requestId, it.body)
}
}
private fun logHeaders(requestId: String?, headers: Headers, networkPetition: NetworkPetition) {
headers.forEach { header ->
val headerValue: String = if (header.first.equals(AUTHORIZATION_HEADER, true)) {
"[redacted]"
} else {
header.second
}
logHttp(networkPetition, HEADER, requestId, "${header.first}: $headerValue")
}
}
private fun logRequestBody(requestId: String?, requestBodyParam: RequestBody?) {
requestBodyParam?.let { requestBody ->
if (requestBody.isOneShot()) {
logHttp(REQUEST, BODY, requestId, "One shot body -- Omitted")
return@let
}
if (requestBody.isDuplex()) {
logHttp(REQUEST, BODY, requestId, "Duplex body -- Omitted")
return@let
}
val buffer = Buffer()
requestBody.writeTo(buffer)
val contentType = requestBody.contentType()
val charset: Charset = contentType?.charset(StandardCharsets.UTF_8) ?: StandardCharsets.UTF_8
logHttp(REQUEST, BODY, requestId, "Length: ${requestBody.contentLength()} byte body")
logHttp(REQUEST, BODY, requestId, "Type: ${requestBody.contentType()}")
logHttp(REQUEST, BODY, requestId, "--> Body start for request")
if (contentType.isLoggable()) {
if (requestBody.contentLength() < LIMIT_BODY_LOG) {
logHttp(REQUEST, BODY, requestId, buffer.readString(charset))
} else {
logHttp(REQUEST, BODY, requestId, buffer.readString(LIMIT_BODY_LOG, charset))
}
logHttp(
REQUEST,
BODY,
requestId,
"<-- Body end for request -- Omitted: ${max(0, requestBody.contentLength() - LIMIT_BODY_LOG)} bytes"
)
} else {
logHttp(
REQUEST,
BODY,
requestId,
"<-- Body end for request -- Binary -- Omitted: ${requestBody.contentLength()} bytes"
)
}
} ?: logHttp(REQUEST, BODY, requestId, "Empty body")
}
private fun logResponseBody(requestId: String?, responseBodyParam: ResponseBody?) {
responseBodyParam?.let { responseBody ->
val contentType = responseBody.contentType()
val charset: Charset = contentType?.charset(StandardCharsets.UTF_8) ?: StandardCharsets.UTF_8
logHttp(RESPONSE, BODY, requestId, "Length: ${responseBody.contentLength()} byte body")
logHttp(RESPONSE, BODY, requestId, "Type: ${responseBody.contentType()}")
logHttp(RESPONSE, BODY, requestId, "--> Body start for response")
val source = responseBody.source()
source.request(LIMIT_BODY_LOG)
val buffer = source.buffer
if (contentType.isLoggable()) {
if (responseBody.contentLength() < LIMIT_BODY_LOG) {
logHttp(RESPONSE, BODY, requestId, buffer.clone().readString(charset))
} else {
logHttp(RESPONSE, BODY, requestId, buffer.clone().readString(LIMIT_BODY_LOG, charset))
}
logHttp(
RESPONSE,
BODY,
requestId,
"<-- Body end for response -- Omitted: ${
max(
0,
responseBody.contentLength() - LIMIT_BODY_LOG
)
} bytes"
)
} else {
logHttp(
RESPONSE,
BODY,
requestId,
"<-- Body end for response -- Binary -- Omitted: ${responseBody.contentLength()} bytes"
)
}
} ?: logHttp(RESPONSE, BODY, requestId, "Empty body")
}
companion object {
var httpLogsEnabled: Boolean = false
private const val LIMIT_BODY_LOG: Long = 1024
}
}

View File

@ -0,0 +1,82 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class TLSSocketFactory extends SSLSocketFactory {
private SSLSocketFactory mInternalSSLSocketFactory;
public TLSSocketFactory(SSLSocketFactory delegate) {
mInternalSSLSocketFactory = delegate;
}
@Override
public String[] getDefaultCipherSuites() {
return mInternalSSLSocketFactory.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return mInternalSSLSocketFactory.getSupportedCipherSuites();
}
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
return enableTLSOnSocket(mInternalSSLSocketFactory.createSocket(s, host, port, autoClose));
}
@Override
public Socket createSocket(String host, int port) throws IOException {
return enableTLSOnSocket(mInternalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
return enableTLSOnSocket(mInternalSSLSocketFactory.createSocket(host, port, localHost, localPort));
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return enableTLSOnSocket(mInternalSSLSocketFactory.createSocket(host, port));
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws
IOException {
return enableTLSOnSocket(mInternalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
}
private Socket enableTLSOnSocket(Socket socket) {
if((socket instanceof SSLSocket)) {
((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.1", "TLSv1.2", "TLSv1.3"});
}
return socket;
}
}

View File

@ -0,0 +1,187 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods
import com.owncloud.android.lib.common.http.HttpClient
import okhttp3.Call
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.InputStream
import java.net.MalformedURLException
import java.net.URL
import java.util.concurrent.TimeUnit
abstract class HttpBaseMethod constructor(url: URL) {
var httpUrl: HttpUrl = url.toHttpUrlOrNull() ?: throw MalformedURLException()
var request: Request
var followPermanentRedirects = false
abstract var response: Response
var call: Call? = null
var followRedirects: Boolean = true
var retryOnConnectionFailure: Boolean = true
var connectionTimeoutVal: Long? = null
var connectionTimeoutUnit: TimeUnit? = null
var readTimeoutVal: Long? = null
private set
var readTimeoutUnit: TimeUnit? = null
private set
init {
request = Request.Builder()
.url(httpUrl)
.build()
}
@Throws(Exception::class)
open fun execute(httpClient: HttpClient): Int {
val okHttpClient = httpClient.okHttpClient.newBuilder().apply {
retryOnConnectionFailure(retryOnConnectionFailure)
followRedirects(followRedirects)
readTimeoutUnit?.let { unit ->
readTimeoutVal?.let { readTimeout(it, unit) }
}
connectionTimeoutUnit?.let { unit ->
connectionTimeoutVal?.let { connectTimeout(it, unit) }
}
}.build()
return onExecute(okHttpClient)
}
open fun setUrl(url: HttpUrl) {
request = request.newBuilder()
.url(url)
.build()
}
/****************
*** Requests ***
****************/
fun getRequestHeader(name: String): String? {
return request.header(name)
}
fun getRequestHeadersAsHashMap(): HashMap<String, String?> {
val headers: HashMap<String, String?> = HashMap()
val superHeaders: Set<String> = request.headers.names()
superHeaders.forEach {
headers[it] = getRequestHeader(it)
}
return headers
}
open fun addRequestHeader(name: String, value: String) {
request = request.newBuilder()
.addHeader(name, value)
.build()
}
/**
* Sets a header and replace it if already exists with that name
*
* @param name header name
* @param value header value
*/
open fun setRequestHeader(name: String, value: String) {
request = request.newBuilder()
.header(name, value)
.build()
}
/****************
*** Response ***
****************/
val statusCode: Int
get() = response.code
val statusMessage: String
get() = response.message
// Headers
open fun getResponseHeaders(): Headers? {
return response.headers
}
open fun getResponseHeader(headerName: String): String? {
return response.header(headerName)
}
// Body
fun getResponseBodyAsString(): String? = response.body?.string()
open fun getResponseBodyAsStream(): InputStream? {
return response.body?.byteStream()
}
/**
* returns the final url after following the last redirect.
*/
open fun getFinalUrl() = response.request.url
/*************************
*** Connection Params ***
*************************/
//////////////////////////////
// Setter
//////////////////////////////
// Connection parameters
open fun setReadTimeout(readTimeout: Long, timeUnit: TimeUnit) {
readTimeoutVal = readTimeout
readTimeoutUnit = timeUnit
}
open fun setConnectionTimeout(
connectionTimeout: Long,
timeUnit: TimeUnit
) {
connectionTimeoutVal = connectionTimeout
connectionTimeoutUnit = timeUnit
}
/************
*** Call ***
************/
open fun abort() {
call?.cancel()
}
open val isAborted: Boolean
get() = call?.isCanceled() ?: false
//////////////////////////////
// For override
//////////////////////////////
@Throws(Exception::class)
protected abstract fun onExecute(okHttpClient: OkHttpClient): Int
}

View File

@ -1,55 +1,43 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2020 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
package com.owncloud.android.lib.common.http.methods.nonwebdav
package com.owncloud.android.lib.common; import okhttp3.OkHttpClient
import java.io.IOException
import java.io.IOException; import java.net.URL
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
/** /**
* Manager to create and reuse OwnCloudClient instances to access remote OC servers. * OkHttp delete calls wrapper
* *
* @author David A. Velasco * @author David González Verdugo
* @author masensio
*/ */
class DeleteMethod(url: URL) : HttpMethod(url) {
public interface OwnCloudClientManager { @Throws(IOException::class)
override fun onExecute(okHttpClient: OkHttpClient): Int {
public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) request = request.newBuilder()
throws AccountNotFoundException, OperationCanceledException, AuthenticatorException, .delete()
IOException; .build()
return super.onExecute(okHttpClient)
public OwnCloudClient removeClientFor(OwnCloudAccount account); }
public void saveAllClients(Context context, String accountType)
throws AccountNotFoundException, AuthenticatorException,
IOException, OperationCanceledException;
} }

View File

@ -0,0 +1,43 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.nonwebdav
import okhttp3.OkHttpClient
import java.io.IOException
import java.net.URL
/**
* OkHttp get calls wrapper
*
* @author David González Verdugo
*/
class GetMethod(url: URL) : HttpMethod(url) {
@Throws(IOException::class)
override fun onExecute(okHttpClient: OkHttpClient): Int {
request = request.newBuilder()
.get()
.build()
return super.onExecute(okHttpClient)
}
}

View File

@ -1,46 +1,47 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2020 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
package com.owncloud.android.lib.sampleclient; package com.owncloud.android.lib.common.http.methods.nonwebdav
import android.content.Context; import com.owncloud.android.lib.common.http.methods.HttpBaseMethod
import android.view.View; import okhttp3.OkHttpClient
import android.view.ViewGroup; import okhttp3.Response
import android.widget.ArrayAdapter; import java.net.URL
import android.widget.TextView;
import com.owncloud.android.lib.resources.files.RemoteFile; /**
* Wrapper to perform OkHttp calls
*
* @author David González Verdugo
*/
abstract class HttpMethod(
url: URL
) : HttpBaseMethod(url) {
public class FilesArrayAdapter extends ArrayAdapter<RemoteFile> { override lateinit var response: Response
public FilesArrayAdapter(Context context, int resource) { public override fun onExecute(okHttpClient: OkHttpClient): Int {
super(context, resource); call = okHttpClient.newCall(request)
} call?.let { response = it.execute() }
return super.statusCode
public View getView(int position, View convertView, ViewGroup parent) { }
TextView textView = (TextView)super.getView(position, convertView, parent);
textView.setText(getItem(position).getRemotePath());
return textView;
}
} }

View File

@ -0,0 +1,47 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.nonwebdav
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import java.io.IOException
import java.net.URL
/**
* OkHttp post calls wrapper
*
* @author David González Verdugo
*/
class PostMethod(
url: URL,
private val postRequestBody: RequestBody
) : HttpMethod(url) {
@Throws(IOException::class)
override fun onExecute(okHttpClient: OkHttpClient): Int {
request = request.newBuilder()
.post(postRequestBody)
.build()
return super.onExecute(okHttpClient)
}
}

View File

@ -0,0 +1,47 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.nonwebdav
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import java.io.IOException
import java.net.URL
/**
* OkHttp put calls wrapper
*
* @author David González Verdugo
*/
class PutMethod(
url: URL,
private val putRequestBody: RequestBody
) : HttpMethod(url) {
@Throws(IOException::class)
override fun onExecute(okHttpClient: OkHttpClient): Int {
request = request.newBuilder()
.put(putRequestBody)
.build()
return super.onExecute(okHttpClient)
}
}

View File

@ -0,0 +1,52 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
import at.bitfire.dav4jvm.DavOCResource
import okhttp3.Response
import java.net.URL
/**
* Copy calls wrapper
*
* @author Christian Schabesberger
* @author David González Verdugo
*/
class CopyMethod(
val url: URL,
private val destinationUrl: String,
val forceOverride: Boolean = false
) : DavMethod(url) {
@Throws(Exception::class)
public override fun onDavExecute(davResource: DavOCResource): Int {
davResource.copy(
destinationUrl,
forceOverride,
super.getRequestHeadersAsHashMap()
) { callBackResponse: Response ->
response = callBackResponse
}
return super.statusCode
}
}

View File

@ -0,0 +1,32 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
/**
* @author David González Verdugo
*/
object DavConstants {
const val DEPTH_0 = 0
const val DEPTH_1 = 1
}

View File

@ -0,0 +1,97 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
import at.bitfire.dav4jvm.Dav4jvm.log
import at.bitfire.dav4jvm.DavOCResource
import at.bitfire.dav4jvm.exception.HttpException
import at.bitfire.dav4jvm.exception.RedirectException
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import java.net.URL
/**
* Wrapper to perform WebDAV (dav4android) calls
*
* @author David González Verdugo
*/
abstract class DavMethod protected constructor(url: URL) : HttpBaseMethod(url) {
override lateinit var response: Response
private var davResource: DavOCResource? = null
override fun abort() {
davResource?.cancelCall()
}
protected abstract fun onDavExecute(davResource: DavOCResource): Int
@Throws(Exception::class)
override fun onExecute(okHttpClient: OkHttpClient): Int {
return try {
davResource = DavOCResource(
okHttpClient.newBuilder().followRedirects(false).build(),
httpUrl,
log
)
onDavExecute(davResource!!)
} catch (httpException: HttpException) {
// Modify responses with information gathered from exceptions
if (httpException is RedirectException) {
response = Response.Builder()
.header(
HttpConstants.LOCATION_HEADER, httpException.redirectLocation
)
.code(httpException.code)
.request(request)
.message(httpException.message ?: "")
.protocol(Protocol.HTTP_1_1)
.build()
} else {
// The check below should be included in okhttp library, method ResponseBody.create(
// TODO check most recent versions of okhttp to see if this is already fixed and try to update if so
if (response.body?.contentType() != null) {
val responseBody = (httpException.responseBody ?: "").toResponseBody(response.body?.contentType())
response = response.newBuilder()
.body(responseBody)
.build()
}
}
httpException.code
}
}
//////////////////////////////
// Getter
//////////////////////////////
override val isAborted: Boolean
get() = davResource?.isCallAborted() ?: false
}

View File

@ -0,0 +1,60 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyUtils.getQuotaPropset
import at.bitfire.dav4jvm.property.CreationDate
import at.bitfire.dav4jvm.property.DisplayName
import at.bitfire.dav4jvm.property.GetContentLength
import at.bitfire.dav4jvm.property.GetContentType
import at.bitfire.dav4jvm.property.GetETag
import at.bitfire.dav4jvm.property.GetLastModified
import at.bitfire.dav4jvm.property.OCId
import at.bitfire.dav4jvm.property.OCPermissions
import at.bitfire.dav4jvm.property.OCPrivatelink
import at.bitfire.dav4jvm.property.OCSize
import at.bitfire.dav4jvm.property.ResourceType
import com.owncloud.android.lib.common.http.methods.webdav.properties.OCShareTypes
object DavUtils {
@JvmStatic val allPropSet: Array<Property.Name>
get() = arrayOf(
DisplayName.NAME,
GetContentType.NAME,
ResourceType.NAME,
GetContentLength.NAME,
GetLastModified.NAME,
CreationDate.NAME,
GetETag.NAME,
OCPermissions.NAME,
OCId.NAME,
OCSize.NAME,
OCPrivatelink.NAME,
OCShareTypes.NAME,
)
val quotaPropSet: Array<Property.Name>
get() = getQuotaPropset()
}

View File

@ -0,0 +1,47 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
import at.bitfire.dav4jvm.DavOCResource
import okhttp3.Response
import java.net.URL
/**
* MkCol calls wrapper
*
* @author Christian Schabesberger
* @author David González Verdugo
*/
class MkColMethod(url: URL) : DavMethod(url) {
@Throws(Exception::class)
public override fun onDavExecute(davResource: DavOCResource): Int {
davResource.mkCol(
xmlBody = null,
listOfHeaders = super.getRequestHeadersAsHashMap()
) { callBackResponse: Response ->
response = callBackResponse
}
return super.statusCode
}
}

View File

@ -0,0 +1,53 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
import at.bitfire.dav4jvm.DavOCResource
import okhttp3.Response
import java.net.URL
/**
* Move calls wrapper
*
* @author Christian Schabesberger
* @author David González Verdugo
*/
class MoveMethod(
url: URL,
private val destinationUrl: String,
val forceOverride: Boolean = false
) : DavMethod(url) {
@Throws(Exception::class)
override fun onDavExecute(davResource: DavOCResource): Int {
davResource.move(
destinationUrl,
forceOverride,
super.getRequestHeadersAsHashMap()
) { callBackResponse: Response ->
response = callBackResponse
}
return super.statusCode
}
}

View File

@ -0,0 +1,73 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
import at.bitfire.dav4jvm.DavOCResource
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.Response
import at.bitfire.dav4jvm.Response.HrefRelation
import at.bitfire.dav4jvm.exception.DavException
import java.io.IOException
import java.net.URL
/**
* Propfind calls wrapper
*
* @author David González Verdugo
*/
class PropfindMethod(
url: URL,
private val depth: Int,
private val propertiesToRequest: Array<Property.Name>
) : DavMethod(url) {
// response
val members: MutableList<Response>
var root: Response?
private set
@Throws(IOException::class, DavException::class)
public override fun onDavExecute(davResource: DavOCResource): Int {
davResource.propfind(
depth = depth,
reqProp = propertiesToRequest,
listOfHeaders = super.getRequestHeadersAsHashMap(),
callback = { response: Response, hrefRelation: HrefRelation ->
when (hrefRelation) {
HrefRelation.MEMBER -> members.add(response)
HrefRelation.SELF -> this.root = response
HrefRelation.OTHER -> {
}
}
}, rawCallback = { callBackResponse: okhttp3.Response ->
response = callBackResponse
})
return statusCode
}
init {
members = arrayListOf()
this.root = null
}
}

View File

@ -0,0 +1,53 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav
import at.bitfire.dav4jvm.DavOCResource
import at.bitfire.dav4jvm.exception.HttpException
import com.owncloud.android.lib.common.http.HttpConstants
import okhttp3.RequestBody
import java.io.IOException
import java.net.URL
/**
* Put calls wrapper
*
* @author David González Verdugo
*/
class PutMethod(
url: URL,
private val putRequestBody: RequestBody
) : DavMethod(url) {
@Throws(IOException::class, HttpException::class)
public override fun onDavExecute(davResource: DavOCResource): Int {
davResource.put(
putRequestBody,
super.getRequestHeader(HttpConstants.IF_MATCH_HEADER),
getRequestHeadersAsHashMap()
) { callBackResponse ->
response = callBackResponse
}
return super.statusCode
}
}

View File

@ -0,0 +1,44 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav.properties
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.XmlUtils
import org.xmlpull.v1.XmlPullParser
class OCShareTypes : ShareTypeListProperty() {
class Factory : ShareTypeListProperty.Factory() {
override fun create(parser: XmlPullParser) =
create(parser, OCShareTypes())
override fun getName(): Property.Name = NAME
}
companion object {
@JvmField
val NAME = Property.Name(XmlUtils.NS_OWNCLOUD, "share-types")
}
}

View File

@ -0,0 +1,46 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.http.methods.webdav.properties
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.PropertyFactory
import at.bitfire.dav4jvm.XmlUtils
import org.xmlpull.v1.XmlPullParser
import java.util.LinkedList
abstract class ShareTypeListProperty : Property {
val shareTypes = LinkedList<String>()
override fun toString() = "share types =[" + shareTypes.joinToString(", ") + "]"
abstract class Factory : PropertyFactory {
fun create(parser: XmlPullParser, list: ShareTypeListProperty): ShareTypeListProperty {
XmlUtils.readTextPropertyList(parser, Property.Name(XmlUtils.NS_OWNCLOUD, "share-type"), list.shareTypes)
return list
}
}
}

View File

@ -1,22 +1,22 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
@ -24,117 +24,105 @@
package com.owncloud.android.lib.common.network; package com.owncloud.android.lib.common.network;
import timber.log.Timber;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.KeyStoreException; import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertStoreException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import com.owncloud.android.lib.common.utils.Log_OC;
/** /**
* @author David A. Velasco * @author David A. Velasco
*/ */
public class AdvancedX509TrustManager implements X509TrustManager { public class AdvancedX509TrustManager implements X509TrustManager {
private static final String TAG = AdvancedX509TrustManager.class.getSimpleName();
private X509TrustManager mStandardTrustManager = null; private X509TrustManager mStandardTrustManager;
private KeyStore mKnownServersKeyStore; private KeyStore mKnownServersKeyStore;
/** /**
* Constructor for AdvancedX509TrustManager * Constructor for AdvancedX509TrustManager
* *
* @param knownServersKeyStore Local certificates store with server certificates explicitly trusted by the user. * @param knownServersKeyStore Local certificates store with server certificates explicitly trusted by the user.
* @throws CertStoreException When no default X509TrustManager instance was found in the system.
*/ */
public AdvancedX509TrustManager(KeyStore knownServersKeyStore) public AdvancedX509TrustManager(KeyStore knownServersKeyStore) throws NoSuchAlgorithmException, KeyStoreException {
throws NoSuchAlgorithmException, KeyStoreException, CertStoreException {
super(); super();
TrustManagerFactory factory = TrustManagerFactory TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
.getInstance(TrustManagerFactory.getDefaultAlgorithm()); factory.init((KeyStore) null);
factory.init((KeyStore)null);
mStandardTrustManager = findX509TrustManager(factory); mStandardTrustManager = findX509TrustManager(factory);
mKnownServersKeyStore = knownServersKeyStore; mKnownServersKeyStore = knownServersKeyStore;
} }
/** /**
* Locates the first X509TrustManager provided by a given TrustManagerFactory * Locates the first X509TrustManager provided by a given TrustManagerFactory
* @param factory TrustManagerFactory to inspect in the search for a X509TrustManager *
* @return The first X509TrustManager found in factory. * @param factory TrustManagerFactory to inspect in the search for a X509TrustManager
* @throws CertStoreException When no X509TrustManager instance was found in factory * @return The first X509TrustManager found in factory.
*/ */
private X509TrustManager findX509TrustManager(TrustManagerFactory factory) throws CertStoreException { private X509TrustManager findX509TrustManager(TrustManagerFactory factory) {
TrustManager tms[] = factory.getTrustManagers(); TrustManager[] tms = factory.getTrustManagers();
for (int i = 0; i < tms.length; i++) { for (TrustManager tm : tms) {
if (tms[i] instanceof X509TrustManager) { if (tm instanceof X509TrustManager) {
return (X509TrustManager) tms[i]; return (X509TrustManager) tm;
} }
} }
return null; return null;
} }
/** /**
* @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[], * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],
* String authType) * String authType)
*/ */
public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException { public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
mStandardTrustManager.checkClientTrusted(certificates, authType); mStandardTrustManager.checkClientTrusted(certificates, authType);
} }
/** /**
* @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],
* String authType) * String authType)
*/ */
public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException { public void checkServerTrusted(X509Certificate[] certificates, String authType) {
if (!isKnownServer(certificates[0])) { if (!isKnownServer(certificates[0])) {
CertificateCombinedException result = new CertificateCombinedException(certificates[0]); CertificateCombinedException result = new CertificateCombinedException(certificates[0]);
try { try {
certificates[0].checkValidity(); certificates[0].checkValidity();
} catch (CertificateExpiredException c) { } catch (CertificateExpiredException c) {
result.setCertificateExpiredException(c); result.setCertificateExpiredException(c);
} catch (CertificateNotYetValidException c) { } catch (CertificateNotYetValidException c) {
result.setCertificateNotYetException(c); result.setCertificateNotYetException(c);
} }
try { try {
mStandardTrustManager.checkServerTrusted(certificates, authType); mStandardTrustManager.checkServerTrusted(certificates, authType);
} catch (CertificateException c) { } catch (CertificateException c) {
Throwable cause = c.getCause(); Throwable cause = c.getCause();
Throwable previousCause = null; Throwable previousCause = null;
while (cause != null && cause != previousCause && !(cause instanceof CertPathValidatorException)) { // getCause() is not funny while (cause != null && cause != previousCause && !(cause instanceof CertPathValidatorException)) { // getCause() is not funny
previousCause = cause; previousCause = cause;
cause = cause.getCause(); cause = cause.getCause();
} }
if (cause != null && cause instanceof CertPathValidatorException) { if (cause instanceof CertPathValidatorException) {
result.setCertPathValidatorException((CertPathValidatorException)cause); result.setCertPathValidatorException((CertPathValidatorException) cause);
} else { } else {
result.setOtherCertificateException(c); result.setOtherCertificateException(c);
} }
} }
if (result.isException()) if (result.isException()) {
throw result; throw result;
}
} }
} }
/** /**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/ */
@ -142,14 +130,13 @@ public class AdvancedX509TrustManager implements X509TrustManager {
return mStandardTrustManager.getAcceptedIssuers(); return mStandardTrustManager.getAcceptedIssuers();
} }
public boolean isKnownServer(X509Certificate cert) { public boolean isKnownServer(X509Certificate cert) {
try { try {
return (mKnownServersKeyStore.getCertificateAlias(cert) != null); return (mKnownServersKeyStore.getCertificateAlias(cert) != null);
} catch (KeyStoreException e) { } catch (KeyStoreException e) {
Log_OC.d(TAG, "Fail while checking certificate in the known-servers store"); Timber.e(e, "Fail while checking certificate in the known-servers store");
return false; return false;
} }
} }
} }

View File

@ -1,22 +1,22 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
@ -24,36 +24,37 @@
package com.owncloud.android.lib.common.network; package com.owncloud.android.lib.common.network;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.security.cert.CertPathValidatorException; import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException; import java.security.cert.CertificateNotYetValidException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import javax.net.ssl.SSLPeerUnverifiedException;
/** /**
* Exception joining all the problems that {@link AdvancedX509TrustManager} can find in * Exception joining all the problems that {@link AdvancedX509TrustManager} can find in
* a certificate chain for a server. * a certificate chain for a server.
* * <p>
* This was initially created as an extension of CertificateException, but some * This was initially created as an extension of CertificateException, but some
* implementations of the SSL socket layer in existing devices are REPLACING the CertificateException * implementations of the SSL socket layer in existing devices are REPLACING the CertificateException
* instances thrown by {@link javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], String)} * instances thrown by {@link javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[], String)}
* with SSLPeerUnverifiedException FORGETTING THE CAUSING EXCEPTION instead of wrapping it. * with SSLPeerUnverifiedException FORGETTING THE CAUSING EXCEPTION instead of wrapping it.
* * <p>
* Due to this, extending RuntimeException is necessary to get that the CertificateCombinedException * Due to this, extending RuntimeException is necessary to get that the CertificateCombinedException
* instance reaches {@link AdvancedSslSocketFactory#verifyPeerIdentity}. * instance reaches {@link AdvancedSslSocketFactory#verifyPeerIdentity}.
* * <p>
* BE CAREFUL. As a RuntimeException extensions, Java compilers do not require to handle it * BE CAREFUL. As a RuntimeException extensions, Java compilers do not require to handle it
* in client methods. Be sure to use it only when you know exactly where it will go. * in client methods. Be sure to use it only when you know exactly where it will go.
* *
* @author David A. Velasco * @author David A. Velasco
*/ */
public class CertificateCombinedException extends RuntimeException { public class CertificateCombinedException extends RuntimeException {
/** Generated - to refresh every time the class changes */ /**
* Generated - to refresh every time the class changes
*/
private static final long serialVersionUID = -8875782030758554999L; private static final long serialVersionUID = -8875782030758554999L;
private X509Certificate mServerCert = null; private X509Certificate mServerCert = null;
private String mHostInUrl; private String mHostInUrl;
@ -62,7 +63,7 @@ public class CertificateCombinedException extends RuntimeException {
private CertPathValidatorException mCertPathValidatorException = null; private CertPathValidatorException mCertPathValidatorException = null;
private CertificateException mOtherCertificateException = null; private CertificateException mOtherCertificateException = null;
private SSLPeerUnverifiedException mSslPeerUnverifiedException = null; private SSLPeerUnverifiedException mSslPeerUnverifiedException = null;
public CertificateCombinedException(X509Certificate x509Certificate) { public CertificateCombinedException(X509Certificate x509Certificate) {
mServerCert = x509Certificate; mServerCert = x509Certificate;
} }
@ -84,7 +85,7 @@ public class CertificateCombinedException extends RuntimeException {
} }
public void setCertificateExpiredException(CertificateExpiredException c) { public void setCertificateExpiredException(CertificateExpiredException c) {
mCertificateExpiredException = c; mCertificateExpiredException = c;
} }
public CertificateNotYetValidException getCertificateNotYetValidException() { public CertificateNotYetValidException getCertificateNotYetValidException() {
@ -112,7 +113,7 @@ public class CertificateCombinedException extends RuntimeException {
} }
public SSLPeerUnverifiedException getSslPeerUnverifiedException() { public SSLPeerUnverifiedException getSslPeerUnverifiedException() {
return mSslPeerUnverifiedException ; return mSslPeerUnverifiedException;
} }
public void setSslPeerUnverifiedException(SSLPeerUnverifiedException s) { public void setSslPeerUnverifiedException(SSLPeerUnverifiedException s) {

View File

@ -0,0 +1,92 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network
import com.owncloud.android.lib.resources.files.chunks.ChunkedUploadFromFileSystemOperation.Companion.CHUNK_SIZE
import okhttp3.MediaType
import okio.BufferedSink
import timber.log.Timber
import java.io.File
import java.nio.ByteBuffer
import java.nio.channels.FileChannel
/**
* A Request body that represents a file chunk and include information about the progress when uploading it
*
* @author David González Verdugo
*/
class ChunkFromFileRequestBody(
file: File,
contentType: MediaType?,
private val channel: FileChannel,
private val chunkSize: Long = CHUNK_SIZE
) : FileRequestBody(file, contentType) {
private var offset: Long = 0
private var alreadyTransferred: Long = 0
private val buffer = ByteBuffer.allocate(4_096)
init {
require(chunkSize > 0) { "Chunk size must be greater than zero" }
}
override fun contentLength(): Long {
return chunkSize.coerceAtMost(channel.size() - channel.position())
}
override fun writeTo(sink: BufferedSink) {
var readCount: Int
var iterator: Iterator<OnDatatransferProgressListener>
try {
channel.position(offset)
val maxCount = (offset + chunkSize).coerceAtMost(channel.size())
while (channel.position() < maxCount) {
readCount = channel.read(buffer)
val bytesToWriteInBuffer = readCount.toLong().coerceAtMost(file.length() - alreadyTransferred).toInt()
sink.buffer.write(buffer.array(), 0, bytesToWriteInBuffer)
sink.flush()
buffer.clear()
if (alreadyTransferred < maxCount) { // condition to avoid accumulate progress for repeated chunks
alreadyTransferred += readCount.toLong()
}
synchronized(dataTransferListeners) {
iterator = dataTransferListeners.iterator()
while (iterator.hasNext()) {
iterator.next().onTransferProgress(readCount.toLong(), alreadyTransferred, file.length(), file.absolutePath)
}
}
}
} catch (exception: Exception) {
Timber.e(exception, "Transferred " + alreadyTransferred + " bytes from a total of " + file.length())
}
}
fun setOffset(newOffset: Long) {
offset = newOffset
}
}

View File

@ -0,0 +1,117 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network
import android.content.ContentResolver
import android.net.Uri
import android.provider.OpenableColumns
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okio.BufferedSink
import okio.Source
import okio.source
import timber.log.Timber
import java.io.IOException
class ContentUriRequestBody(
private val contentResolver: ContentResolver,
private val contentUri: Uri
) : RequestBody(), ProgressiveDataTransferer {
private val dataTransferListeners: MutableSet<OnDatatransferProgressListener> = HashSet()
val fileSize: Long = contentResolver.query(contentUri, null, null, null, null)?.use { cursor ->
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.moveToFirst()
cursor.getLong(sizeIndex)
} ?: -1
override fun contentType(): MediaType? {
val contentType = contentResolver.getType(contentUri) ?: return null
return contentType.toMediaTypeOrNull()
}
override fun contentLength(): Long {
return fileSize
}
override fun writeTo(sink: BufferedSink) {
val inputStream = contentResolver.openInputStream(contentUri)
?: throw IOException("Couldn't open content URI for reading: $contentUri")
val previousTime = System.currentTimeMillis()
sink.writeAndUpdateProgress(inputStream.source())
inputStream.source().close()
val laterTime = System.currentTimeMillis()
Timber.d("Difference - ${laterTime - previousTime} milliseconds")
}
private fun BufferedSink.writeAndUpdateProgress(source: Source) {
var iterator: Iterator<OnDatatransferProgressListener>
try {
var totalBytesRead = 0L
var read: Long
while (source.read(this.buffer, BYTES_TO_READ).also { read = it } != -1L) {
totalBytesRead += read
this.flush()
synchronized(dataTransferListeners) {
iterator = dataTransferListeners.iterator()
while (iterator.hasNext()) {
iterator.next().onTransferProgress(read, totalBytesRead, fileSize, contentUri.toString())
}
}
}
} catch (e: Exception) {
Timber.e(e)
}
}
override fun addDatatransferProgressListener(listener: OnDatatransferProgressListener) {
synchronized(dataTransferListeners) {
dataTransferListeners.add(listener)
}
}
override fun addDatatransferProgressListeners(listeners: MutableCollection<OnDatatransferProgressListener>) {
synchronized(dataTransferListeners) {
dataTransferListeners.addAll(listeners)
}
}
override fun removeDatatransferProgressListener(listener: OnDatatransferProgressListener) {
synchronized(dataTransferListeners) {
dataTransferListeners.remove(listener)
}
}
companion object {
private const val BYTES_TO_READ = 4_096L
}
}

View File

@ -0,0 +1,97 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network
import okhttp3.MediaType
import okhttp3.RequestBody
import okio.BufferedSink
import okio.Source
import okio.source
import timber.log.Timber
import java.io.File
import java.util.HashSet
/**
* A Request body that represents a file and include information about the progress when uploading it
*
* @author David González Verdugo
*/
open class FileRequestBody(
val file: File,
private val contentType: MediaType?,
) : RequestBody(), ProgressiveDataTransferer {
val dataTransferListeners: MutableSet<OnDatatransferProgressListener> = HashSet()
override fun isOneShot(): Boolean = true
override fun contentType(): MediaType? = contentType
override fun contentLength(): Long = file.length()
override fun writeTo(sink: BufferedSink) {
val source: Source
var it: Iterator<OnDatatransferProgressListener>
try {
source = file.source()
var transferred: Long = 0
var read: Long
while (source.read(sink.buffer, BYTES_TO_READ).also { read = it } != -1L) {
transferred += read
sink.flush()
synchronized(dataTransferListeners) {
it = dataTransferListeners.iterator()
while (it.hasNext()) {
it.next().onTransferProgress(read, transferred, file.length(), file.absolutePath)
}
}
}
Timber.d("File with name ${file.name} and size ${file.length()} written in request body")
} catch (e: Exception) {
Timber.e(e)
}
}
override fun addDatatransferProgressListener(listener: OnDatatransferProgressListener) {
synchronized(dataTransferListeners) {
dataTransferListeners.add(listener)
}
}
override fun addDatatransferProgressListeners(listeners: Collection<OnDatatransferProgressListener>) {
synchronized(dataTransferListeners) {
dataTransferListeners.addAll(listeners)
}
}
override fun removeDatatransferProgressListener(listener: OnDatatransferProgressListener) {
synchronized(dataTransferListeners) {
dataTransferListeners.remove(listener)
}
}
companion object {
private const val BYTES_TO_READ = 4_096L
}
}

View File

@ -0,0 +1,97 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2016 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network;
import android.content.Context;
import timber.log.Timber;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
public class NetworkUtils {
private static String LOCAL_TRUSTSTORE_FILENAME = "knownServers.bks";
private static String LOCAL_TRUSTSTORE_PASSWORD = "password";
private static KeyStore mKnownServersStore = null;
/**
* Returns the local store of reliable server certificates, explicitly accepted by the user.
* <p>
* Returns a KeyStore instance with empty content if the local store was never created.
* <p>
* Loads the store from the storage environment if needed.
*
* @param context Android context where the operation is being performed.
* @return KeyStore instance with explicitly-accepted server certificates.
* @throws KeyStoreException When the KeyStore instance could not be created.
* @throws IOException When an existing local trust store could not be loaded.
* @throws NoSuchAlgorithmException When the existing local trust store was saved with an unsupported algorithm.
* @throws CertificateException When an exception occurred while loading the certificates from the local
* trust store.
*/
public static KeyStore getKnownServersStore(Context context)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
if (mKnownServersStore == null) {
//mKnownServersStore = KeyStore.getInstance("BKS");
mKnownServersStore = KeyStore.getInstance(KeyStore.getDefaultType());
File localTrustStoreFile = new File(context.getFilesDir(), LOCAL_TRUSTSTORE_FILENAME);
Timber.d("Searching known-servers store at %s", localTrustStoreFile.getAbsolutePath());
if (localTrustStoreFile.exists()) {
InputStream in = new FileInputStream(localTrustStoreFile);
try {
mKnownServersStore.load(in, LOCAL_TRUSTSTORE_PASSWORD.toCharArray());
} finally {
in.close();
}
} else {
// next is necessary to initialize an empty KeyStore instance
mKnownServersStore.load(null, LOCAL_TRUSTSTORE_PASSWORD.toCharArray());
}
}
return mKnownServersStore;
}
public static void addCertToKnownServersStore(Certificate cert, Context context)
throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
KeyStore knownServers = getKnownServersStore(context);
knownServers.setCertificateEntry(Integer.toString(cert.hashCode()), cert);
try (FileOutputStream fos = context.openFileOutput(LOCAL_TRUSTSTORE_FILENAME, Context.MODE_PRIVATE)) {
knownServers.store(fos, LOCAL_TRUSTSTORE_PASSWORD.toCharArray());
}
}
}

View File

@ -1,23 +1,23 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* Copyright (C) 2012 Bartek Przybylski * Copyright (C) 2012 Bartek Przybylski
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
@ -26,5 +26,5 @@
package com.owncloud.android.lib.common.network; package com.owncloud.android.lib.common.network;
public interface OnDatatransferProgressListener { public interface OnDatatransferProgressListener {
public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileAbsoluteName); void onTransferProgress(long read, long transferred, long percent, String absolutePath);
} }

View File

@ -1,22 +1,22 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
@ -26,14 +26,12 @@ package com.owncloud.android.lib.common.network;
import java.util.Collection; import java.util.Collection;
public interface ProgressiveDataTransferer { public interface ProgressiveDataTransferer {
public void addDatatransferProgressListener (OnDatatransferProgressListener listener); void addDatatransferProgressListener(OnDatatransferProgressListener listener);
public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners);
public void removeDatatransferProgressListener(OnDatatransferProgressListener listener); void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners);
void removeDatatransferProgressListener(OnDatatransferProgressListener listener);
} }

View File

@ -0,0 +1,123 @@
/* ownCloud Android Library is available under MIT license
*
* @author David A. Velasco
*
* Copyright (C) 2016 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network;
import com.owncloud.android.lib.common.http.HttpConstants;
import java.util.Arrays;
/**
* Aggregate saving the list of URLs followed in a sequence of redirections during the exceution of a
* {@link RemoteOperation}, and the status codes corresponding to all
* of them.
* <p>
* The last status code saved corresponds to the first response not being a redirection, unless the sequence exceeds
* the maximum length of redirections allowed by the {@link com.owncloud.android.lib.common.OwnCloudClient} instance
* that ran the operation.
* <p>
* If no redirection was followed, the last (and first) status code contained corresponds to the original URL in the
* request.
*/
public class RedirectionPath {
private int[] mStatuses = null;
private int mLastStatus = -1;
private String[] mLocations = null;
private int mLastLocation = -1;
/**
* Public constructor.
*
* @param status Status code resulting of executing a request on the original URL.
* @param maxRedirections Maximum number of redirections that will be contained.
* @throws IllegalArgumentException If 'maxRedirections' is < 0
*/
public RedirectionPath(int status, int maxRedirections) {
if (maxRedirections < 0) {
throw new IllegalArgumentException("maxRedirections MUST BE zero or greater");
}
mStatuses = new int[maxRedirections + 1];
Arrays.fill(mStatuses, -1);
mStatuses[++mLastStatus] = status;
}
/**
* Adds a new location URL to the list of followed redirections.
*
* @param location URL extracted from a 'Location' header in a redirection.
*/
public void addLocation(String location) {
if (mLocations == null) {
mLocations = new String[mStatuses.length - 1];
}
if (mLastLocation < mLocations.length - 1) {
mLocations[++mLastLocation] = location;
}
}
/**
* Adds a new status code to the list of status corresponding to followed redirections.
*
* @param status Status code from the response of another followed redirection.
*/
public void addStatus(int status) {
if (mLastStatus < mStatuses.length - 1) {
mStatuses[++mLastStatus] = status;
}
}
/**
* @return Last status code saved.
*/
public int getLastStatus() {
return mStatuses[mLastStatus];
}
/**
* @return Last location followed corresponding to a permanent redirection (status code 301).
*/
public String getLastPermanentLocation() {
for (int i = mLastStatus; i >= 0; i--) {
if (mStatuses[i] == HttpConstants.HTTP_MOVED_PERMANENTLY && i <= mLastLocation) {
return mLocations[i];
}
}
return null;
}
/**
* @return Count of locations.
*/
public int getRedirectionsCount() {
return mLastLocation + 1;
}
}

View File

@ -0,0 +1,117 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2016 ownCloud GmbH.
* Copyright (C) 2012 Bartek Przybylski
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.network;
import android.net.Uri;
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class WebdavUtils {
private static final SimpleDateFormat[] DATETIME_FORMATS = {
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US),
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sss'Z'", Locale.US),
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.US),
new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US),
new SimpleDateFormat("EEEEEE, dd-MMM-yy HH:mm:ss zzz", Locale.US),
new SimpleDateFormat("EEE MMMM d HH:mm:ss yyyy", Locale.US),
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.US)
};
public static Date parseResponseDate(String date) {
Date returnDate;
SimpleDateFormat format;
for (SimpleDateFormat datetimeFormat : DATETIME_FORMATS) {
try {
format = datetimeFormat;
synchronized (format) {
returnDate = format.parse(date);
}
return returnDate;
} catch (ParseException e) {
// this is not the format
}
}
return null;
}
/**
* Encodes a path according to URI RFC 2396.
* <p>
* If the received path doesn't start with "/", the method adds it.
*
* @param remoteFilePath Path
* @return Encoded path according to RFC 2396, always starting with "/"
*/
public static String encodePath(String remoteFilePath) {
String encodedPath = Uri.encode(remoteFilePath, "/");
if (!encodedPath.startsWith("/")) {
encodedPath = "/" + encodedPath;
}
return encodedPath;
}
/**
* @param httpBaseMethod from which to get the etag
* @return etag from response
*/
public static String getEtagFromResponse(HttpBaseMethod httpBaseMethod) {
String eTag = httpBaseMethod.getResponseHeader("OC-ETag");
if (eTag == null) {
eTag = httpBaseMethod.getResponseHeader("oc-etag");
}
if (eTag == null) {
eTag = httpBaseMethod.getResponseHeader("ETag");
}
if (eTag == null) {
eTag = httpBaseMethod.getResponseHeader("etag");
}
String result = "";
if (eTag != null) {
result = eTag;
}
return result;
}
public static String normalizeProtocolPrefix(String url, boolean isSslConn) {
if (!url.toLowerCase().startsWith("http://") &&
!url.toLowerCase().startsWith("https://")) {
if (isSslConn) {
return "https://" + url;
} else {
return "http://" + url;
}
}
return url;
}
}

View File

@ -0,0 +1,143 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2017 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.operations;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStream;
/**
* Parser for server exceptions
*
* @author davidgonzalez
*/
public class ErrorMessageParser {
// No namespaces
private static final String ns = null;
// Nodes for XML Parser
private static final String NODE_ERROR = "d:error";
private static final String NODE_MESSAGE = "s:message";
/**
* Parse exception response
*
* @param is
* @return errorMessage for an exception
* @throws XmlPullParserException
* @throws IOException
*/
public String parseXMLResponse(InputStream is) throws XmlPullParserException,
IOException {
String errorMessage = "";
try {
// XMLPullParser
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);
parser.nextTag();
errorMessage = readError(parser);
} finally {
is.close();
}
return errorMessage;
}
/**
* Parse OCS node
*
* @param parser
* @return reason for exception
* @throws XmlPullParserException
* @throws IOException
*/
private String readError(XmlPullParser parser) throws XmlPullParserException, IOException {
String errorMessage = "";
parser.require(XmlPullParser.START_TAG, ns, NODE_ERROR);
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// read NODE_MESSAGE
if (name.equalsIgnoreCase(NODE_MESSAGE)) {
errorMessage = readText(parser);
} else {
skip(parser);
}
}
return errorMessage;
}
/**
* Skip tags in parser procedure
*
* @param parser
* @throws XmlPullParserException
* @throws IOException
*/
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
/**
* Read the text from a node
*
* @param parser
* @return Text of the node
* @throws IOException
* @throws XmlPullParserException
*/
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
}

View File

@ -0,0 +1,150 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2016 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.operations;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStream;
/**
* Parser for Invalid Character server exception
*
* @author masensio
*/
public class InvalidCharacterExceptionParser {
private static final String EXCEPTION_STRING = "OC\\Connector\\Sabre\\Exception\\InvalidPath";
private static final String EXCEPTION_UPLOAD_STRING = "OCP\\Files\\InvalidPathException";
// No namespaces
private static final String ns = null;
// Nodes for XML Parser
private static final String NODE_ERROR = "d:error";
private static final String NODE_EXCEPTION = "s:exception";
/**
* Parse is as an Invalid Path Exception
*
* @param is
* @return if The exception is an Invalid Char Exception
* @throws XmlPullParserException
* @throws IOException
*/
public boolean parseXMLResponse(InputStream is) throws XmlPullParserException,
IOException {
boolean result = false;
try {
// XMLPullParser
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(is, null);
parser.nextTag();
result = readError(parser);
} finally {
is.close();
}
return result;
}
/**
* Parse OCS node
*
* @param parser
* @return List of ShareRemoteFiles
* @throws XmlPullParserException
* @throws IOException
*/
private boolean readError(XmlPullParser parser) throws XmlPullParserException, IOException {
String exception = "";
parser.require(XmlPullParser.START_TAG, ns, NODE_ERROR);
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// read NODE_EXCEPTION
if (name.equalsIgnoreCase(NODE_EXCEPTION)) {
exception = readText(parser);
} else {
skip(parser);
}
}
return exception.equalsIgnoreCase(EXCEPTION_STRING) ||
exception.equalsIgnoreCase(EXCEPTION_UPLOAD_STRING);
}
/**
* Skip tags in parser procedure
*
* @param parser
* @throws XmlPullParserException
* @throws IOException
*/
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
/**
* Read the text from a node
*
* @param parser
* @return Text of the node
* @throws IOException
* @throws XmlPullParserException
*/
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
}

View File

@ -1,22 +1,22 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
@ -24,9 +24,8 @@
package com.owncloud.android.lib.common.operations; package com.owncloud.android.lib.common.operations;
public interface OnRemoteOperationListener { public interface OnRemoteOperationListener {
void onRemoteOperationFinish(RemoteOperation caller, RemoteOperationResult result); void onRemoteOperationFinish(RemoteOperation caller, RemoteOperationResult result);
} }

View File

@ -1,22 +1,22 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2016 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *

View File

@ -0,0 +1,292 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.operations;
import android.accounts.Account;
import android.accounts.AccountsException;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.os.Handler;
import com.owncloud.android.lib.common.OwnCloudAccount;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.SingleSessionManager;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import okhttp3.OkHttpClient;
import timber.log.Timber;
import java.io.IOException;
@SuppressWarnings("WeakerAccess")
public abstract class RemoteOperation<T> implements Runnable {
/**
* OCS API header name
*/
public static final String OCS_API_HEADER = "OCS-APIREQUEST";
/**
* OCS API header value
*/
public static final String OCS_API_HEADER_VALUE = "true";
/**
* ownCloud account in the remote ownCloud server to operate
*/
protected Account mAccount = null;
/**
* Android Application context
*/
protected Context mContext = null;
/**
* Object to interact with the remote server
*/
private OwnCloudClient mClient = null;
/**
* Object to interact with the remote server
*/
private OkHttpClient mHttpClient = null;
/**
* Callback object to notify about the execution of the remote operation
*/
private OnRemoteOperationListener mListener = null;
/**
* Handler to the thread where mListener methods will be called
*/
private Handler mListenerHandler = null;
/**
* Asynchronously executes the remote operation
* <p>
* This method should be used whenever an ownCloud account is available,
* instead of {@link #execute(OwnCloudClient, OnRemoteOperationListener, Handler))}.
*
* @param account ownCloud account in remote ownCloud server to reach during the
* execution of the operation.
* @param context Android context for the component calling the method.
* @param listener Listener to be notified about the execution of the operation.
* @param listenerHandler Handler associated to the thread where the methods of the listener
* objects must be called.
* @return Thread were the remote operation is executed.
*/
public Thread execute(Account account, Context context,
OnRemoteOperationListener listener, Handler listenerHandler) {
if (account == null) {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account");
}
if (context == null) {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context");
}
// mAccount and mContext in the runnerThread to create below
mAccount = account;
mContext = context.getApplicationContext();
mClient = null; // the client instance will be created from
mListener = listener;
mListenerHandler = listenerHandler;
Thread runnerThread = new Thread(this);
runnerThread.start();
return runnerThread;
}
/**
* Asynchronously executes the remote operation
*
* @param client Client object to reach an ownCloud server
* during the execution of the operation.
* @param listener Listener to be notified about the execution of the operation.
* @param listenerHandler Handler, if passed in, associated to the thread where the methods of
* the listener objects must be called.
* @return Thread were the remote operation is executed.
*/
public Thread execute(OwnCloudClient client, OnRemoteOperationListener listener, Handler listenerHandler) {
if (client == null) {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL OwnCloudClient");
}
mClient = client;
if (client.getAccount() != null) {
mAccount = client.getAccount().getSavedAccount();
}
mContext = client.getContext();
if (listener == null) {
throw new IllegalArgumentException
("Trying to execute a remote operation asynchronously without a listener to notify the result");
}
mListener = listener;
if (listenerHandler != null) {
mListenerHandler = listenerHandler;
}
Thread runnerThread = new Thread(this);
runnerThread.start();
return runnerThread;
}
private void grantOwnCloudClient() throws
AccountUtils.AccountNotFoundException, OperationCanceledException, AuthenticatorException, IOException {
if (mClient == null) {
if (mAccount != null && mContext != null) {
OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
mClient = SingleSessionManager.getDefaultSingleton().
getClientFor(ocAccount, mContext, SingleSessionManager.getConnectionValidator());
} else {
throw new IllegalStateException("Trying to run a remote operation " +
"asynchronously with no client and no chance to create one (no account)");
}
}
}
/**
* Returns the current client instance to access the remote server.
*
* @return Current client instance to access the remote server.
*/
public final OwnCloudClient getClient() {
return mClient;
}
/**
* Abstract method to implement the operation in derived classes.
*/
protected abstract RemoteOperationResult<T> run(OwnCloudClient client);
/**
* Synchronously executes the remote operation on the received ownCloud account.
* <p>
* Do not call this method from the main thread.
* <p>
* This method should be used whenever an ownCloud account is available, instead of
* {@link #execute(OwnCloudClient)}.
*
* @param account ownCloud account in remote ownCloud server to reach during the
* execution of the operation.
* @param context Android context for the component calling the method.
* @return Result of the operation.
*/
public RemoteOperationResult<T> execute(Account account, Context context) {
if (account == null) {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Account");
}
if (context == null) {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL Context");
}
mAccount = account;
mContext = context.getApplicationContext();
return runOperation();
}
/**
* Synchronously executes the remote operation
* <p>
* Do not call this method from the main thread.
*
* @param client Client object to reach an ownCloud server during the execution of
* the operation.
* @return Result of the operation.
*/
public RemoteOperationResult<T> execute(OwnCloudClient client) {
if (client == null) {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL OwnCloudClient");
}
mClient = client;
if (client.getAccount() != null) {
mAccount = client.getAccount().getSavedAccount();
}
mContext = client.getContext();
return runOperation();
}
/**
* Synchronously executes the remote operation
* <p>
* Do not call this method from the main thread.
*
* @param client Client object to reach an ownCloud server during the execution of
* the operation.
* @return Result of the operation.
*/
public RemoteOperationResult<T> execute(OkHttpClient client, Context context) {
if (client == null) {
throw new IllegalArgumentException("Trying to execute a remote operation with a NULL OwnCloudClient");
}
mHttpClient = client;
mContext = context;
return runOperation();
}
/**
* Run operation for asynchronous or synchronous 'onExecute' method.
* <p>
* Considers and performs silent refresh of account credentials if possible
*
* @return Remote operation result
*/
private RemoteOperationResult<T> runOperation() {
RemoteOperationResult<T> result;
try {
grantOwnCloudClient();
result = run(mClient);
} catch (AccountsException | IOException e) {
Timber.e(e, "Error while trying to access to %s", mAccount.name);
result = new RemoteOperationResult<>(e);
}
return result;
}
/**
* Asynchronous execution of the operation
* started by {@link RemoteOperation#execute(OwnCloudClient,
* OnRemoteOperationListener, Handler)},
* and result posting.
*/
@Override
public final void run() {
final RemoteOperationResult resultToSend = runOperation();
if (mListenerHandler != null && mListener != null) {
mListenerHandler.post(() ->
mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend));
} else if (mListener != null) {
mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
}
}
}

View File

@ -0,0 +1,598 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.operations;
import android.accounts.Account;
import android.accounts.AccountsException;
import at.bitfire.dav4jvm.exception.DavException;
import at.bitfire.dav4jvm.exception.HttpException;
import com.owncloud.android.lib.common.accounts.AccountUtils;
import com.owncloud.android.lib.common.http.HttpConstants;
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
import com.owncloud.android.lib.common.network.CertificateCombinedException;
import okhttp3.Headers;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.json.JSONException;
import timber.log.Timber;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class RemoteOperationResult<T>
implements Serializable {
/**
* Generated - should be refreshed every time the class changes!!
*/
private static final long serialVersionUID = 4968939884332372230L;
private static final String LOCATION = "location";
private static final String WWW_AUTHENTICATE = "www-authenticate";
private boolean mSuccess = false;
private int mHttpCode = -1;
private String mHttpPhrase = null;
private Exception mException = null;
private ResultCode mCode = ResultCode.UNKNOWN_ERROR;
private String mRedirectedLocation = "";
private List<String> mAuthenticate = new ArrayList<>();
private String mLastPermanentLocation = null;
private T mData = null;
/**
* Public constructor from result code.
* <p>
* To be used when the caller takes the responsibility of interpreting the result of a {@link RemoteOperation}
*
* @param code {@link ResultCode} decided by the caller.
*/
public RemoteOperationResult(ResultCode code) {
mCode = code;
mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL ||
code == ResultCode.OK_NO_SSL ||
code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION);
}
/**
* Create a new RemoteOperationResult based on the result given by a previous one.
* It does not copy the data.
*
* @param prevRemoteOperation
*/
public RemoteOperationResult(RemoteOperationResult prevRemoteOperation) {
mCode = prevRemoteOperation.mCode;
mHttpCode = prevRemoteOperation.mHttpCode;
mHttpPhrase = prevRemoteOperation.mHttpPhrase;
mAuthenticate = prevRemoteOperation.mAuthenticate;
mException = prevRemoteOperation.mException;
mLastPermanentLocation = prevRemoteOperation.mLastPermanentLocation;
mSuccess = prevRemoteOperation.mSuccess;
mRedirectedLocation = prevRemoteOperation.mRedirectedLocation;
}
/**
* Public constructor from exception.
* <p>
* To be used when an exception prevented the end of the {@link RemoteOperation}.
* <p>
* Determines a {@link ResultCode} depending on the type of the exception.
*
* @param e Exception that interrupted the {@link RemoteOperation}
*/
public RemoteOperationResult(Exception e) {
mException = e;
//TODO: Do propper exception handling and remove this
Timber.e("---------------------------------" +
"\nCreate RemoteOperationResult from exception." +
"\n Message: %s" +
"\n Stacktrace: %s" +
"\n---------------------------------",
ExceptionUtils.getMessage(e),
ExceptionUtils.getStackTrace(e));
if (e instanceof OperationCancelledException) {
mCode = ResultCode.CANCELLED;
} else if (e instanceof SocketException) {
mCode = ResultCode.WRONG_CONNECTION;
} else if (e instanceof SocketTimeoutException) {
mCode = ResultCode.TIMEOUT;
} else if (e instanceof MalformedURLException) {
mCode = ResultCode.INCORRECT_ADDRESS;
} else if (e instanceof UnknownHostException) {
mCode = ResultCode.HOST_NOT_AVAILABLE;
} else if (e instanceof AccountUtils.AccountNotFoundException) {
mCode = ResultCode.ACCOUNT_NOT_FOUND;
} else if (e instanceof AccountsException) {
mCode = ResultCode.ACCOUNT_EXCEPTION;
} else if (e instanceof SSLException || e instanceof RuntimeException) {
if (e instanceof SSLPeerUnverifiedException) {
mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
} else {
CertificateCombinedException se = getCertificateCombinedException(e);
if (se != null) {
mException = se;
if (se.isRecoverable()) {
mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
}
} else if (e instanceof RuntimeException) {
mCode = ResultCode.HOST_NOT_AVAILABLE;
} else {
mCode = ResultCode.SSL_ERROR;
}
}
} else if (e instanceof FileNotFoundException) {
mCode = ResultCode.LOCAL_FILE_NOT_FOUND;
} else if (e instanceof ProtocolException) {
mCode = ResultCode.NETWORK_ERROR;
}
else {
mCode = ResultCode.UNKNOWN_ERROR;
}
}
/**
* Public constructor from separate elements of an HTTP or DAV response.
* <p>
* To be used when the result needs to be interpreted from the response of an HTTP/DAV method.
* <p>
* Determines a {@link ResultCode} from the already executed method received as a parameter. Generally,
* will depend on the HTTP code and HTTP response headers received. In some cases will inspect also the
* response body
*
* @param httpMethod
* @throws IOException
*/
public RemoteOperationResult(HttpBaseMethod httpMethod) throws IOException {
this(httpMethod.getStatusCode(),
httpMethod.getStatusMessage(),
httpMethod.getResponseHeaders()
);
if (mHttpCode == HttpConstants.HTTP_BAD_REQUEST) { // 400
String bodyResponse = httpMethod.getResponseBodyAsString();
// do not get for other HTTP codes!; could not be available
if (bodyResponse != null && bodyResponse.length() > 0) {
InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
InvalidCharacterExceptionParser xmlParser = new InvalidCharacterExceptionParser();
try {
if (xmlParser.parseXMLResponse(is)) {
mCode = ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER;
} else {
parseErrorMessageAndSetCode(
httpMethod.getResponseBodyAsString(),
ResultCode.SPECIFIC_BAD_REQUEST
);
}
} catch (Exception e) {
Timber.w("Error reading exception from server: %s", e.getMessage());
// mCode stays as set in this(success, httpCode, headers)
}
}
}
// before
switch (mHttpCode) {
case HttpConstants.HTTP_FORBIDDEN:
parseErrorMessageAndSetCode(
httpMethod.getResponseBodyAsString(),
ResultCode.SPECIFIC_FORBIDDEN
);
break;
case HttpConstants.HTTP_UNSUPPORTED_MEDIA_TYPE:
parseErrorMessageAndSetCode(
httpMethod.getResponseBodyAsString(),
ResultCode.SPECIFIC_UNSUPPORTED_MEDIA_TYPE
);
break;
case HttpConstants.HTTP_SERVICE_UNAVAILABLE:
parseErrorMessageAndSetCode(
httpMethod.getResponseBodyAsString(),
ResultCode.SPECIFIC_SERVICE_UNAVAILABLE
);
break;
case HttpConstants.HTTP_METHOD_NOT_ALLOWED:
parseErrorMessageAndSetCode(
httpMethod.getResponseBodyAsString(),
ResultCode.SPECIFIC_METHOD_NOT_ALLOWED
);
break;
case HttpConstants.HTTP_TOO_EARLY:
mCode = ResultCode.TOO_EARLY;
break;
default:
break;
}
}
/**
* Public constructor from separate elements of an HTTP or DAV response.
* <p>
* To be used when the result needs to be interpreted from HTTP response elements that could come from
* different requests (WARNING: black magic, try to avoid).
* <p>
* <p>
* Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received.
*
* @param httpCode HTTP status code returned by an HTTP/DAV method.
* @param httpPhrase HTTP status line phrase returned by an HTTP/DAV method
* @param headers HTTP response header returned by an HTTP/DAV method
*/
public RemoteOperationResult(int httpCode, String httpPhrase, Headers headers) {
this(httpCode, httpPhrase);
if (headers != null) {
for (Map.Entry<String, List<String>> header : headers.toMultimap().entrySet()) {
if (LOCATION.equalsIgnoreCase(header.getKey())) {
mRedirectedLocation = header.getValue().get(0);
continue;
}
if (WWW_AUTHENTICATE.equalsIgnoreCase(header.getKey())) {
for (String value: header.getValue()) {
mAuthenticate.add(value.toLowerCase());
}
}
}
}
}
/**
* Private constructor for results built interpreting a HTTP or DAV response.
* <p>
* Determines a {@link ResultCode} depending of the type of the exception.
*
* @param httpCode HTTP status code returned by the HTTP/DAV method.
* @param httpPhrase HTTP status line phrase returned by the HTTP/DAV method
*/
private RemoteOperationResult(int httpCode, String httpPhrase) {
mHttpCode = httpCode;
mHttpPhrase = httpPhrase;
if (httpCode > 0) {
switch (httpCode) {
case HttpConstants.HTTP_UNAUTHORIZED: // 401
mCode = ResultCode.UNAUTHORIZED;
break;
case HttpConstants.HTTP_FORBIDDEN: // 403
mCode = ResultCode.FORBIDDEN;
break;
case HttpConstants.HTTP_NOT_FOUND: // 404
mCode = ResultCode.FILE_NOT_FOUND;
break;
case HttpConstants.HTTP_CONFLICT: // 409
mCode = ResultCode.CONFLICT;
break;
case HttpConstants.HTTP_INTERNAL_SERVER_ERROR: // 500
mCode = ResultCode.INSTANCE_NOT_CONFIGURED; // assuming too much...
break;
case HttpConstants.HTTP_SERVICE_UNAVAILABLE: // 503
mCode = ResultCode.SERVICE_UNAVAILABLE;
break;
case HttpConstants.HTTP_INSUFFICIENT_STORAGE: // 507
mCode = ResultCode.QUOTA_EXCEEDED; // surprise!
break;
default:
mCode = ResultCode.UNHANDLED_HTTP_CODE; // UNKNOWN ERROR
Timber.d("RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " + mHttpCode + " " + mHttpPhrase);
}
}
}
/**
* Parse the error message included in the body response, if any, and set the specific result
* code
*
* @param bodyResponse okHttp response body
* @param resultCode our own custom result code
*/
private void parseErrorMessageAndSetCode(String bodyResponse, ResultCode resultCode) {
if (bodyResponse != null && bodyResponse.length() > 0) {
InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
ErrorMessageParser xmlParser = new ErrorMessageParser();
try {
String errorMessage = xmlParser.parseXMLResponse(is);
if (!errorMessage.equals("")) {
mCode = resultCode;
mHttpPhrase = errorMessage;
}
} catch (Exception e) {
Timber.w("Error reading exception from server: %s\nTrace: %s", e.getMessage(), ExceptionUtils.getStackTrace(e));
// mCode stays as set in this(success, httpCode, headers)
}
}
}
public boolean isSuccess() {
return mSuccess;
}
public void setSuccess(boolean success) {
this.mSuccess = success;
}
public boolean isCancelled() {
return mCode == ResultCode.CANCELLED;
}
public int getHttpCode() {
return mHttpCode;
}
public String getHttpPhrase() {
return mHttpPhrase;
}
public ResultCode getCode() {
return mCode;
}
public Exception getException() {
return mException;
}
public boolean isSslRecoverableException() {
return mCode == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
}
public boolean isRedirectToNonSecureConnection() {
return mCode == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION;
}
private CertificateCombinedException getCertificateCombinedException(Exception e) {
CertificateCombinedException result = null;
if (e instanceof CertificateCombinedException) {
return (CertificateCombinedException) e;
}
Throwable cause = mException.getCause();
Throwable previousCause = null;
while (cause != null && cause != previousCause &&
!(cause instanceof CertificateCombinedException)) {
previousCause = cause;
cause = cause.getCause();
}
if (cause instanceof CertificateCombinedException) {
result = (CertificateCombinedException) cause;
}
return result;
}
public String getLogMessage() {
if (mException != null) {
if (mException instanceof OperationCancelledException) {
return "Operation cancelled by the caller";
} else if (mException instanceof SocketException) {
return "Socket exception";
} else if (mException instanceof SocketTimeoutException) {
return "Socket timeout exception";
} else if (mException instanceof MalformedURLException) {
return "Malformed URL exception";
} else if (mException instanceof UnknownHostException) {
return "Unknown host exception";
} else if (mException instanceof CertificateCombinedException) {
if (((CertificateCombinedException) mException).isRecoverable()) {
return "SSL recoverable exception";
} else {
return "SSL exception";
}
} else if (mException instanceof SSLException) {
return "SSL exception";
} else if (mException instanceof DavException) {
return "Unexpected WebDAV exception";
} else if (mException instanceof HttpException) {
return "HTTP violation";
} else if (mException instanceof IOException) {
return "Unrecovered transport exception";
} else if (mException instanceof AccountUtils.AccountNotFoundException) {
Account failedAccount =
((AccountUtils.AccountNotFoundException) mException).getFailedAccount();
return mException.getMessage() + " (" +
(failedAccount != null ? failedAccount.name : "NULL") + ")";
} else if (mException instanceof AccountsException) {
return "Exception while using account";
} else if (mException instanceof JSONException) {
return "JSON exception";
} else {
return "Unexpected exception";
}
}
if (mCode == ResultCode.INSTANCE_NOT_CONFIGURED) {
return "The ownCloud server is not configured!";
} else if (mCode == ResultCode.NO_NETWORK_CONNECTION) {
return "No network connection";
} else if (mCode == ResultCode.BAD_OC_VERSION) {
return "No valid ownCloud version was found at the server";
} else if (mCode == ResultCode.LOCAL_STORAGE_FULL) {
return "Local storage full";
} else if (mCode == ResultCode.LOCAL_STORAGE_NOT_MOVED) {
return "Error while moving file to final directory";
} else if (mCode == ResultCode.ACCOUNT_NOT_NEW) {
return "Account already existing when creating a new one";
} else if (mCode == ResultCode.ACCOUNT_NOT_THE_SAME) {
return "Authenticated with a different account than the one updating";
} else if (mCode == ResultCode.INVALID_CHARACTER_IN_NAME) {
return "The file name contains an forbidden character";
} else if (mCode == ResultCode.FILE_NOT_FOUND) {
return "Local file does not exist";
} else if (mCode == ResultCode.SYNC_CONFLICT) {
return "Synchronization conflict";
}
return "Operation finished with HTTP status code " + mHttpCode + " (" +
(isSuccess() ? "success" : "fail") + ")";
}
public boolean isServerFail() {
return (mHttpCode >= HttpConstants.HTTP_INTERNAL_SERVER_ERROR);
}
public boolean isException() {
return (mException != null);
}
public boolean isTemporalRedirection() {
return (mHttpCode == 302 || mHttpCode == 307);
}
public String getRedirectedLocation() {
return mRedirectedLocation;
}
/**
* Checks if is a non https connection
*
* @return boolean true/false
*/
public boolean isNonSecureRedirection() {
return (mRedirectedLocation != null && !(mRedirectedLocation.toLowerCase().startsWith("https://")));
}
public List<String> getAuthenticateHeaders() {
return mAuthenticate;
}
public String getLastPermanentLocation() {
return mLastPermanentLocation;
}
public void setLastPermanentLocation(String lastPermanentLocation) {
mLastPermanentLocation = lastPermanentLocation;
}
public T getData() {
return mData;
}
public void setData(T data) {
mData = data;
}
public void setHttpPhrase(String httpPhrase) {
mHttpPhrase = httpPhrase;
}
public enum ResultCode {
OK,
OK_SSL,
OK_NO_SSL,
UNHANDLED_HTTP_CODE,
UNAUTHORIZED,
FILE_NOT_FOUND,
INSTANCE_NOT_CONFIGURED,
UNKNOWN_ERROR,
WRONG_CONNECTION,
TIMEOUT,
INCORRECT_ADDRESS,
HOST_NOT_AVAILABLE,
NO_NETWORK_CONNECTION,
SSL_ERROR,
SSL_RECOVERABLE_PEER_UNVERIFIED,
BAD_OC_VERSION,
CANCELLED,
INVALID_LOCAL_FILE_NAME,
INVALID_OVERWRITE,
CONFLICT,
OAUTH2_ERROR,
SYNC_CONFLICT,
LOCAL_STORAGE_FULL,
LOCAL_STORAGE_NOT_MOVED,
LOCAL_STORAGE_NOT_COPIED,
OAUTH2_ERROR_ACCESS_DENIED,
QUOTA_EXCEEDED,
ACCOUNT_NOT_FOUND,
ACCOUNT_EXCEPTION,
ACCOUNT_NOT_NEW,
ACCOUNT_NOT_THE_SAME,
INVALID_CHARACTER_IN_NAME,
SHARE_NOT_FOUND,
LOCAL_STORAGE_NOT_REMOVED,
FORBIDDEN,
SHARE_FORBIDDEN,
SPECIFIC_FORBIDDEN,
OK_REDIRECT_TO_NON_SECURE_CONNECTION,
INVALID_MOVE_INTO_DESCENDANT,
INVALID_COPY_INTO_DESCENDANT,
PARTIAL_MOVE_DONE,
PARTIAL_COPY_DONE,
SHARE_WRONG_PARAMETER,
WRONG_SERVER_RESPONSE,
INVALID_CHARACTER_DETECT_IN_SERVER,
DELAYED_FOR_WIFI,
LOCAL_FILE_NOT_FOUND,
SERVICE_UNAVAILABLE,
SPECIFIC_SERVICE_UNAVAILABLE,
SPECIFIC_UNSUPPORTED_MEDIA_TYPE,
SPECIFIC_METHOD_NOT_ALLOWED,
SPECIFIC_BAD_REQUEST,
TOO_EARLY,
NETWORK_ERROR,
}
}

View File

@ -0,0 +1,29 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.utils
fun Any.isOneOf(vararg values: Any): Boolean {
return this in values
}

View File

@ -1,78 +1,48 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2022 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
package com.owncloud.android.lib.resources.shares; package com.owncloud.android.lib.common.utils
/** import info.hannes.timber.FileLoggingTree
* Enum for Share Type, with values: import info.hannes.timber.fileLoggingTree
* -1 - No shared import timber.log.Timber
* 0 - Shared by user import java.io.File
* 1 - Shared by group
* 3 - Shared by public link
* 4 - Shared by e-mail
* 5 - Shared by contact
*
* @author masensio
*
*/
public enum ShareType { object LoggingHelper {
NO_SHARED (-1),
USER (0), fun startLogging(directory: File, storagePath: String) {
GROUP (1), fileLoggingTree()?.let {
PUBLIC_LINK (3), Timber.uproot(it)
EMAIL (4),
CONTACT (5);
private int value;
private ShareType(int value)
{
this.value = value;
}
public int getValue() {
return value;
}
public static ShareType fromValue(int value)
{
switch (value)
{
case -1:
return NO_SHARED;
case 0:
return USER;
case 1:
return GROUP;
case 3:
return PUBLIC_LINK;
case 4:
return EMAIL;
case 5:
return CONTACT;
} }
return null; if (!directory.exists())
directory.mkdirs()
Timber.plant(FileLoggingTree(directory, filename = storagePath))
} }
};
fun stopLogging() {
fileLoggingTree()?.let {
Timber.uproot(it)
}
}
}

View File

@ -0,0 +1,70 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.common.utils;
import java.util.Random;
import java.util.UUID;
/**
* Class with methods to generate random values
*
* @author David González Verdugo
*/
public class RandomUtils {
private static final String CANDIDATECHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"1234567890-+/_=.:";
/**
* @param length the number of random chars to be generated
* @return String containing random chars
*/
public static String generateRandomString(int length) {
StringBuilder sb = new StringBuilder();
Random random = new Random();
for (int i = 0; i < length; i++) {
sb.append(CANDIDATECHARS.charAt(random.nextInt(CANDIDATECHARS.length())));
}
return sb.toString();
}
/**
* @param min minimum integer to obtain randomly
* @param max maximum integer to obtain randomly
* @return random integer between min and max
*/
public static int generateRandomInteger(int min, int max) {
Random r = new Random();
return r.nextInt(max - min) + min;
}
/**
* @return random UUID
*/
public static String generateRandomUUID() {
return UUID.randomUUID().toString();
}
}

View File

@ -0,0 +1,52 @@
/* ownCloud Android Library is available under MIT license
*
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.owncloud.android.lib.resources
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
// Response retrieved by OCS Rest API, used to obtain capabilities, shares and user info among others.
// More info: https://doc.owncloud.com/server/developer_manual/core/apis/ocs-capabilities.html
@JsonClass(generateAdapter = true)
data class CommonOcsResponse<T>(
val ocs: OCSResponse<T>
)
@JsonClass(generateAdapter = true)
data class OCSResponse<T>(
val meta: MetaData,
val data: T?
)
@JsonClass(generateAdapter = true)
data class MetaData(
val status: String,
@Json(name = "statuscode")
val statusCode: Int,
val message: String?,
@Json(name = "itemsperpage")
val itemsPerPage: String?,
@Json(name = "totalitems")
val totalItems: String?
)

View File

@ -1,42 +1,37 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2022 ownCloud GmbH.
* *
* @author David González Verdugo
*
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
* *
*/ */
package com.owncloud.android.lib.resources.shares; package com.owncloud.android.lib.resources
import com.owncloud.android.lib.common.OwnCloudClient
/** /**
* Contains Constants for Share Operation * Facade to perform network calls without the verbosity of remote operations
*
* @author masensio
*
*/ */
public class ShareUtils { interface Service {
val client: OwnCloudClient
// OCS Route
public static final String SHARING_API_PATH ="/ocs/v1.php/apps/files_sharing/api/v1/shares";
// String to build the link with the token of a share: server address + "/public.php?service=files&t=" + token
public static final String SHARING_LINK_TOKEN = "/public.php?service=files&t=";
} }

View File

@ -0,0 +1,108 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.appregistry
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.Moshi
import okhttp3.FormBody
import okhttp3.RequestBody
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
class CreateRemoteFileWithAppProviderOperation(
private val createFileWithAppProviderEndpoint: String,
private val parentContainerId: String,
private val filename: String,
) : RemoteOperation<String>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<String> {
return try {
val createFileWithAppProviderRequestBody = CreateFileWithAppProviderParams(parentContainerId, filename)
.toRequestBody()
val stringUrl = client.baseUri.toString() + WebdavUtils.encodePath(createFileWithAppProviderEndpoint)
val postMethod = PostMethod(URL(stringUrl), createFileWithAppProviderRequestBody).apply {
setReadTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
setConnectionTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
}
val status = client.executeHttpMethod(postMethod)
Timber.d("Create file $filename with app provider in folder with ID $parentContainerId - $status${if (!isSuccess(status)) "(FAIL)" else ""}")
if (isSuccess(status)) RemoteOperationResult<String>(ResultCode.OK).apply {
val moshi = Moshi.Builder().build()
val adapter: JsonAdapter<CreateFileWithAppProviderResponse> = moshi.adapter(CreateFileWithAppProviderResponse::class.java)
data = postMethod.getResponseBodyAsString()?.let { adapter.fromJson(it)!!.fileId }
}
else RemoteOperationResult<String>(postMethod).apply { data = "" }
} catch (e: Exception) {
val result = RemoteOperationResult<String>(e)
Timber.e(e, "Create file $filename with app provider in folder with ID $parentContainerId failed")
result
}
}
private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK
data class CreateFileWithAppProviderParams(
val parentContainerId: String,
val filename: String,
) {
fun toRequestBody(): RequestBody =
FormBody.Builder()
.add(PARAM_PARENT_CONTAINER_ID, parentContainerId)
.add(PARAM_FILENAME, filename)
.build()
companion object {
const val PARAM_PARENT_CONTAINER_ID = "parent_container_id"
const val PARAM_FILENAME = "filename"
}
}
@JsonClass(generateAdapter = true)
data class CreateFileWithAppProviderResponse(
@Json(name = "file_id")
val fileId: String,
)
companion object {
private const val TIMEOUT: Long = 5_000
}
}

View File

@ -0,0 +1,78 @@
/* ownCloud Android Library is available under MIT license
* @author Abel García de Prada
*
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.appregistry
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK
import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import timber.log.Timber
import java.net.URL
class GetRemoteAppRegistryOperation(private val appUrl: String?) : RemoteOperation<AppRegistryResponse>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<AppRegistryResponse> {
var result: RemoteOperationResult<AppRegistryResponse>
try {
val uriBuilder = client.baseUri.buildUpon().apply {
appendEncodedPath(appUrl)
}
val getMethod = GetMethod(URL(uriBuilder.build().toString()))
val status = client.executeHttpMethod(getMethod)
val response = getMethod.getResponseBodyAsString()
if (status == HttpConstants.HTTP_OK) {
Timber.d("Successful response $response")
// Parse the response
val moshi: Moshi = Moshi.Builder().build()
val adapter: JsonAdapter<AppRegistryResponse> = moshi.adapter(AppRegistryResponse::class.java)
val appRegistryResponse: AppRegistryResponse = response?.let { adapter.fromJson(it) } ?: AppRegistryResponse(value = emptyList())
result = RemoteOperationResult(OK)
result.data = appRegistryResponse
Timber.d("Get AppRegistry completed and parsed to ${result.data}")
} else {
result = RemoteOperationResult(getMethod)
Timber.e("Failed response while getting app registry from the server status code: $status; response message: $response")
}
} catch (e: Exception) {
result = RemoteOperationResult(e)
Timber.e(e, "Exception while getting app registry")
}
return result
}
}

View File

@ -0,0 +1,107 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.appregistry
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.Moshi
import okhttp3.FormBody
import okhttp3.RequestBody
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
class GetUrlToOpenInWebRemoteOperation(
private val openWithWebEndpoint: String,
private val fileId: String,
private val appName: String,
) : RemoteOperation<String>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<String> {
return try {
val openInWebRequestBody = OpenInWebParams(fileId, appName).toRequestBody()
val stringUrl =
client.baseUri.toString() + WebdavUtils.encodePath(openWithWebEndpoint)
val postMethod = PostMethod(URL(stringUrl), openInWebRequestBody).apply {
setReadTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
setConnectionTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
}
val status = client.executeHttpMethod(postMethod)
Timber.d("Open in web for file: $fileId - $status${if (!isSuccess(status)) "(FAIL)" else ""}")
if (isSuccess(status)) RemoteOperationResult<String>(ResultCode.OK).apply {
val moshi = Moshi.Builder().build()
val adapter: JsonAdapter<OpenInWebResponse> = moshi.adapter(OpenInWebResponse::class.java)
data = postMethod.getResponseBodyAsString()?.let { adapter.fromJson(it)!!.uri }
}
else RemoteOperationResult<String>(postMethod).apply { data = "" }
} catch (e: Exception) {
val result = RemoteOperationResult<String>(e)
Timber.e(e, "Open in web for file: $fileId failed")
result
}
}
private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK
data class OpenInWebParams(
val fileId: String,
val appName: String,
) {
fun toRequestBody(): RequestBody =
FormBody.Builder()
.add(PARAM_FILE_ID, fileId)
.add(PARAM_APP_NAME, appName)
.build()
companion object {
const val PARAM_FILE_ID = "file_id"
const val PARAM_APP_NAME = "app_name"
}
}
@JsonClass(generateAdapter = true)
data class OpenInWebResponse(val uri: String)
companion object {
/**
* Maximum time to wait for a response from the server in milliseconds.
*/
private const val TIMEOUT = 5_000L
}
}

View File

@ -0,0 +1,56 @@
/* ownCloud Android Library is available under MIT license
* @author Abel García de Prada
*
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.appregistry.responses
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class AppRegistryResponse(
@Json(name = "mime-types")
val value: List<AppRegistryMimeTypeResponse>
)
@JsonClass(generateAdapter = true)
data class AppRegistryMimeTypeResponse(
@Json(name = "mime_type") val mimeType: String,
val ext: String? = null,
@Json(name = "app_providers")
val appProviders: List<AppRegistryProviderResponse>,
val name: String? = null,
val icon: String? = null,
val description: String? = null,
@Json(name = "allow_creation")
val allowCreation: Boolean? = null,
@Json(name = "default_application")
val defaultApplication: String? = null
)
@JsonClass(generateAdapter = true)
data class AppRegistryProviderResponse(
val name: String,
val icon: String,
)

View File

@ -1,55 +1,44 @@
/* ownCloud Android Library is available under MIT license /* ownCloud Android Library is available under MIT license
* Copyright (C) 2015 ownCloud Inc. * Copyright (C) 2023 ownCloud GmbH.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights * in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is * copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions: * furnished to do so, subject to the following conditions:
* *
* The above copyright notice and this permission notice shall be included in * The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software. * all copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*
*/ */
package com.owncloud.android.lib.test_project.test; package com.owncloud.android.lib.resources.appregistry.services
import android.content.Context; import com.owncloud.android.lib.common.operations.RemoteOperationResult
import android.util.Log; import com.owncloud.android.lib.resources.Service
import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse
import com.owncloud.android.lib.common.operations.RemoteOperationResult; interface AppRegistryService : Service {
import com.owncloud.android.lib.test_project.R; fun getAppRegistry(appUrl: String?): RemoteOperationResult<AppRegistryResponse>
public class Utils { fun getUrlToOpenInWeb(
openWebEndpoint: String,
fileId: String,
appName: String,
): RemoteOperationResult<String>
private static String LOG_TAG = Utils.class.getSimpleName(); fun createFileWithAppProvider(
createFileWithAppProviderEndpoint: String,
private static String sBuildNumber = null; parentContainerId: String,
filename: String,
public static void logAndThrow(String tag, RemoteOperationResult result) throws Exception { ): RemoteOperationResult<String>
Log.e(tag, result.getLogMessage(), result.getException());
throw new Exception(result.getLogMessage(), result.getException());
}
public static String getBuildNumber(Context context) {
if (sBuildNumber == null) {
sBuildNumber = context.getString(R.string.build_number);
if (sBuildNumber == null || sBuildNumber.length() == 0) {
Log.w(LOG_TAG, "Build number unknown, using current time instead");
sBuildNumber = Long.toString(System.currentTimeMillis());
}
}
return sBuildNumber;
}
} }

View File

@ -0,0 +1,54 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.owncloud.android.lib.resources.appregistry.services
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.resources.appregistry.CreateRemoteFileWithAppProviderOperation
import com.owncloud.android.lib.resources.appregistry.GetRemoteAppRegistryOperation
import com.owncloud.android.lib.resources.appregistry.GetUrlToOpenInWebRemoteOperation
import com.owncloud.android.lib.resources.appregistry.responses.AppRegistryResponse
class OCAppRegistryService(override val client: OwnCloudClient) : AppRegistryService {
override fun getAppRegistry(appUrl: String?): RemoteOperationResult<AppRegistryResponse> =
GetRemoteAppRegistryOperation(appUrl).execute(client)
override fun getUrlToOpenInWeb(openWebEndpoint: String, fileId: String, appName: String): RemoteOperationResult<String> =
GetUrlToOpenInWebRemoteOperation(
openWithWebEndpoint = openWebEndpoint,
fileId = fileId,
appName = appName
).execute(client)
override fun createFileWithAppProvider(
createFileWithAppProviderEndpoint: String,
parentContainerId: String,
filename: String
): RemoteOperationResult<String> =
CreateRemoteFileWithAppProviderOperation(
createFileWithAppProviderEndpoint = createFileWithAppProviderEndpoint,
parentContainerId = parentContainerId,
filename = filename,
).execute(client)
}

View File

@ -0,0 +1,96 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.webdav.DavUtils.allPropSet
import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
/**
* Operation to check the existence of a path in a remote server.
*
* @author David A. Velasco
* @author David González Verdugo
* @author Abel García de Prada
* @author Juan Carlos Garrote Gascón
*
* @param remotePath Path to append to the URL owned by the client instance.
* @param isUserLoggedIn When `true`, the username won't be added at the end of the PROPFIND url since is not
* needed to check user credentials
*/
class CheckPathExistenceRemoteOperation(
val remotePath: String? = "",
val isUserLoggedIn: Boolean,
val spaceWebDavUrl: String? = null,
) : RemoteOperation<Boolean>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<Boolean> {
val baseStringUrl = spaceWebDavUrl ?: if (isUserLoggedIn) client.userFilesWebDavUri.toString() else client.baseFilesWebDavUri.toString()
val stringUrl = if (isUserLoggedIn) baseStringUrl + WebdavUtils.encodePath(remotePath) else baseStringUrl
return try {
val propFindMethod = PropfindMethod(URL(stringUrl), 0, allPropSet).apply {
setReadTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS)
setConnectionTimeout(TIMEOUT.toLong(), TimeUnit.SECONDS)
}
val status = client.executeHttpMethod(propFindMethod)
/* PROPFIND method
* 404 NOT FOUND: path doesn't exist,
* 207 MULTI_STATUS: path exists.
*/
Timber.d(
"Existence check for $stringUrl finished with HTTP status $status${if (!isSuccess(status)) "(FAIL)" else ""}"
)
if (isSuccess(status)) RemoteOperationResult<Boolean>(ResultCode.OK).apply { data = true }
else RemoteOperationResult<Boolean>(propFindMethod).apply { data = false }
} catch (e: Exception) {
val result = RemoteOperationResult<Boolean>(e)
Timber.e(
e,
"Existence check for $stringUrl : ${result.logMessage}"
)
result.data = false
result
}
}
private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS
companion object {
/**
* Maximum time to wait for a response from the server in milliseconds.
*/
private const val TIMEOUT = 10000
}
}

View File

@ -0,0 +1,133 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.webdav.CopyMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.owncloud.android.lib.common.utils.isOneOf
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
/**
* Remote operation copying a remote file or folder in the ownCloud server to a different folder
* in the same account.
*
* Allows renaming the copying file/folder at the same time.
*
* @author David A. Velasco
* @author Christian Schabesberger
* @author David González V.
* @author Juan Carlos Garrote Gascón
* @author Manuel Plazas Palacio
*
* @param sourceRemotePath Remote path of the file/folder to copy.
* @param targetRemotePath Remote path desired for the file/folder to copy it.
*/
class CopyRemoteFileOperation(
private val sourceRemotePath: String,
private val targetRemotePath: String,
private val sourceSpaceWebDavUrl: String? = null,
private val targetSpaceWebDavUrl: String? = null,
private val forceOverride: Boolean = false,
) : RemoteOperation<String>() {
/**
* Performs the rename operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
override fun run(client: OwnCloudClient): RemoteOperationResult<String> {
if (targetRemotePath == sourceRemotePath && sourceSpaceWebDavUrl == targetSpaceWebDavUrl) {
// nothing to do!
return RemoteOperationResult(ResultCode.OK)
}
if (targetRemotePath.startsWith(sourceRemotePath) && sourceSpaceWebDavUrl == targetSpaceWebDavUrl) {
return RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT)
}
/// perform remote operation
var result: RemoteOperationResult<String>
try {
val copyMethod = CopyMethod(
url = URL((sourceSpaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(sourceRemotePath)),
destinationUrl = (targetSpaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(targetRemotePath),
forceOverride = forceOverride,
).apply {
addRequestHeaders(this)
setReadTimeout(COPY_READ_TIMEOUT, TimeUnit.SECONDS)
setConnectionTimeout(COPY_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
}
val status = client.executeHttpMethod(copyMethod)
when {
isSuccess(status) -> {
val fileRemoteId = copyMethod.getResponseHeader(HttpConstants.OC_FILE_REMOTE_ID)
result = RemoteOperationResult(ResultCode.OK)
result.setData(fileRemoteId)
}
isPreconditionFailed(status) -> {
result = RemoteOperationResult(ResultCode.INVALID_OVERWRITE)
client.exhaustResponse(copyMethod.getResponseBodyAsStream())
/// for other errors that could be explicitly handled, check first:
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
}
else -> {
result = RemoteOperationResult(copyMethod)
client.exhaustResponse(copyMethod.getResponseBodyAsStream())
}
}
Timber.i("Copy $sourceRemotePath to $targetRemotePath: ${result.logMessage}")
} catch (e: Exception) {
result = RemoteOperationResult(e)
Timber.e(e, "Copy $sourceRemotePath to $targetRemotePath: ${result.logMessage}")
}
return result
}
private fun addRequestHeaders(copyMethod: CopyMethod) {
//Adding this because the library has an error with override
if (copyMethod.forceOverride) {
copyMethod.setRequestHeader(OVERWRITE, TRUE)
}
}
private fun isSuccess(status: Int) = status.isOneOf(HttpConstants.HTTP_CREATED, HttpConstants.HTTP_NO_CONTENT)
private fun isPreconditionFailed(status: Int) = status == HttpConstants.HTTP_PRECONDITION_FAILED
companion object {
private const val COPY_READ_TIMEOUT = 10L
private const val COPY_CONNECTION_TIMEOUT = 6L
private const val OVERWRITE = "overwrite"
private const val TRUE = "T"
}
}

View File

@ -0,0 +1,110 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.webdav.MkColMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
/**
* Remote operation performing the creation of a new folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*
* @param remotePath Full path to the new directory to create in the remote server.
* @param createFullPath 'True' means that all the ancestor folders should be created.
*/
class CreateRemoteFolderOperation(
val remotePath: String,
private val createFullPath: Boolean,
private val isChunksFolder: Boolean = false,
val spaceWebDavUrl: String? = null,
) : RemoteOperation<Unit>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
var result = createFolder(client)
if (!result.isSuccess && createFullPath && result.code == ResultCode.CONFLICT) {
result = createParentFolder(FileUtils.getParentPath(remotePath), client)
if (result.isSuccess) {
// Second and last try
result = createFolder(client)
}
}
return result
}
private fun createFolder(client: OwnCloudClient): RemoteOperationResult<Unit> {
var result: RemoteOperationResult<Unit>
try {
val webDavUri = if (isChunksFolder) {
client.uploadsWebDavUri.toString()
} else {
spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
}
val mkCol = MkColMethod(
URL(webDavUri + WebdavUtils.encodePath(remotePath))
).apply {
setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
setConnectionTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
}
val status = client.executeHttpMethod(mkCol)
result =
if (status == HttpConstants.HTTP_CREATED) {
RemoteOperationResult(ResultCode.OK)
} else {
RemoteOperationResult(mkCol)
}
Timber.d("Create directory $remotePath: ${result.logMessage}")
client.exhaustResponse(mkCol.getResponseBodyAsStream())
} catch (e: Exception) {
result = RemoteOperationResult(e)
Timber.e(e, "Create directory $remotePath: ${result.logMessage}")
}
return result
}
private fun createParentFolder(parentPath: String, client: OwnCloudClient): RemoteOperationResult<Unit> {
val operation: RemoteOperation<Unit> = CreateRemoteFolderOperation(parentPath, createFullPath)
return operation.execute(client)
}
companion object {
private const val READ_TIMEOUT: Long = 30_000
private const val CONNECTION_TIMEOUT: Long = 5_000
}
}

View File

@ -0,0 +1,185 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.nonwebdav.GetMethod
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.OperationCancelledException
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import timber.log.Timber
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.net.URL
import java.util.concurrent.atomic.AtomicBoolean
/**
* Remote operation performing the download of a remote file in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
class DownloadRemoteFileOperation(
private val remotePath: String,
localFolderPath: String,
private val spaceWebDavUrl: String? = null,
) : RemoteOperation<Unit>() {
private val cancellationRequested = AtomicBoolean(false)
private val dataTransferListeners: MutableSet<OnDatatransferProgressListener> = HashSet()
var modificationTimestamp: Long = 0
private set
var etag: String = ""
private set
override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
// download will be performed to a temporal file, then moved to the final location
val tmpFile = File(tmpPath)
// perform the download
return try {
tmpFile.parentFile?.mkdirs()
downloadFile(client, tmpFile).also { result ->
Timber.i("Download of $remotePath to $tmpPath: ${result.logMessage}")
}
} catch (e: Exception) {
RemoteOperationResult<Unit>(e).also { result ->
Timber.e(e, "Download of $remotePath to $tmpPath: ${result.logMessage}")
}
}
}
@Throws(Exception::class)
private fun downloadFile(client: OwnCloudClient, targetFile: File): RemoteOperationResult<Unit> {
val result: RemoteOperationResult<Unit>
var it: Iterator<OnDatatransferProgressListener>
var fos: FileOutputStream? = null
var bis: BufferedInputStream? = null
var savedFile = false
val webDavUri = spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
val getMethod = GetMethod(URL(webDavUri + WebdavUtils.encodePath(remotePath)))
try {
val status = client.executeHttpMethod(getMethod)
if (isSuccess(status)) {
targetFile.createNewFile()
bis = BufferedInputStream(getMethod.getResponseBodyAsStream())
fos = FileOutputStream(targetFile)
var transferred: Long = 0
val contentLength = getMethod.getResponseHeader(HttpConstants.CONTENT_LENGTH_HEADER)
val totalToTransfer = if (!contentLength.isNullOrEmpty()) {
contentLength.toLong()
} else {
0
}
val bytes = ByteArray(4096)
var readResult: Int
while (bis.read(bytes).also { readResult = it } != -1) {
synchronized(cancellationRequested) {
if (cancellationRequested.get()) {
getMethod.abort()
throw OperationCancelledException()
}
}
fos.write(bytes, 0, readResult)
transferred += readResult.toLong()
synchronized(dataTransferListeners) {
it = dataTransferListeners.iterator()
while (it.hasNext()) {
it.next()
.onTransferProgress(readResult.toLong(), transferred, totalToTransfer, targetFile.name)
}
}
}
if (transferred == totalToTransfer) { // Check if the file is completed
savedFile = true
val modificationTime =
getMethod.getResponseHeaders()?.get("Last-Modified")
?: getMethod.getResponseHeader("last-modified")
if (modificationTime != null) {
val modificationDate = WebdavUtils.parseResponseDate(modificationTime)
modificationTimestamp = modificationDate?.time ?: 0
} else {
Timber.e("Could not read modification time from response downloading %s", remotePath)
}
etag = WebdavUtils.getEtagFromResponse(getMethod)
// Get rid of extra quotas
etag = etag.replace("\"", "")
if (etag.isEmpty()) {
Timber.e("Could not read eTag from response downloading %s", remotePath)
}
} else {
Timber.e("Content-Length not equal to transferred bytes.")
Timber.d("totalToTransfer = $totalToTransfer, transferred = $transferred")
client.exhaustResponse(getMethod.getResponseBodyAsStream())
// TODO some kind of error control!
}
} else if (status != HttpConstants.HTTP_FORBIDDEN && status != HttpConstants.HTTP_SERVICE_UNAVAILABLE) {
client.exhaustResponse(getMethod.getResponseBodyAsStream())
} // else, body read by RemoteOperationResult constructor
result =
if (isSuccess(status)) {
RemoteOperationResult(RemoteOperationResult.ResultCode.OK)
} else {
RemoteOperationResult(getMethod)
}
} finally {
fos?.close()
bis?.close()
if (!savedFile && targetFile.exists()) {
targetFile.delete()
}
}
return result
}
private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK
private val tmpPath: String = localFolderPath + remotePath
fun addDatatransferProgressListener(listener: OnDatatransferProgressListener) {
synchronized(dataTransferListeners) { dataTransferListeners.add(listener) }
}
fun removeDatatransferProgressListener(listener: OnDatatransferProgressListener?) {
synchronized(dataTransferListeners) { dataTransferListeners.remove(listener) }
}
fun cancel() {
cancellationRequested.set(true) // atomic set; there is no need of synchronizing it
}
}

View File

@ -0,0 +1,57 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files;
import timber.log.Timber;
import java.io.File;
public class FileUtils {
public static final String FINAL_CHUNKS_FILE = ".file";
public static final String MIME_DIR = "DIR";
public static final String MIME_DIR_UNIX = "httpd/unix-directory";
public static final String MODE_READ_ONLY = "r";
static String getParentPath(String remotePath) {
String parentPath = new File(remotePath).getParent();
parentPath = parentPath.endsWith(File.separator) ? parentPath : parentPath + File.separator;
return parentPath;
}
/**
* Validate the fileName to detect if contains any forbidden character: / , \ , < , > ,
* : , " , | , ? , *
*
*/
public static boolean isValidName(String fileName) {
boolean result = true;
Timber.d("fileName =======%s", fileName);
if (fileName.contains(File.separator)) {
result = false;
}
return result;
}
}

View File

@ -0,0 +1,77 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2022 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.webdav.DavUtils
import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
/**
* Operation to get the base url, which might differ in case of a redirect.
*
* @author Christian Schabesberger
*/
class GetBaseUrlRemoteOperation : RemoteOperation<String?>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<String?> {
return try {
val stringUrl = client.baseFilesWebDavUri.toString()
val propFindMethod = PropfindMethod(URL(stringUrl), 0, DavUtils.allPropSet).apply {
setReadTimeout(TIMEOUT, TimeUnit.SECONDS)
setConnectionTimeout(TIMEOUT, TimeUnit.SECONDS)
}
val status = client.executeHttpMethod(propFindMethod)
if (isSuccess(status)) {
RemoteOperationResult<String?>(RemoteOperationResult.ResultCode.OK).apply {
data = propFindMethod.getFinalUrl().toString()
}
} else {
RemoteOperationResult<String?>(propFindMethod).apply {
data = null
}
}
} catch (e: Exception) {
Timber.e(e, "Could not get actuall (or redirected) base URL from base url (/).")
RemoteOperationResult<String?>(e)
}
}
private fun isSuccess(status: Int) = status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS
companion object {
/**
* Maximum time to wait for a response from the server in milliseconds.
*/
private const val TIMEOUT = 10_000L
}
}

View File

@ -0,0 +1,149 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2023 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import android.net.Uri
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.webdav.MoveMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.owncloud.android.lib.common.utils.isOneOf
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
/**
* Remote operation moving a remote file or folder in the ownCloud server to a different folder
* in the same account and space.
*
* Allows renaming the moving file/folder at the same time.
*
* @author David A. Velasco
* @author David González Verdugo
* @author Abel García de Prada
* @author Juan Carlos Garrote Gascón
* @author Manuel Plazas Palacio
*
* @param sourceRemotePath Remote path of the file/folder to copy.
* @param targetRemotePath Remote path desired for the file/folder to copy it.
*/
open class MoveRemoteFileOperation(
private val sourceRemotePath: String,
private val targetRemotePath: String,
private val spaceWebDavUrl: String? = null,
private val forceOverride: Boolean = false,
) : RemoteOperation<Unit>() {
/**
* Performs the rename operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
if (targetRemotePath == sourceRemotePath) {
// nothing to do!
return RemoteOperationResult(ResultCode.OK)
}
if (targetRemotePath.startsWith(sourceRemotePath)) {
return RemoteOperationResult(ResultCode.INVALID_MOVE_INTO_DESCENDANT)
}
/// perform remote operation
var result: RemoteOperationResult<Unit>
try {
// After finishing a chunked upload, we have to move the resulting file from uploads folder to files one,
// so this uri has to be customizable
val srcWebDavUri = getSrcWebDavUriForClient(client)
val moveMethod = MoveMethod(
url = URL((spaceWebDavUrl ?: srcWebDavUri.toString()) + WebdavUtils.encodePath(sourceRemotePath)),
destinationUrl = (spaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(targetRemotePath),
forceOverride = forceOverride,
).apply {
addRequestHeaders(this)
setReadTimeout(MOVE_READ_TIMEOUT, TimeUnit.SECONDS)
setConnectionTimeout(MOVE_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
}
val status = client.executeHttpMethod(moveMethod)
when {
isSuccess(status) -> {
result = RemoteOperationResult<Unit>(ResultCode.OK)
}
isPreconditionFailed(status) -> {
result = RemoteOperationResult<Unit>(ResultCode.INVALID_OVERWRITE)
client.exhaustResponse(moveMethod.getResponseBodyAsStream())
/// for other errors that could be explicitly handled, check first:
/// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
}
else -> {
result = RemoteOperationResult<Unit>(moveMethod)
client.exhaustResponse(moveMethod.getResponseBodyAsStream())
}
}
Timber.i("Move $sourceRemotePath to $targetRemotePath: ${result.logMessage}")
} catch (e: Exception) {
result = RemoteOperationResult<Unit>(e)
Timber.e(e, "Move $sourceRemotePath to $targetRemotePath: ${result.logMessage}")
}
return result
}
/**
* For standard moves, we will use [OwnCloudClient.getUserFilesWebDavUri].
* In case we need a different source Uri, override this method.
*/
open fun getSrcWebDavUriForClient(client: OwnCloudClient): Uri = client.userFilesWebDavUri
/**
* For standard moves, we won't need any special headers.
* In case new headers are needed, override this method
*/
open fun addRequestHeaders(moveMethod: MoveMethod) {
//Adding this because the library has an error with override
if (moveMethod.forceOverride) {
moveMethod.setRequestHeader(OVERWRITE, TRUE)
}
}
private fun isSuccess(status: Int) = status.isOneOf(HttpConstants.HTTP_CREATED, HttpConstants.HTTP_NO_CONTENT)
private fun isPreconditionFailed(status: Int) = status == HttpConstants.HTTP_PRECONDITION_FAILED
companion object {
private const val MOVE_READ_TIMEOUT = 10L
private const val MOVE_CONNECTION_TIMEOUT = 6L
private const val OVERWRITE = "overwrite"
private const val TRUE = "T"
}
}

View File

@ -0,0 +1,107 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2016 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.accounts.AccountUtils
import com.owncloud.android.lib.common.http.HttpConstants.HTTP_MULTI_STATUS
import com.owncloud.android.lib.common.http.HttpConstants.HTTP_OK
import com.owncloud.android.lib.common.http.methods.webdav.DavConstants.DEPTH_0
import com.owncloud.android.lib.common.http.methods.webdav.DavUtils
import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.utils.isOneOf
import timber.log.Timber
import java.net.URL
import java.util.concurrent.TimeUnit
/**
* Remote operation performing the read a file from the ownCloud server.
*
* @author David A. Velasco
* @author masensio
* @author David González Verdugo
*/
class ReadRemoteFileOperation(
val remotePath: String,
val spaceWebDavUrl: String? = null,
) : RemoteOperation<RemoteFile>() {
/**
* Performs the read operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
@Override
override fun run(client: OwnCloudClient): RemoteOperationResult<RemoteFile> {
try {
val propFind = PropfindMethod(
url = getFinalWebDavUrl(),
depth = DEPTH_0,
propertiesToRequest = DavUtils.allPropSet
).apply {
setReadTimeout(SYNC_READ_TIMEOUT, TimeUnit.SECONDS)
setConnectionTimeout(SYNC_CONNECTION_TIMEOUT, TimeUnit.SECONDS)
}
val status = client.executeHttpMethod(propFind)
Timber.i("Read remote file $remotePath with status ${propFind.statusCode}")
return if (isSuccess(status)) {
val remoteFile = RemoteFile.getRemoteFileFromDav(
davResource = propFind.root!!,
userId = AccountUtils.getUserId(mAccount, mContext),
userName = mAccount.name,
spaceWebDavUrl = spaceWebDavUrl,
)
RemoteOperationResult<RemoteFile>(RemoteOperationResult.ResultCode.OK).apply {
data = remoteFile
}
} else {
RemoteOperationResult<RemoteFile>(propFind).also {
client.exhaustResponse(propFind.getResponseBodyAsStream())
}
}
} catch (exception: Exception) {
return RemoteOperationResult(exception)
}
}
private fun getFinalWebDavUrl(): URL {
val baseWebDavUrl = spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
return URL(baseWebDavUrl + WebdavUtils.encodePath(remotePath))
}
private fun isSuccess(status: Int) = status.isOneOf(HTTP_MULTI_STATUS, HTTP_OK)
companion object {
private const val SYNC_READ_TIMEOUT = 40_000L
private const val SYNC_CONNECTION_TIMEOUT = 5_000L
}
}

View File

@ -0,0 +1,118 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import at.bitfire.dav4jvm.PropertyRegistry
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.accounts.AccountUtils
import com.owncloud.android.lib.common.http.HttpConstants.HTTP_MULTI_STATUS
import com.owncloud.android.lib.common.http.HttpConstants.HTTP_OK
import com.owncloud.android.lib.common.http.methods.webdav.DavConstants
import com.owncloud.android.lib.common.http.methods.webdav.DavUtils
import com.owncloud.android.lib.common.http.methods.webdav.PropfindMethod
import com.owncloud.android.lib.common.http.methods.webdav.properties.OCShareTypes
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.owncloud.android.lib.common.utils.isOneOf
import timber.log.Timber
import java.net.URL
/**
* Remote operation performing the read of remote file or folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
* @author David González Verdugo
*/
class ReadRemoteFolderOperation(
val remotePath: String,
val spaceWebDavUrl: String? = null,
) : RemoteOperation<ArrayList<RemoteFile>>() {
/**
* Performs the read operation.
*
* @param client Client object to communicate with the remote ownCloud server.
*/
override fun run(client: OwnCloudClient): RemoteOperationResult<ArrayList<RemoteFile>> {
try {
PropertyRegistry.register(OCShareTypes.Factory())
val propfindMethod = PropfindMethod(
getFinalWebDavUrl(),
DavConstants.DEPTH_1,
DavUtils.allPropSet
)
val status = client.executeHttpMethod(propfindMethod)
if (isSuccess(status)) {
val mFolderAndFiles = ArrayList<RemoteFile>()
val remoteFolder = RemoteFile.getRemoteFileFromDav(
davResource = propfindMethod.root!!,
userId = AccountUtils.getUserId(mAccount, mContext),
userName = mAccount.name,
spaceWebDavUrl = spaceWebDavUrl,
)
mFolderAndFiles.add(remoteFolder)
// loop to update every child
propfindMethod.members.forEach { resource ->
val remoteFile = RemoteFile.getRemoteFileFromDav(
davResource = resource,
userId = AccountUtils.getUserId(mAccount, mContext),
userName = mAccount.name,
spaceWebDavUrl = spaceWebDavUrl,
)
mFolderAndFiles.add(remoteFile)
}
// Result of the operation
return RemoteOperationResult<ArrayList<RemoteFile>>(ResultCode.OK).apply {
data = mFolderAndFiles
Timber.i("Synchronized $remotePath with ${mFolderAndFiles.size} files. ${this.logMessage}")
}
} else { // synchronization failed
return RemoteOperationResult<ArrayList<RemoteFile>>(propfindMethod).also {
Timber.w("Synchronized $remotePath ${it.logMessage}")
}
}
} catch (e: Exception) {
return RemoteOperationResult<ArrayList<RemoteFile>>(e).also {
Timber.e(it.exception, "Synchronized $remotePath")
}
}
}
private fun getFinalWebDavUrl(): URL {
val baseWebDavUrl = spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
return URL(baseWebDavUrl + WebdavUtils.encodePath(remotePath))
}
private fun isSuccess(status: Int): Boolean = status.isOneOf(HTTP_OK, HTTP_MULTI_STATUS)
}

View File

@ -0,0 +1,194 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import android.net.Uri
import android.os.Parcelable
import androidx.annotation.VisibleForTesting
import at.bitfire.dav4jvm.PropStat
import at.bitfire.dav4jvm.Property
import at.bitfire.dav4jvm.Response
import at.bitfire.dav4jvm.property.CreationDate
import at.bitfire.dav4jvm.property.GetContentLength
import at.bitfire.dav4jvm.property.GetContentType
import at.bitfire.dav4jvm.property.GetETag
import at.bitfire.dav4jvm.property.GetLastModified
import at.bitfire.dav4jvm.property.OCId
import at.bitfire.dav4jvm.property.OCPermissions
import at.bitfire.dav4jvm.property.OCPrivatelink
import at.bitfire.dav4jvm.property.OCSize
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.webdav.properties.OCShareTypes
import com.owncloud.android.lib.common.utils.isOneOf
import com.owncloud.android.lib.resources.shares.ShareType
import com.owncloud.android.lib.resources.shares.ShareType.Companion.fromValue
import kotlinx.parcelize.Parcelize
import okhttp3.HttpUrl
import timber.log.Timber
import java.io.File
/**
* Contains the data of a Remote File from a WebDavEntry
*
* The path received must be URL-decoded. Path separator must be File.separator, and it must be the first character in 'path'.
*
* @author masensio
* @author Christian Schabesberger
* @author Abel García de Prada
*/
@Parcelize
data class RemoteFile(
var remotePath: String,
var mimeType: String = "DIR",
var length: Long = 0,
var creationTimestamp: Long = 0,
var modifiedTimestamp: Long = 0,
var etag: String? = null,
var permissions: String? = null,
var remoteId: String? = null,
var size: Long = 0,
var privateLink: String? = null,
var owner: String,
var sharedByLink: Boolean = false,
var sharedWithSharee: Boolean = false,
) : Parcelable {
// TODO: Quotas not used. Use or remove them.
init {
require(
!(remotePath.isEmpty() || !remotePath.startsWith(File.separator))
) { "Trying to create a OCFile with a non valid remote path: $remotePath" }
}
/**
* Use this to find out if this file is a folder.
*
* @return true if it is a folder
*/
val isFolder
get() = mimeType.isOneOf(MIME_DIR, MIME_DIR_UNIX)
companion object {
const val MIME_DIR = "DIR"
const val MIME_DIR_UNIX = "httpd/unix-directory"
fun getRemoteFileFromDav(
davResource: Response,
userId: String,
userName: String,
spaceWebDavUrl: String? = null
): RemoteFile {
val remotePath = getRemotePathFromUrl(davResource.href, userId, spaceWebDavUrl)
val remoteFile = RemoteFile(remotePath = remotePath, owner = userName)
val properties = getPropertiesEvenIfPostProcessing(davResource)
for (property in properties) {
when (property) {
is CreationDate -> {
remoteFile.creationTimestamp = property.creationDate.toLong()
}
is GetContentLength -> {
remoteFile.length = property.contentLength
}
is GetContentType -> {
property.type?.let { remoteFile.mimeType = it }
}
is GetLastModified -> {
remoteFile.modifiedTimestamp = property.lastModified
}
is GetETag -> {
remoteFile.etag = property.eTag
}
is OCPermissions -> {
remoteFile.permissions = property.permission
}
is OCId -> {
remoteFile.remoteId = property.id
}
is OCSize -> {
remoteFile.size = property.size
}
is OCPrivatelink -> {
remoteFile.privateLink = property.link
}
is OCShareTypes -> {
val list = property.shareTypes
for (i in list.indices) {
val shareType = fromValue(list[i].toInt())
if (shareType == null) {
Timber.d("Illegal share type value: " + list[i])
continue
}
if (shareType == ShareType.PUBLIC_LINK) {
remoteFile.sharedByLink = true
} else if (shareType == ShareType.USER || shareType == ShareType.FEDERATED || shareType == ShareType.GROUP) {
remoteFile.sharedWithSharee = true
}
}
}
}
}
return remoteFile
}
/**
* Retrieves a relative path from a remote file url
*
*
* Example legacy:
* /remote.php/dav/files/username/Documents/text.txt => /Documents/text.txt
*
* Example spaces:
* /dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$05bca744-d89f-4e9c-a990-25a0d7f03fe9/Documents/text.txt => /Documents/text.txt
*
* @param url remote file url
* @param userId file owner
* @param spaceWebDavUrl custom web dav url for space
* @return remote relative path of the file
*/
@VisibleForTesting
fun getRemotePathFromUrl(
url: HttpUrl,
userId: String,
spaceWebDavUrl: String? = null,
): String {
val davFilesPath = spaceWebDavUrl ?: (OwnCloudClient.WEBDAV_FILES_PATH_4_0 + userId)
val absoluteDavPath = if (spaceWebDavUrl != null) Uri.decode(url.toString()) else Uri.decode(url.encodedPath)
val pathToOc = absoluteDavPath.split(davFilesPath).first()
return absoluteDavPath.replace(pathToOc + davFilesPath, "")
}
private fun getPropertiesEvenIfPostProcessing(response: Response): List<Property> {
return if (response.isSuccess())
response.propstat.filter { propStat -> propStat.isSuccessOrPostProcessing() }.map { it.properties }.flatten()
else
emptyList()
}
private fun PropStat.isSuccessOrPostProcessing() = (status.code / 100 == 2 || status.code == HttpConstants.HTTP_TOO_EARLY)
}
}

View File

@ -0,0 +1,81 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2020 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants.HTTP_NO_CONTENT
import com.owncloud.android.lib.common.http.HttpConstants.HTTP_OK
import com.owncloud.android.lib.common.http.methods.nonwebdav.DeleteMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.owncloud.android.lib.common.utils.isOneOf
import timber.log.Timber
import java.net.URL
/**
* Remote operation performing the removal of a remote file or folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
* @author David González Verdugo
* @author Abel García de Prada
*/
open class RemoveRemoteFileOperation(
private val remotePath: String,
val spaceWebDavUrl: String? = null,
) : RemoteOperation<Unit>() {
override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
var result: RemoteOperationResult<Unit>
try {
val srcWebDavUri = getSrcWebDavUriForClient(client)
val deleteMethod = DeleteMethod(
URL(srcWebDavUri + WebdavUtils.encodePath(remotePath))
)
val status = client.executeHttpMethod(deleteMethod)
result = if (isSuccess(status)) {
RemoteOperationResult<Unit>(ResultCode.OK)
} else {
RemoteOperationResult<Unit>(deleteMethod)
}
Timber.i("Remove $remotePath: ${result.logMessage}")
} catch (e: Exception) {
result = RemoteOperationResult<Unit>(e)
Timber.e(e, "Remove $remotePath: ${result.logMessage}")
}
return result
}
/**
* For standard removals, we will use [OwnCloudClient.getUserFilesWebDavUri].
* In case we need a different source Uri, override this method.
*/
open fun getSrcWebDavUriForClient(client: OwnCloudClient): String = spaceWebDavUrl ?: client.userFilesWebDavUri.toString()
private fun isSuccess(status: Int) = status.isOneOf(HTTP_OK, HTTP_NO_CONTENT)
}

View File

@ -0,0 +1,120 @@
/* ownCloud Android Library is available under MIT license
* Copyright (C) 2021 ownCloud GmbH.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
package com.owncloud.android.lib.resources.files
import com.owncloud.android.lib.common.OwnCloudClient
import com.owncloud.android.lib.common.http.HttpConstants
import com.owncloud.android.lib.common.http.methods.webdav.MoveMethod
import com.owncloud.android.lib.common.network.WebdavUtils
import com.owncloud.android.lib.common.operations.RemoteOperation
import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode
import com.owncloud.android.lib.common.utils.isOneOf
import timber.log.Timber
import java.io.File
import java.net.URL
import java.util.concurrent.TimeUnit
/**
* Remote operation performing the rename of a remote file or folder in the ownCloud server.
*
* @author David A. Velasco
* @author masensio
*/
class RenameRemoteFileOperation(
private val oldName: String,
private val oldRemotePath: String,
private val newName: String,
isFolder: Boolean,
val spaceWebDavUrl: String? = null,
) : RemoteOperation<Unit>() {
private var newRemotePath: String
init {
var parent = (File(oldRemotePath)).parent ?: throw IllegalArgumentException()
if (!parent.endsWith(File.separator)) {
parent = parent.plus(File.separator)
}
newRemotePath = parent.plus(newName)
if (isFolder) {
newRemotePath.plus(File.separator)
}
}
override fun run(client: OwnCloudClient): RemoteOperationResult<Unit> {
var result: RemoteOperationResult<Unit>
try {
if (newName == oldName) {
return RemoteOperationResult<Unit>(ResultCode.OK)
}
if (targetPathIsUsed(client)) {
return RemoteOperationResult<Unit>(ResultCode.INVALID_OVERWRITE)
}
val moveMethod: MoveMethod = MoveMethod(
url = URL((spaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(oldRemotePath)),
destinationUrl = (spaceWebDavUrl ?: client.userFilesWebDavUri.toString()) + WebdavUtils.encodePath(newRemotePath),
).apply {
setReadTimeout(RENAME_READ_TIMEOUT, TimeUnit.MILLISECONDS)
setConnectionTimeout(RENAME_CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS)
}
val status = client.executeHttpMethod(moveMethod)
result = if (isSuccess(status)) {
RemoteOperationResult<Unit>(ResultCode.OK)
} else {
RemoteOperationResult<Unit>(moveMethod)
}
Timber.i("Rename $oldRemotePath to $newRemotePath: ${result.logMessage}")
client.exhaustResponse(moveMethod.getResponseBodyAsStream())
return result
} catch (exception: Exception) {
result = RemoteOperationResult<Unit>(exception)
Timber.e(exception, "Rename $oldRemotePath to $newName: ${result.logMessage}")
return result
}
}
/**
* Checks if a file with the new name already exists.
*
* @return 'True' if the target path is already used by an existing file.
*/
private fun targetPathIsUsed(client: OwnCloudClient): Boolean {
val checkPathExistenceRemoteOperation = CheckPathExistenceRemoteOperation(newRemotePath, true)
val exists = checkPathExistenceRemoteOperation.execute(client)
return exists.isSuccess
}
private fun isSuccess(status: Int) = status.isOneOf(HttpConstants.HTTP_CREATED, HttpConstants.HTTP_NO_CONTENT)
companion object {
private const val RENAME_READ_TIMEOUT = 10_000L
private const val RENAME_CONNECTION_TIMEOUT = 5_000L
}
}

Some files were not shown because too many files have changed in this diff Show More