mirror of
				https://github.com/owncloud/android-library.git
				synced 2025-11-03 20:08:00 +00:00 
			
		
		
		
	
						commit
						07318a2aa2
					
				@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
ownCloud Android Library is available under MIT license
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
Copyright (C) 2018 ownCloud GmbH.
 | 
			
		||||
Copyright (C) 2012 Bartek Przybylski
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 | 
			
		||||
@ -44,9 +44,7 @@ ownCloud Android Library is available under MIT license. See the file LICENSE.md
 | 
			
		||||
 | 
			
		||||
#### 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.
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
ownCloud Android Library uses OkHttp version 3.10, licensed under Apache License and version 2.0. Besides, it uses Dav4Android, licensed under Mozilla Public License, v. 2.0
 | 
			
		||||
   
 | 
			
		||||
 | 
			
		||||
### Compatibility
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								build.gradle
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								build.gradle
									
									
									
									
									
								
							@ -1,7 +1,7 @@
 | 
			
		||||
buildscript {
 | 
			
		||||
    repositories {
 | 
			
		||||
        jcenter()
 | 
			
		||||
        google()
 | 
			
		||||
        jcenter()
 | 
			
		||||
    }
 | 
			
		||||
    dependencies {
 | 
			
		||||
        classpath 'com.android.tools.build:gradle:3.1.2'
 | 
			
		||||
@ -14,12 +14,14 @@ allprojects {
 | 
			
		||||
    repositories {
 | 
			
		||||
        google()
 | 
			
		||||
        jcenter()
 | 
			
		||||
        maven { url 'https://jitpack.io' }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    api 'org.apache.jackrabbit:jackrabbit-webdav:2.12.4'
 | 
			
		||||
    api 'com.squareup.okhttp3:okhttp:3.10.0'
 | 
			
		||||
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.51"
 | 
			
		||||
    implementation 'com.gitlab.ownclouders:dav4android:oc_support'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
@ -52,4 +54,8 @@ android {
 | 
			
		||||
    lintOptions {
 | 
			
		||||
        abortOnError false
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
        sourceCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
        targetCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								pom.xml
									
									
									
									
									
								
							@ -29,12 +29,6 @@
 | 
			
		||||
            <scope>provided</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.apache.jackrabbit</groupId>
 | 
			
		||||
            <artifactId>jackrabbit-webdav</artifactId>
 | 
			
		||||
            <version>2.7.2</version>
 | 
			
		||||
        </dependency>
 | 
			
		||||
 | 
			
		||||
    </dependencies>
 | 
			
		||||
 | 
			
		||||
    <build>
 | 
			
		||||
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!--  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.
 | 
			
		||||
 | 
			
		||||
 -->
 | 
			
		||||
 
 | 
			
		||||
<resources/>
 | 
			
		||||
@ -34,8 +34,7 @@
 | 
			
		||||
        android:targetSdkVersion="26"/>
 | 
			
		||||
    <application
 | 
			
		||||
        android:icon="@drawable/ic_launcher"
 | 
			
		||||
        android:label="@string/app_name"
 | 
			
		||||
        android:theme="@android:style/Theme.Light.NoTitleBar">
 | 
			
		||||
        android:label="@string/app_name">
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name="MainActivity"
 | 
			
		||||
            android:configChanges="orientation|keyboardHidden"
 | 
			
		||||
@ -48,4 +47,4 @@
 | 
			
		||||
            </intent-filter>
 | 
			
		||||
        </activity>
 | 
			
		||||
    </application>
 | 
			
		||||
</manifest>
 | 
			
		||||
</manifest>
 | 
			
		||||
@ -42,4 +42,8 @@ android {
 | 
			
		||||
    packagingOptions {
 | 
			
		||||
        exclude 'META-INF/LICENSE.txt'
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
        sourceCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
        targetCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,150 +24,99 @@
 | 
			
		||||
 -->
 | 
			
		||||
 | 
			
		||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="match_parent"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    >
 | 
			
		||||
 | 
			
		||||
    <EditText
 | 
			
		||||
        android:id="@+id/server_address"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_alignParentLeft="true"
 | 
			
		||||
        android:layout_alignParentStart="true"
 | 
			
		||||
        android:layout_alignParentTop="true"
 | 
			
		||||
        android:layout_toLeftOf="@+id/button_check_server"
 | 
			
		||||
        android:layout_toStartOf="@+id/button_check_server"
 | 
			
		||||
        android:ems="10"
 | 
			
		||||
        android:hint="Server address (with http or https)"
 | 
			
		||||
        android:inputType="textPersonName"/>
 | 
			
		||||
 | 
			
		||||
    <Button
 | 
			
		||||
        android:id="@+id/button_check_server"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_alignBaseline="@+id/server_address"
 | 
			
		||||
        android:layout_alignBottom="@+id/server_address"
 | 
			
		||||
        android:layout_alignParentEnd="true"
 | 
			
		||||
        android:layout_alignParentRight="true"
 | 
			
		||||
        android:onClick="onClickHandler"
 | 
			
		||||
        android:text="@string/check_server"/>
 | 
			
		||||
 | 
			
		||||
    <Button
 | 
			
		||||
        android:id="@+id/button_refresh"
 | 
			
		||||
        style="@style/ButtonStyle"
 | 
			
		||||
        android:layout_alignParentLeft="true"
 | 
			
		||||
        android:layout_alignParentTop="true"
 | 
			
		||||
        android:text="@string/refresh"
 | 
			
		||||
        android:onClick="onClickHandler"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <ListView
 | 
			
		||||
        android:id="@+id/list_view"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_alignParentEnd="true"
 | 
			
		||||
		android:layout_below="@+id/button_refresh"
 | 
			
		||||
        android:layout_above="@+id/button_upload"
 | 
			
		||||
        android:layout_alignParentLeft="true"
 | 
			
		||||
        android:layout_alignParentRight="true"
 | 
			
		||||
        android:layout_below="@id/server_address"
 | 
			
		||||
        android:layout_marginTop="10dp"
 | 
			
		||||
        android:onClick="onClickHandler"
 | 
			
		||||
        android:text="@string/refresh"/>
 | 
			
		||||
        >
 | 
			
		||||
    </ListView>
 | 
			
		||||
 | 
			
		||||
    <Button
 | 
			
		||||
        android:id="@+id/button_upload"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        style="@style/ButtonStyle"
 | 
			
		||||
        android:layout_alignParentLeft="true"
 | 
			
		||||
        android:layout_below="@id/button_refresh"
 | 
			
		||||
        android:layout_marginTop="10dp"
 | 
			
		||||
        android:layout_above="@+id/frame"
 | 
			
		||||
        android:text="@string/upload"
 | 
			
		||||
        android:onClick="onClickHandler"
 | 
			
		||||
        android:text="@string/upload"/>
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/upload_progress"
 | 
			
		||||
        style="@style/ProgressStyle"
 | 
			
		||||
        android:layout_below="@id/list_view"
 | 
			
		||||
        android:layout_above="@id/frame"
 | 
			
		||||
        android:layout_toRightOf="@id/button_upload"
 | 
			
		||||
        android:layout_toLeftOf="@+id/button_delete_remote"
 | 
			
		||||
        android:gravity="center"
 | 
			
		||||
        android:textSize="14sp"
 | 
			
		||||
        android:text="0%"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <Button
 | 
			
		||||
        android:id="@+id/button_download"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_alignParentLeft="true"
 | 
			
		||||
        android:layout_below="@id/button_upload"
 | 
			
		||||
        android:layout_marginTop="10dp"
 | 
			
		||||
        android:id="@id/button_delete_remote"
 | 
			
		||||
        style="@style/ButtonStyle"
 | 
			
		||||
        android:layout_alignParentRight="true"
 | 
			
		||||
        android:layout_above="@id/frame"
 | 
			
		||||
        android:text="@string/delete_remote_file"
 | 
			
		||||
        android:onClick="onClickHandler"
 | 
			
		||||
        android:text="@string/download"/>
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <FrameLayout
 | 
			
		||||
        android:id="@id/frame"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="@dimen/frame_height"
 | 
			
		||||
        android:layout_alignParentLeft="true"
 | 
			
		||||
        android:layout_alignParentRight="true"
 | 
			
		||||
        android:layout_above="@+id/button_download"
 | 
			
		||||
        >
 | 
			
		||||
    </FrameLayout>
 | 
			
		||||
 | 
			
		||||
    <Button
 | 
			
		||||
        android:id="@+id/button_delete_remote"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:id="@id/button_download"
 | 
			
		||||
        style="@style/ButtonStyle"
 | 
			
		||||
        android:layout_alignParentBottom="true"
 | 
			
		||||
        android:layout_alignParentLeft="true"
 | 
			
		||||
        android:layout_below="@id/button_download"
 | 
			
		||||
        android:layout_marginTop="10dp"
 | 
			
		||||
        android:text="@string/download"
 | 
			
		||||
        android:onClick="onClickHandler"
 | 
			
		||||
        android:text="@string/delete_remote_file"/>
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <!--<ListView-->
 | 
			
		||||
    <!--android:id="@+id/list_view"-->
 | 
			
		||||
    <!--android:layout_width="match_parent"-->
 | 
			
		||||
    <!--android:layout_height="wrap_content"-->
 | 
			
		||||
    <!--android:layout_alignParentLeft="true"-->
 | 
			
		||||
    <!--android:layout_alignParentRight="true"-->
 | 
			
		||||
    <!--android:layout_below="@+id/button_refresh"-->
 | 
			
		||||
    <!--android:visibility="invisible">-->
 | 
			
		||||
    <!--</ListView>-->
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/download_progress"
 | 
			
		||||
        style="@style/ProgressStyle"
 | 
			
		||||
        android:layout_below="@id/frame"
 | 
			
		||||
        android:layout_alignParentBottom="true"
 | 
			
		||||
        android:layout_toRightOf="@id/button_download"
 | 
			
		||||
        android:layout_toLeftOf="@+id/button_delete_local"
 | 
			
		||||
        android:gravity="center"
 | 
			
		||||
        android:textSize="14sp"
 | 
			
		||||
        android:text="0%"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <!--<TextView-->
 | 
			
		||||
    <!--android:id="@+id/upload_progress"-->
 | 
			
		||||
    <!--style="@style/ProgressStyle"-->
 | 
			
		||||
    <!--android:layout_above="@id/frame"-->
 | 
			
		||||
    <!--android:layout_below="@id/list_view"-->
 | 
			
		||||
    <!--android:layout_toLeftOf="@+id/button_delete_remote"-->
 | 
			
		||||
    <!--android:layout_toRightOf="@id/button_upload"-->
 | 
			
		||||
    <!--android:enabled="false"-->
 | 
			
		||||
    <!--android:gravity="center"-->
 | 
			
		||||
    <!--android:text="0%"-->
 | 
			
		||||
    <!--android:textSize="14sp"-->
 | 
			
		||||
    <!--android:visibility="invisible"/>-->
 | 
			
		||||
 | 
			
		||||
    <!--<Button-->
 | 
			
		||||
    <!--android:id="@id/button_delete_remote"-->
 | 
			
		||||
    <!--style="@style/ButtonStyle"-->
 | 
			
		||||
    <!--android:layout_above="@id/frame"-->
 | 
			
		||||
    <!--android:layout_alignParentRight="true"-->
 | 
			
		||||
    <!--android:enabled="false"-->
 | 
			
		||||
    <!--android:onClick="onClickHandler"-->
 | 
			
		||||
    <!--android:text="@string/delete_remote_file"-->
 | 
			
		||||
    <!--android:visibility="invisible"/>-->
 | 
			
		||||
 | 
			
		||||
    <!--<FrameLayout-->
 | 
			
		||||
    <!--android:id="@id/frame"-->
 | 
			
		||||
    <!--android:layout_width="match_parent"-->
 | 
			
		||||
    <!--android:layout_height="@dimen/frame_height"-->
 | 
			
		||||
    <!--android:layout_alignParentLeft="true"-->
 | 
			
		||||
    <!--android:layout_alignParentRight="true"-->
 | 
			
		||||
    <!--android:layout_above="@+id/button_download"-->
 | 
			
		||||
    <!-->-->
 | 
			
		||||
    <!--</FrameLayout>-->
 | 
			
		||||
 | 
			
		||||
    <!--<Button-->
 | 
			
		||||
    <!--android:id="@id/button_download"-->
 | 
			
		||||
    <!--style="@style/ButtonStyle"-->
 | 
			
		||||
    <!--android:layout_alignParentBottom="true"-->
 | 
			
		||||
    <!--android:layout_alignParentLeft="true"-->
 | 
			
		||||
    <!--android:enabled="false"-->
 | 
			
		||||
    <!--android:onClick="onClickHandler"-->
 | 
			
		||||
    <!--android:text="@string/download"-->
 | 
			
		||||
    <!--android:visibility="invisible"/>-->
 | 
			
		||||
 | 
			
		||||
    <!--<TextView-->
 | 
			
		||||
    <!--android:id="@+id/download_progress"-->
 | 
			
		||||
    <!--style="@style/ProgressStyle"-->
 | 
			
		||||
    <!--android:layout_alignParentBottom="true"-->
 | 
			
		||||
    <!--android:layout_below="@id/frame"-->
 | 
			
		||||
    <!--android:layout_toLeftOf="@+id/button_delete_local"-->
 | 
			
		||||
    <!--android:layout_toRightOf="@id/button_download"-->
 | 
			
		||||
    <!--android:enabled="false"-->
 | 
			
		||||
    <!--android:gravity="center"-->
 | 
			
		||||
    <!--android:text="0%"-->
 | 
			
		||||
    <!--android:textSize="14sp"-->
 | 
			
		||||
    <!--android:visibility="invisible"/>-->
 | 
			
		||||
 | 
			
		||||
    <!--<Button-->
 | 
			
		||||
    <!--android:id="@id/button_delete_local"-->
 | 
			
		||||
    <!--style="@style/ButtonStyle"-->
 | 
			
		||||
    <!--android:layout_alignParentBottom="true"-->
 | 
			
		||||
    <!--android:layout_alignParentRight="true"-->
 | 
			
		||||
    <!--android:enabled="false"-->
 | 
			
		||||
    <!--android:onClick="onClickHandler"-->
 | 
			
		||||
    <!--android:text="@string/delete_local_file"-->
 | 
			
		||||
    <!--android:visibility="invisible"/>-->
 | 
			
		||||
    <Button
 | 
			
		||||
        android:id="@id/button_delete_local"
 | 
			
		||||
        style="@style/ButtonStyle"
 | 
			
		||||
        android:layout_alignParentBottom="true"
 | 
			
		||||
        android:layout_alignParentRight="true"
 | 
			
		||||
        android:text="@string/delete_local_file"
 | 
			
		||||
        android:onClick="onClickHandler"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
</RelativeLayout>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,31 +1,30 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!--  ownCloud Android Library is available under MIT license
 | 
			
		||||
   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
    
 | 
			
		||||
   Copyright (C) 2018 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, 
 | 
			
		||||
 | 
			
		||||
   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 
 | 
			
		||||
   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.
 | 
			
		||||
 | 
			
		||||
 -->
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="server_base_url"></string>
 | 
			
		||||
    <string name="username"></string>
 | 
			
		||||
    <string name="password"></string>
 | 
			
		||||
    <string name ="user_agent">Mozilla/5.0 (Android) ownCloud sample </string>
 | 
			
		||||
</resources>
 | 
			
		||||
</resources>
 | 
			
		||||
@ -26,7 +26,6 @@
 | 
			
		||||
<resources>
 | 
			
		||||
    <string name="app_name">ownCloud Sample Client</string>
 | 
			
		||||
    <string name="refresh">Refresh</string>
 | 
			
		||||
    <string name="check_server">Check server</string>
 | 
			
		||||
    <string name="upload">Upload</string>
 | 
			
		||||
    <string name="delete_remote_file">Delete remote file</string>
 | 
			
		||||
    <string name="download">Download</string>
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 ownCloud GmbH.
 | 
			
		||||
 *
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   
 | 
			
		||||
 *   Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
 *   of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
@ -26,25 +24,30 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.sampleclient;
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint;
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.pm.PackageInfo;
 | 
			
		||||
import android.content.pm.PackageManager;
 | 
			
		||||
import android.content.res.AssetManager;
 | 
			
		||||
import android.graphics.drawable.BitmapDrawable;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Bundle;
 | 
			
		||||
import android.os.Handler;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
import android.view.Gravity;
 | 
			
		||||
import android.view.View;
 | 
			
		||||
import android.widget.ListView;
 | 
			
		||||
import android.widget.TextView;
 | 
			
		||||
import android.widget.Toast;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.OnRemoteOperationListener;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.FileUtils;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation;
 | 
			
		||||
@ -52,9 +55,6 @@ import com.owncloud.android.lib.resources.files.RemoteFile;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.RemoveRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
 | 
			
		||||
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
@ -63,42 +63,16 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import okhttp3.Call;
 | 
			
		||||
import okhttp3.Callback;
 | 
			
		||||
import okhttp3.Credentials;
 | 
			
		||||
import okhttp3.Headers;
 | 
			
		||||
import okhttp3.MediaType;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import okhttp3.Request;
 | 
			
		||||
import okhttp3.RequestBody;
 | 
			
		||||
import okhttp3.Response;
 | 
			
		||||
import static android.content.ContentValues.TAG;
 | 
			
		||||
 | 
			
		||||
public class MainActivity extends Activity implements OnRemoteOperationListener, OnDatatransferProgressListener {
 | 
			
		||||
	
 | 
			
		||||
	private static String LOG_TAG = MainActivity.class.getCanonicalName();
 | 
			
		||||
 | 
			
		||||
	private static final String NODE_VERSION = "version";
 | 
			
		||||
	private static final String WEBDAV_PATH_4_0 = "/remote.php/webdav/";
 | 
			
		||||
	private static final String NEW_WEBDAV_PATH = "/remote.php/dav/files/";
 | 
			
		||||
	private static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length";
 | 
			
		||||
	private static final String OC_X_OC_MTIME_HEADER = "X-OC-Mtime";
 | 
			
		||||
	private static final String AUTHORIZATION_HEADER = "Authorization";
 | 
			
		||||
	private static final String USER_AGENT_HEADER = "User-Agent";
 | 
			
		||||
	private static final String CONTENT_TYPE_HEADER = "Content-Type";
 | 
			
		||||
	private static final String USER_AGENT_VALUE = "Mozilla/5.0 (Android) ownCloud-android/2.7.0";
 | 
			
		||||
	private static final String CONTENT_TYPE_VALUE = "multipart/form-data";
 | 
			
		||||
	
 | 
			
		||||
	private Handler mHandler;
 | 
			
		||||
	
 | 
			
		||||
	private OwnCloudClient mClient; 
 | 
			
		||||
	
 | 
			
		||||
	private OwnCloudClient mClient;
 | 
			
		||||
	private FilesArrayAdapter mFilesAdapter;
 | 
			
		||||
	
 | 
			
		||||
	private View mFrame;
 | 
			
		||||
 | 
			
		||||
	private OkHttpClient mOkHttpClient;
 | 
			
		||||
 | 
			
		||||
	private String mCredentials;
 | 
			
		||||
	
 | 
			
		||||
    /** Called when the activity is first created. */
 | 
			
		||||
    @Override
 | 
			
		||||
@ -108,17 +82,20 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
        
 | 
			
		||||
        mHandler = new Handler();
 | 
			
		||||
        
 | 
			
		||||
    	Uri serverUri = Uri.parse(getString(R.string.server_base_url));
 | 
			
		||||
    	final Uri serverUri = Uri.parse(getString(R.string.server_base_url));
 | 
			
		||||
 | 
			
		||||
		OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
 | 
			
		||||
    	mClient = OwnCloudClientFactory.createOwnCloudClient(serverUri, this, true);
 | 
			
		||||
    	mClient.setCredentials(
 | 
			
		||||
    			OwnCloudCredentialsFactory.newBasicCredentials(
 | 
			
		||||
    					getString(R.string.username), 
 | 
			
		||||
    					getString(R.string.password)
 | 
			
		||||
 | 
			
		||||
		mClient.setCredentials(
 | 
			
		||||
				OwnCloudCredentialsFactory.newBasicCredentials(
 | 
			
		||||
						getString(R.string.username),
 | 
			
		||||
						getString(R.string.password)
 | 
			
		||||
				)
 | 
			
		||||
		);
 | 
			
		||||
    	
 | 
			
		||||
    	mFilesAdapter = new FilesArrayAdapter(this, R.layout.file_in_list);
 | 
			
		||||
//    	((ListView)findViewById(R.id.list_view)).setAdapter(mFilesAdapter);
 | 
			
		||||
    	((ListView)findViewById(R.id.list_view)).setAdapter(mFilesAdapter);
 | 
			
		||||
    	
 | 
			
		||||
    	// TODO move to background thread or task
 | 
			
		||||
    	AssetManager assets = getAssets();
 | 
			
		||||
@ -140,14 +117,8 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
			Toast.makeText(this, R.string.error_copying_sample_file, Toast.LENGTH_SHORT).show();
 | 
			
		||||
			Log.e(LOG_TAG, getString(R.string.error_copying_sample_file), e);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		((TextView) findViewById(R.id.server_address)).setText(getString(R.string.server_base_url));
 | 
			
		||||
 | 
			
		||||
		mOkHttpClient = new OkHttpClient();
 | 
			
		||||
 | 
			
		||||
		mCredentials = Credentials.basic(getString(R.string.username), getString(R.string.password));
 | 
			
		||||
		
 | 
			
		||||
//		mFrame = findViewById(R.id.frame);
 | 
			
		||||
		mFrame = findViewById(R.id.frame);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
@ -163,275 +134,77 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
    
 | 
			
		||||
    public void onClickHandler(View button) {
 | 
			
		||||
    	switch (button.getId())	{
 | 
			
		||||
			case R.id.button_check_server:
 | 
			
		||||
				startCheck();
 | 
			
		||||
				break;
 | 
			
		||||
	    	case R.id.button_refresh:
 | 
			
		||||
	    		startRefresh();
 | 
			
		||||
	    		break;
 | 
			
		||||
	    	case R.id.button_upload:
 | 
			
		||||
	    		startUpload();
 | 
			
		||||
	    		break;
 | 
			
		||||
			case R.id.button_download:
 | 
			
		||||
	    		startDownload();
 | 
			
		||||
	    		break;
 | 
			
		||||
	    	case R.id.button_delete_remote:
 | 
			
		||||
	    		startRemoteDeletion();
 | 
			
		||||
	    		break;
 | 
			
		||||
//	    	case R.id.button_delete_local:
 | 
			
		||||
//	    		startLocalDeletion();
 | 
			
		||||
//	    		break;
 | 
			
		||||
	    	case R.id.button_download:
 | 
			
		||||
	    		startDownload();
 | 
			
		||||
	    		break;
 | 
			
		||||
	    	case R.id.button_delete_local:
 | 
			
		||||
	    		startLocalDeletion();
 | 
			
		||||
	    		break;
 | 
			
		||||
			default:
 | 
			
		||||
	    		Toast.makeText(this, R.string.youre_doing_it_wrong, Toast.LENGTH_SHORT).show();
 | 
			
		||||
    	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void startCheck() {
 | 
			
		||||
 | 
			
		||||
		if (!validServerAddress()) return;
 | 
			
		||||
 | 
			
		||||
		Request request = new Request.Builder()
 | 
			
		||||
				.url(getString(R.string.server_base_url) + "/status.php")
 | 
			
		||||
				.get()
 | 
			
		||||
				.build();
 | 
			
		||||
 | 
			
		||||
		mOkHttpClient.newCall(request).enqueue(new Callback() {
 | 
			
		||||
 | 
			
		||||
			@Override public void onResponse(Call call, final Response response) throws IOException {
 | 
			
		||||
 | 
			
		||||
				if (!response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
					showMessage("Response not successful with code: " + response.code());
 | 
			
		||||
 | 
			
		||||
					throw new IOException("Unexpected code " + response);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				try { // Successful response
 | 
			
		||||
 | 
			
		||||
					String jsonData = response.body().string();
 | 
			
		||||
 | 
			
		||||
					JSONObject Jobject = new JSONObject(jsonData);
 | 
			
		||||
 | 
			
		||||
					final String serverVersion = Jobject.get("version").toString();
 | 
			
		||||
 | 
			
		||||
					showMessage("Server with version " + serverVersion + " detected");
 | 
			
		||||
 | 
			
		||||
				} catch (JSONException e) {
 | 
			
		||||
					e.printStackTrace();
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Headers responseHeaders = response.headers();
 | 
			
		||||
				for (int i = 0, size = responseHeaders.size(); i < size; i++) {
 | 
			
		||||
					System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override public void onFailure(Call call, final IOException e) {
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
				showMessage("Something was wrong: " + e.toString());
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void startRefresh() {
 | 
			
		||||
 | 
			
		||||
//		Let's first use OKHttp with the new endpoint without depending on our library operations
 | 
			
		||||
 | 
			
		||||
//    	ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(FileUtils.PATH_SEPARATOR);
 | 
			
		||||
//    	refreshOperation.execute(mClient, this, mHandler);
 | 
			
		||||
 | 
			
		||||
		if (!validServerAddress()) return;
 | 
			
		||||
 | 
			
		||||
		final Request request = new Request.Builder()
 | 
			
		||||
				.url(getString(R.string.server_base_url) + NEW_WEBDAV_PATH + getString(R.string.username))
 | 
			
		||||
				.addHeader(AUTHORIZATION_HEADER, mCredentials)
 | 
			
		||||
				.addHeader(USER_AGENT_HEADER, USER_AGENT_VALUE)
 | 
			
		||||
				.method("PROPFIND", null)
 | 
			
		||||
				.build();
 | 
			
		||||
 | 
			
		||||
		mOkHttpClient.newCall(request).enqueue(new Callback() {
 | 
			
		||||
 | 
			
		||||
			@Override public void onResponse(Call call, final Response response) throws IOException {
 | 
			
		||||
 | 
			
		||||
				if (!response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
					showMessage("Response not successful with code: " + response.code());
 | 
			
		||||
 | 
			
		||||
					throw new IOException("Unexpected code " + response);
 | 
			
		||||
 | 
			
		||||
				} else { // Successful response
 | 
			
		||||
 | 
			
		||||
					final String propFindResult = response.body().string();
 | 
			
		||||
 | 
			
		||||
					showMessage(propFindResult);
 | 
			
		||||
 | 
			
		||||
					Headers responseHeaders = response.headers();
 | 
			
		||||
					for (int i = 0, size = responseHeaders.size(); i < size; i++) {
 | 
			
		||||
						System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override public void onFailure(Call call, IOException e) {
 | 
			
		||||
				showMessage("Something was wrong: " + e.toString());
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
    private void startRefresh() {
 | 
			
		||||
		ReadRemoteFolderOperation refreshOperation = new ReadRemoteFolderOperation(FileUtils.PATH_SEPARATOR);
 | 
			
		||||
		refreshOperation.execute(mClient, this, mHandler);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private void startUpload() {
 | 
			
		||||
 | 
			
		||||
    	File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path));
 | 
			
		||||
    	final File fileToUpload = upFolder.listFiles()[0];
 | 
			
		||||
    	File fileToUpload = upFolder.listFiles()[0];
 | 
			
		||||
    	String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName(); 
 | 
			
		||||
    	String mimeType = getString(R.string.sample_file_mimetype);
 | 
			
		||||
 | 
			
		||||
		MediaType mediaType = MediaType.parse(mimeType);
 | 
			
		||||
 | 
			
		||||
		// Get the last modification date of the file from the file system
 | 
			
		||||
		Long timeStampLong = fileToUpload.lastModified()/1000;
 | 
			
		||||
		String timeStamp = timeStampLong.toString();
 | 
			
		||||
 | 
			
		||||
//		Let's first use OKHttp with the new endpoint without depending on our library operations
 | 
			
		||||
 | 
			
		||||
//    	UploadRemoteFileOperation uploadOperation = new UploadRemoteFileOperation(fileToUpload.getAbsolutePath(), remotePath, mimeType, timeStamp);
 | 
			
		||||
//    	uploadOperation.addDatatransferProgressListener(this);
 | 
			
		||||
//    	uploadOperation.execute(mClient, this, mHandler);
 | 
			
		||||
 | 
			
		||||
		if (!validServerAddress()) return;
 | 
			
		||||
 | 
			
		||||
		RequestBody requestBody = RequestBody.create(mediaType, fileToUpload);
 | 
			
		||||
 | 
			
		||||
		final Request request = new Request.Builder()
 | 
			
		||||
				.url(getString(R.string.server_base_url) + NEW_WEBDAV_PATH + getString(R.string.username) + remotePath)
 | 
			
		||||
				.addHeader(AUTHORIZATION_HEADER, mCredentials)
 | 
			
		||||
				.addHeader(USER_AGENT_HEADER, USER_AGENT_VALUE)
 | 
			
		||||
                .addHeader(CONTENT_TYPE_HEADER, CONTENT_TYPE_VALUE)
 | 
			
		||||
				.addHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(fileToUpload.length()))
 | 
			
		||||
				.addHeader(OC_X_OC_MTIME_HEADER, timeStamp)
 | 
			
		||||
				.put(requestBody)
 | 
			
		||||
				.build();
 | 
			
		||||
 | 
			
		||||
		mOkHttpClient.newCall(request).enqueue(new Callback() {
 | 
			
		||||
 | 
			
		||||
			@Override public void onResponse(Call call, final Response response) throws IOException {
 | 
			
		||||
 | 
			
		||||
				if (!response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
					showMessage("Response not successful with code: " + response.code());
 | 
			
		||||
 | 
			
		||||
					throw new IOException("Unexpected code " + response);
 | 
			
		||||
 | 
			
		||||
				} else { // Successful response
 | 
			
		||||
 | 
			
		||||
					showMessage("Successful upload of " + fileToUpload.getName());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override public void onFailure(Call call, IOException e) {
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
				showMessage("Something was wrong: " + e.toString());
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
    	UploadRemoteFileOperation uploadOperation = new UploadRemoteFileOperation(fileToUpload.getAbsolutePath(),
 | 
			
		||||
				remotePath, mimeType, timeStamp);
 | 
			
		||||
    	uploadOperation.addDatatransferProgressListener(this);
 | 
			
		||||
    	uploadOperation.execute(mClient, this, mHandler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	private void startDownload() {
 | 
			
		||||
		File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path));
 | 
			
		||||
		downFolder.mkdir();
 | 
			
		||||
    private void startRemoteDeletion() {
 | 
			
		||||
		File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path));
 | 
			
		||||
		final File fileToUpload = upFolder.listFiles()[0];
 | 
			
		||||
		File fileToUpload = upFolder.listFiles()[0];
 | 
			
		||||
		String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName();
 | 
			
		||||
 | 
			
		||||
//		Let's first use OKHttp with the new endpoint without depending on our library operations
 | 
			
		||||
    	RemoveRemoteFileOperation removeOperation = new RemoveRemoteFileOperation(remotePath);
 | 
			
		||||
    	removeOperation.execute(mClient, this, mHandler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//		DownloadRemoteFileOperation downloadOperation = new DownloadRemoteFileOperation(remotePath, downFolder.getAbsolutePath());
 | 
			
		||||
//		downloadOperation.addDatatransferProgressListener(this);
 | 
			
		||||
//		downloadOperation.execute(mClient, this, mHandler);
 | 
			
		||||
 | 
			
		||||
		if (!validServerAddress()) return;
 | 
			
		||||
 | 
			
		||||
		final Request request = new Request.Builder()
 | 
			
		||||
				.url(getString(R.string.server_base_url) + NEW_WEBDAV_PATH + getString(R.string.username) + remotePath)
 | 
			
		||||
				.addHeader(AUTHORIZATION_HEADER, mCredentials)
 | 
			
		||||
				.addHeader(USER_AGENT_HEADER, USER_AGENT_VALUE)
 | 
			
		||||
				.get()
 | 
			
		||||
				.build();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		mOkHttpClient.newCall(request).enqueue(new Callback() {
 | 
			
		||||
 | 
			
		||||
			@Override public void onResponse(Call call, final Response response) throws IOException {
 | 
			
		||||
 | 
			
		||||
				if (!response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
					showMessage("Response not successful with code: " + response.code());
 | 
			
		||||
 | 
			
		||||
					throw new IOException("Unexpected code " + response);
 | 
			
		||||
 | 
			
		||||
				} else { // Successful response
 | 
			
		||||
 | 
			
		||||
					showMessage("Successful download of " + fileToUpload.getName() + " although local file " +
 | 
			
		||||
							"won't be created in this stage");
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override public void onFailure(Call call, IOException e) {
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
				showMessage("Something was wrong: " + e.toString());
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void startRemoteDeletion() {
 | 
			
		||||
    private void startDownload() {
 | 
			
		||||
    	File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path));
 | 
			
		||||
    	downFolder.mkdir();
 | 
			
		||||
    	File upFolder = new File(getCacheDir(), getString(R.string.upload_folder_path));
 | 
			
		||||
    	final File fileToUpload = upFolder.listFiles()[0];
 | 
			
		||||
    	File fileToUpload = upFolder.listFiles()[0];
 | 
			
		||||
    	String remotePath = FileUtils.PATH_SEPARATOR + fileToUpload.getName();
 | 
			
		||||
 | 
			
		||||
//		Let's first use OKHttp with the new endpoint without depending on our library operations
 | 
			
		||||
//    	RemoveRemoteFileOperation removeOperation = new RemoveRemoteFileOperation(remotePath);
 | 
			
		||||
//    	removeOperation.execute(mClient, this, mHandler);
 | 
			
		||||
 | 
			
		||||
		if (!validServerAddress()) return;
 | 
			
		||||
 | 
			
		||||
		final Request request = new Request.Builder()
 | 
			
		||||
				.url(getString(R.string.server_base_url) + NEW_WEBDAV_PATH + getString(R.string.username) + remotePath)
 | 
			
		||||
				.addHeader(AUTHORIZATION_HEADER, mCredentials)
 | 
			
		||||
				.addHeader(USER_AGENT_HEADER, USER_AGENT_VALUE)
 | 
			
		||||
				.delete()
 | 
			
		||||
				.build();
 | 
			
		||||
 | 
			
		||||
		mOkHttpClient.newCall(request).enqueue(new Callback() {
 | 
			
		||||
 | 
			
		||||
			@Override public void onResponse(Call call, final Response response) throws IOException {
 | 
			
		||||
 | 
			
		||||
				if (!response.isSuccessful()) {
 | 
			
		||||
 | 
			
		||||
					showMessage("Response not successful with code: " + response.code());
 | 
			
		||||
 | 
			
		||||
					throw new IOException("Unexpected code " + response);
 | 
			
		||||
 | 
			
		||||
				} else { // Successful response
 | 
			
		||||
 | 
			
		||||
					showMessage("Successful deletion of " + fileToUpload.getName());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			@Override public void onFailure(Call call, IOException e) {
 | 
			
		||||
				e.printStackTrace();
 | 
			
		||||
				showMessage("Something was wrong: " + e.toString());
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
    	DownloadRemoteFileOperation downloadOperation = new DownloadRemoteFileOperation(remotePath,
 | 
			
		||||
				downFolder.getAbsolutePath());
 | 
			
		||||
    	downloadOperation.addDatatransferProgressListener(this);
 | 
			
		||||
    	downloadOperation.execute(mClient, this, mHandler);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @SuppressWarnings("deprecation")
 | 
			
		||||
 | 
			
		||||
	private void startLocalDeletion() {
 | 
			
		||||
    	File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path));
 | 
			
		||||
    	File downloadedFile = downFolder.listFiles()[0];
 | 
			
		||||
    	if (!downloadedFile.delete() && downloadedFile.exists()) {
 | 
			
		||||
    		Toast.makeText(this, R.string.error_deleting_local_file, Toast.LENGTH_SHORT).show();
 | 
			
		||||
    	} else {
 | 
			
		||||
//    		((TextView) findViewById(R.id.download_progress)).setText("0%");
 | 
			
		||||
//    		findViewById(R.id.frame).setBackgroundDrawable(null);
 | 
			
		||||
    		((TextView) findViewById(R.id.download_progress)).setText("0%");
 | 
			
		||||
    		findViewById(R.id.frame).setBackgroundDrawable(null);
 | 
			
		||||
    	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -444,14 +217,14 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
		} else if (operation instanceof ReadRemoteFolderOperation) {
 | 
			
		||||
			onSuccessfulRefresh((ReadRemoteFolderOperation)operation, result);
 | 
			
		||||
			
 | 
			
		||||
		} else if (operation instanceof UploadRemoteFileOperation ) {
 | 
			
		||||
			onSuccessfulUpload((UploadRemoteFileOperation)operation, result);
 | 
			
		||||
		} else if (operation instanceof com.owncloud.android.lib.resources.files.UploadRemoteFileOperation) {
 | 
			
		||||
			onSuccessfulUpload((com.owncloud.android.lib.resources.files.UploadRemoteFileOperation)operation, result);
 | 
			
		||||
			
 | 
			
		||||
		} else if (operation instanceof RemoveRemoteFileOperation ) {
 | 
			
		||||
			onSuccessfulRemoteDeletion((RemoveRemoteFileOperation)operation, result);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		} else if (operation instanceof DownloadRemoteFileOperation ) {
 | 
			
		||||
			onSuccessfulDownload((DownloadRemoteFileOperation)operation, result);
 | 
			
		||||
			onSuccessfulDownload();
 | 
			
		||||
			
 | 
			
		||||
		} else {
 | 
			
		||||
			Toast.makeText(this, R.string.todo_operation_finished_in_success, Toast.LENGTH_SHORT).show();
 | 
			
		||||
@ -460,9 +233,9 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
 | 
			
		||||
	private void onSuccessfulRefresh(ReadRemoteFolderOperation operation, RemoteOperationResult result) {
 | 
			
		||||
		mFilesAdapter.clear();
 | 
			
		||||
		List<RemoteFile> files = new ArrayList<RemoteFile>();
 | 
			
		||||
        for(Object obj: result.getData()) {
 | 
			
		||||
            files.add((RemoteFile) obj);
 | 
			
		||||
		List<RemoteFile> files = new ArrayList<>();
 | 
			
		||||
        for(RemoteFile remoteFile: (List<RemoteFile>) result.getData()) {
 | 
			
		||||
            files.add(remoteFile);
 | 
			
		||||
        }
 | 
			
		||||
		if (files != null) {
 | 
			
		||||
			Iterator<RemoteFile> it = files.iterator();
 | 
			
		||||
@ -474,20 +247,19 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
		mFilesAdapter.notifyDataSetChanged();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void onSuccessfulUpload(UploadRemoteFileOperation operation, RemoteOperationResult result) {
 | 
			
		||||
	private void onSuccessfulUpload(com.owncloud.android.lib.resources.files.UploadRemoteFileOperation operation, RemoteOperationResult result) {
 | 
			
		||||
		startRefresh();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void onSuccessfulRemoteDeletion(RemoveRemoteFileOperation operation, RemoteOperationResult result) {
 | 
			
		||||
		startRefresh();
 | 
			
		||||
//		TextView progressView = (TextView) findViewById(R.id.upload_progress);
 | 
			
		||||
//		if (progressView != null) {
 | 
			
		||||
//			progressView.setText("0%");
 | 
			
		||||
//		}
 | 
			
		||||
		TextView progressView = (TextView) findViewById(R.id.upload_progress);
 | 
			
		||||
		if (progressView != null) {
 | 
			
		||||
			progressView.setText("0%");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@SuppressWarnings("deprecation")
 | 
			
		||||
	private void onSuccessfulDownload(DownloadRemoteFileOperation operation, RemoteOperationResult result) {
 | 
			
		||||
	private void onSuccessfulDownload() {
 | 
			
		||||
    	File downFolder = new File(getCacheDir(), getString(R.string.download_folder_path));
 | 
			
		||||
    	File downloadedFile = downFolder.listFiles()[0];
 | 
			
		||||
    	BitmapDrawable bDraw = new BitmapDrawable(getResources(), downloadedFile.getAbsolutePath());
 | 
			
		||||
@ -503,11 +275,11 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
            @Override
 | 
			
		||||
            public void run() {
 | 
			
		||||
				TextView progressView = null;
 | 
			
		||||
//				if (upload) {
 | 
			
		||||
//					progressView = (TextView) findViewById(R.id.upload_progress);
 | 
			
		||||
//				} else {
 | 
			
		||||
//					progressView = (TextView) findViewById(R.id.download_progress);
 | 
			
		||||
//				}
 | 
			
		||||
				if (upload) {
 | 
			
		||||
					progressView = findViewById(R.id.upload_progress);
 | 
			
		||||
				} else {
 | 
			
		||||
					progressView = findViewById(R.id.download_progress);
 | 
			
		||||
				}
 | 
			
		||||
				if (progressView != null) {
 | 
			
		||||
	    			progressView.setText(Long.toString(percentage) + "%");
 | 
			
		||||
				}
 | 
			
		||||
@ -515,32 +287,24 @@ public class MainActivity extends Activity implements OnRemoteOperationListener,
 | 
			
		||||
        });
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private boolean validServerAddress() {
 | 
			
		||||
	// user agent
 | 
			
		||||
	@SuppressLint("StringFormatInvalid")
 | 
			
		||||
	private String getUserAgent() {
 | 
			
		||||
		String appString = getResources().getString(R.string.user_agent);
 | 
			
		||||
		String packageName = getPackageName();
 | 
			
		||||
		String version = "";
 | 
			
		||||
 | 
			
		||||
    	String serverAddress = ((TextView) findViewById(R.id.server_address)).getText().toString();
 | 
			
		||||
 | 
			
		||||
		if (serverAddress.equals("") || (!serverAddress.contains("http://") && !serverAddress.contains("https://"))) {
 | 
			
		||||
			showToastMessage("Introduce a proper server address with http/https");
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void showMessage(final String message) {
 | 
			
		||||
		runOnUiThread(new Runnable() {
 | 
			
		||||
			@Override
 | 
			
		||||
			public void run() {
 | 
			
		||||
 | 
			
		||||
				showToastMessage(message);
 | 
			
		||||
		PackageInfo pInfo;
 | 
			
		||||
		try {
 | 
			
		||||
			pInfo = getPackageManager().getPackageInfo(packageName, 0);
 | 
			
		||||
			if (pInfo != null) {
 | 
			
		||||
				version = pInfo.versionName;
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		} catch (PackageManager.NameNotFoundException e) {
 | 
			
		||||
			Log_OC.e(TAG, "Trying to get packageName", e.getCause());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Mozilla/5.0 (Android) ownCloud-android/1.7.0
 | 
			
		||||
		return String.format(appString, version);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void showToastMessage(String message) {
 | 
			
		||||
		Toast toast = Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG);
 | 
			
		||||
 | 
			
		||||
		toast.setGravity(Gravity.CENTER, 0, 0);
 | 
			
		||||
 | 
			
		||||
		toast.show();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,3 @@
 | 
			
		||||
include ':'
 | 
			
		||||
include ':sample_client'
 | 
			
		||||
include ':test_client'
 | 
			
		||||
include ':test_client'
 | 
			
		||||
@ -56,11 +56,8 @@ public class DynamicSessionManager implements OwnCloudClientManager {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveAllClients(Context context, String accountType)
 | 
			
		||||
        throws AccountUtils.AccountNotFoundException,
 | 
			
		||||
                AuthenticatorException, IOException, OperationCanceledException {
 | 
			
		||||
    public void saveAllClients(Context context, String accountType) {
 | 
			
		||||
        mSimpleFactoryManager.saveAllClients(context, accountType);
 | 
			
		||||
        mSingleSessionManager.saveAllClients(context, accountType);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -116,9 +116,8 @@ public class OwnCloudAccount {
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     * @throws OperationCanceledException
 | 
			
		||||
     */
 | 
			
		||||
    public void loadCredentials(Context context)
 | 
			
		||||
        throws AccountNotFoundException, AuthenticatorException,
 | 
			
		||||
                IOException, OperationCanceledException {
 | 
			
		||||
    public void loadCredentials(Context context) throws AuthenticatorException,
 | 
			
		||||
            IOException, OperationCanceledException {
 | 
			
		||||
 | 
			
		||||
        if (context == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Parameter 'context' cannot be null");
 | 
			
		||||
 | 
			
		||||
@ -1,23 +1,23 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2017 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -25,64 +25,50 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Cookie;
 | 
			
		||||
import org.apache.commons.httpclient.Header;
 | 
			
		||||
import org.apache.commons.httpclient.HostConfiguration;
 | 
			
		||||
import org.apache.commons.httpclient.HttpClient;
 | 
			
		||||
import org.apache.commons.httpclient.HttpConnectionManager;
 | 
			
		||||
import org.apache.commons.httpclient.HttpMethod;
 | 
			
		||||
import org.apache.commons.httpclient.HttpMethodBase;
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.HttpVersion;
 | 
			
		||||
import org.apache.commons.httpclient.URI;
 | 
			
		||||
import org.apache.commons.httpclient.URIException;
 | 
			
		||||
import org.apache.commons.httpclient.cookie.CookiePolicy;
 | 
			
		||||
import org.apache.commons.httpclient.params.HttpMethodParams;
 | 
			
		||||
import org.apache.commons.httpclient.params.HttpParams;
 | 
			
		||||
 | 
			
		||||
import android.accounts.AccountManager;
 | 
			
		||||
import android.accounts.AccountsException;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
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.accounts.AccountUtils;
 | 
			
		||||
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.network.RedirectionPath;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.RandomUtils;
 | 
			
		||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.exception.HttpException;
 | 
			
		||||
import okhttp3.Cookie;
 | 
			
		||||
import okhttp3.Headers;
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.http.HttpConstants.OC_X_REQUEST_ID;
 | 
			
		||||
 | 
			
		||||
public class OwnCloudClient extends HttpClient {
 | 
			
		||||
 | 
			
		||||
    public static final String WEBDAV_PATH_4_0 = "/remote.php/webdav";
 | 
			
		||||
    public static final String NEW_WEBDAV_FILES_PATH_4_0 = "/remote.php/dav/files/";
 | 
			
		||||
    public static final String NEW_WEBDAV_UPLOADS_PATH_4_0 = "/remote.php/dav/uploads/";
 | 
			
		||||
    public static final String STATUS_PATH = "/status.php";
 | 
			
		||||
    public static final String FILES_WEB_PATH = "/index.php/apps/files";
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = OwnCloudClient.class.getSimpleName();
 | 
			
		||||
    private static final int MAX_REDIRECTIONS_COUNT = 3;
 | 
			
		||||
    private static final int MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS = 1;
 | 
			
		||||
    private static final String PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
 | 
			
		||||
    private static final boolean PARAM_SINGLE_COOKIE_HEADER_VALUE = true;
 | 
			
		||||
    private static final String PARAM_PROTOCOL_VERSION = "http.protocol.version";
 | 
			
		||||
 | 
			
		||||
    private static byte[] sExhaustBuffer = new byte[1024];
 | 
			
		||||
 | 
			
		||||
    private static int sIntanceCounter = 0;
 | 
			
		||||
    private boolean mFollowRedirects = true;
 | 
			
		||||
    private OwnCloudCredentials mCredentials = null;
 | 
			
		||||
    private int mInstanceNumber = 0;
 | 
			
		||||
 | 
			
		||||
    private Uri mBaseUri;
 | 
			
		||||
 | 
			
		||||
    private OwnCloudVersion mVersion = null;
 | 
			
		||||
 | 
			
		||||
    /// next too attributes are a very ugly dependency, added to grant silent retry of OAuth token when needed ;
 | 
			
		||||
    /// see #shouldInvalidateCredentials and #invalidateCredentials for more details
 | 
			
		||||
    private Context mContext;
 | 
			
		||||
    private OwnCloudAccount mAccount;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -91,20 +77,11 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
     */
 | 
			
		||||
    private OwnCloudClientManager mOwnCloudClientManager = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * When 'true', the method {@link #executeMethod(HttpMethod)}  tries to silently refresh credentials
 | 
			
		||||
     * if fails due to lack of authorization, if credentials support authorization refresh.
 | 
			
		||||
     */
 | 
			
		||||
    private boolean mSilentRefreshOfAccountCredentials = true;
 | 
			
		||||
 | 
			
		||||
    private String mRedirectedLocation;
 | 
			
		||||
    private boolean mFollowRedirects;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     */
 | 
			
		||||
    public OwnCloudClient(Uri baseUri, HttpConnectionManager connectionMgr) {
 | 
			
		||||
        super(connectionMgr);
 | 
			
		||||
 | 
			
		||||
    public OwnCloudClient(Uri baseUri) {
 | 
			
		||||
        if (baseUri == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Parameter 'baseUri' cannot be NULL");
 | 
			
		||||
        }
 | 
			
		||||
@ -113,45 +90,10 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
        mInstanceNumber = sIntanceCounter++;
 | 
			
		||||
        Log_OC.d(TAG + " #" + mInstanceNumber, "Creating OwnCloudClient");
 | 
			
		||||
 | 
			
		||||
        String userAgent = OwnCloudClientManagerFactory.getUserAgent();
 | 
			
		||||
        getParams().setParameter(HttpMethodParams.USER_AGENT, userAgent);
 | 
			
		||||
        getParams().setParameter(
 | 
			
		||||
            PARAM_PROTOCOL_VERSION,
 | 
			
		||||
            HttpVersion.HTTP_1_1
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
 | 
			
		||||
        getParams().setParameter(
 | 
			
		||||
            PARAM_SINGLE_COOKIE_HEADER,             // to avoid problems with some web servers
 | 
			
		||||
            PARAM_SINGLE_COOKIE_HEADER_VALUE
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        applyProxySettings();
 | 
			
		||||
 | 
			
		||||
        clearCredentials();
 | 
			
		||||
        clearCookies();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private void applyProxySettings() {
 | 
			
		||||
        String proxyHost = System.getProperty("http.proxyHost");
 | 
			
		||||
        String proxyPortSt = System.getProperty("http.proxyPort");
 | 
			
		||||
        int proxyPort = 0;
 | 
			
		||||
        try {
 | 
			
		||||
            if (proxyPortSt != null && proxyPortSt.length() > 0) {
 | 
			
		||||
                proxyPort = Integer.parseInt(proxyPortSt);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            Log_OC.w(TAG, "Proxy port could not be read, keeping default value " + proxyPort);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (proxyHost != null && proxyHost.length() > 0) {
 | 
			
		||||
            HostConfiguration hostCfg = getHostConfiguration();
 | 
			
		||||
            hostCfg.setProxy(proxyHost, proxyPort);
 | 
			
		||||
            Log_OC.d(TAG, "Proxy settings: " + proxyHost + ":" + proxyPort);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void setCredentials(OwnCloudCredentials credentials) {
 | 
			
		||||
        if (credentials != null) {
 | 
			
		||||
            mCredentials = credentials;
 | 
			
		||||
@ -168,74 +110,22 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
        mCredentials.applyTo(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Requests the received method with the received timeout (milliseconds).
 | 
			
		||||
     *
 | 
			
		||||
     * Executes the method through the inherited HttpClient.executedMethod(method).
 | 
			
		||||
     *
 | 
			
		||||
     * Sets the socket and connection timeouts only for the method received.
 | 
			
		||||
     *
 | 
			
		||||
     * The timeouts are both in milliseconds; 0 means 'infinite';
 | 
			
		||||
     * < 0 means 'do not change the default'
 | 
			
		||||
     *
 | 
			
		||||
     * @param method            HTTP method request.
 | 
			
		||||
     * @param readTimeout       Timeout to set for data reception
 | 
			
		||||
     * @param connectionTimeout Timeout to set for connection establishment
 | 
			
		||||
     */
 | 
			
		||||
    public int executeMethod(HttpMethodBase method, int readTimeout, int connectionTimeout) throws IOException {
 | 
			
		||||
 | 
			
		||||
        int oldSoTimeout = getParams().getSoTimeout();
 | 
			
		||||
        int oldConnectionTimeout = getHttpConnectionManager().getParams().getConnectionTimeout();
 | 
			
		||||
        try {
 | 
			
		||||
            if (readTimeout >= 0) {
 | 
			
		||||
                method.getParams().setSoTimeout(readTimeout);   // this should be enough...
 | 
			
		||||
                getParams().setSoTimeout(readTimeout);          // ... but HTTPS needs this
 | 
			
		||||
            }
 | 
			
		||||
            if (connectionTimeout >= 0) {
 | 
			
		||||
                getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout);
 | 
			
		||||
            }
 | 
			
		||||
            return executeMethod(method);
 | 
			
		||||
        } finally {
 | 
			
		||||
            getParams().setSoTimeout(oldSoTimeout);
 | 
			
		||||
            getHttpConnectionManager().getParams().setConnectionTimeout(oldConnectionTimeout);
 | 
			
		||||
        }
 | 
			
		||||
    public void applyCredentials() {
 | 
			
		||||
        mCredentials.applyTo(this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Requests the received method.
 | 
			
		||||
     *
 | 
			
		||||
     * Executes the method through the inherited HttpClient.executedMethod(method).
 | 
			
		||||
     *
 | 
			
		||||
     * @param method HTTP method request.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public int executeMethod(HttpMethod method) throws IOException {
 | 
			
		||||
 | 
			
		||||
    public int executeHttpMethod (HttpBaseMethod method) throws Exception {
 | 
			
		||||
        boolean repeatWithFreshCredentials;
 | 
			
		||||
        int repeatCounter = 0;
 | 
			
		||||
        int status;
 | 
			
		||||
 | 
			
		||||
        do {
 | 
			
		||||
            // Update User Agent
 | 
			
		||||
            HttpParams params = method.getParams();
 | 
			
		||||
            String userAgent = OwnCloudClientManagerFactory.getUserAgent();
 | 
			
		||||
            params.setParameter(HttpMethodParams.USER_AGENT, userAgent);
 | 
			
		||||
 | 
			
		||||
            preventCrashDueToInvalidPort(method);
 | 
			
		||||
 | 
			
		||||
            Log_OC.d(TAG + " #" + mInstanceNumber, "REQUEST " +
 | 
			
		||||
            method.getName() + " " + method.getPath());
 | 
			
		||||
 | 
			
		||||
            //logCookiesAtRequest(method.getRequestHeaders(), "before");
 | 
			
		||||
            //logCookiesAtState("before");
 | 
			
		||||
            method.setFollowRedirects(false);
 | 
			
		||||
 | 
			
		||||
            status = super.executeMethod(method);
 | 
			
		||||
            setRequestId(method);
 | 
			
		||||
 | 
			
		||||
            status = method.execute();
 | 
			
		||||
            checkFirstRedirection(method);
 | 
			
		||||
 | 
			
		||||
            if (mFollowRedirects) {
 | 
			
		||||
            if(mFollowRedirects && !isIdPRedirection()) {
 | 
			
		||||
                status = followRedirection(method).getLastStatus();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -243,109 +133,105 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
            if (repeatWithFreshCredentials) {
 | 
			
		||||
                repeatCounter++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } while (repeatWithFreshCredentials);
 | 
			
		||||
 | 
			
		||||
        //logCookiesAtRequest(method.getRequestHeaders(), "after");
 | 
			
		||||
        //logCookiesAtState("after");
 | 
			
		||||
        //logSetCookiesAtResponse(method.getResponseHeaders());
 | 
			
		||||
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void checkFirstRedirection(HttpMethod method) {
 | 
			
		||||
        Header[] httpHeaders = method.getResponseHeaders();
 | 
			
		||||
    private void checkFirstRedirection(HttpBaseMethod method) {
 | 
			
		||||
        final String location = method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER);
 | 
			
		||||
        if(location != null && !location.isEmpty()) {
 | 
			
		||||
            mRedirectedLocation = location;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        for (Header httpHeader : httpHeaders) {
 | 
			
		||||
    private int executeRedirectedHttpMethod (HttpBaseMethod method) throws Exception {
 | 
			
		||||
        boolean repeatWithFreshCredentials;
 | 
			
		||||
        int repeatCounter = 0;
 | 
			
		||||
        int status;
 | 
			
		||||
 | 
			
		||||
            if ("location".equals(httpHeader.getName().toLowerCase())) {
 | 
			
		||||
                mRedirectedLocation = httpHeader.getValue();
 | 
			
		||||
                break;
 | 
			
		||||
        do {
 | 
			
		||||
            setRequestId(method);
 | 
			
		||||
 | 
			
		||||
            status = method.execute();
 | 
			
		||||
 | 
			
		||||
            repeatWithFreshCredentials = checkUnauthorizedAccess(status, repeatCounter);
 | 
			
		||||
            if (repeatWithFreshCredentials) {
 | 
			
		||||
                repeatCounter++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        } while (repeatWithFreshCredentials);
 | 
			
		||||
 | 
			
		||||
        return status;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Fix for https://github.com/owncloud/android/issues/1847#issuecomment-267558274
 | 
			
		||||
     *
 | 
			
		||||
     * The problem: default SocketFactory in HTTPClient 3.x for HTTP connections creates a separate thread
 | 
			
		||||
     * to create the socket. When a port out of TCP bounds is passed, an exception is thrown in that
 | 
			
		||||
     * separate thread, and our original thread is not able to catch it. This is not happenning with HTTPS
 | 
			
		||||
     * connections because we had to define our own socket factory,
 | 
			
		||||
     * {@link com.owncloud.android.lib.common.network.AdvancedSslSocketFactory}, and it does not mess with
 | 
			
		||||
     * threads.
 | 
			
		||||
     *
 | 
			
		||||
     * The solution: validate the input (the port number) ourselves before let the work to HTTPClient 3.x.
 | 
			
		||||
     *
 | 
			
		||||
     * @param method HTTP method to run.
 | 
			
		||||
     * @throws IllegalArgumentException If 'method' targets an invalid port in an HTTP URI.
 | 
			
		||||
     * @throws URIException             If the URI to the target server cannot be built.
 | 
			
		||||
     */
 | 
			
		||||
    private void preventCrashDueToInvalidPort(HttpMethod method) throws URIException {
 | 
			
		||||
        int port = method.getURI().getPort();
 | 
			
		||||
        String scheme = method.getURI().getScheme().toLowerCase();
 | 
			
		||||
        if ("http".equals(scheme) && port > 0xFFFF) {
 | 
			
		||||
            // < 0 is not tested because -1 is used when no port number is specified in the URL;
 | 
			
		||||
            // no problem, the network library will convert that in the default HTTP port
 | 
			
		||||
            throw new IllegalArgumentException("Invalid port number " + port);
 | 
			
		||||
        }
 | 
			
		||||
    private void setRequestId(HttpBaseMethod method) {
 | 
			
		||||
        // Clean previous request id. This is a bit hacky but is the only way to add request headers in WebDAV
 | 
			
		||||
        // methods by using Dav4Android
 | 
			
		||||
        deleteHeaderForAllRequests(OC_X_REQUEST_ID);
 | 
			
		||||
 | 
			
		||||
        String requestId = RandomUtils.generateRandomUUID();
 | 
			
		||||
 | 
			
		||||
        // Header to allow tracing requests in apache and ownCloud logs
 | 
			
		||||
        addHeaderForAllRequests(OC_X_REQUEST_ID, requestId);
 | 
			
		||||
 | 
			
		||||
        Log_OC.d(TAG, "Executing " + method.getClass().getSimpleName() + " in request with id " + requestId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public RedirectionPath followRedirection(HttpMethod method) throws IOException {
 | 
			
		||||
    public RedirectionPath followRedirection(HttpBaseMethod method) throws Exception {
 | 
			
		||||
        int redirectionsCount = 0;
 | 
			
		||||
        int status = method.getStatusCode();
 | 
			
		||||
        RedirectionPath result = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT);
 | 
			
		||||
        RedirectionPath redirectionPath = new RedirectionPath(status, MAX_REDIRECTIONS_COUNT);
 | 
			
		||||
 | 
			
		||||
        while (redirectionsCount < MAX_REDIRECTIONS_COUNT &&
 | 
			
		||||
            (status == HttpStatus.SC_MOVED_PERMANENTLY ||
 | 
			
		||||
                status == HttpStatus.SC_MOVED_TEMPORARILY ||
 | 
			
		||||
                status == HttpStatus.SC_TEMPORARY_REDIRECT)
 | 
			
		||||
            ) {
 | 
			
		||||
                (status == HttpConstants.HTTP_MOVED_PERMANENTLY ||
 | 
			
		||||
                        status == HttpConstants.HTTP_MOVED_TEMPORARILY ||
 | 
			
		||||
                        status == HttpConstants.HTTP_TEMPORARY_REDIRECT)
 | 
			
		||||
                ) {
 | 
			
		||||
 | 
			
		||||
            final String location = method.getResponseHeader(HttpConstants.LOCATION_HEADER) != null
 | 
			
		||||
                    ? method.getResponseHeader(HttpConstants.LOCATION_HEADER)
 | 
			
		||||
                    : method.getResponseHeader(HttpConstants.LOCATION_HEADER_LOWER);
 | 
			
		||||
 | 
			
		||||
            Header location = method.getResponseHeader("Location");
 | 
			
		||||
            if (location == null) {
 | 
			
		||||
                location = method.getResponseHeader("location");
 | 
			
		||||
            }
 | 
			
		||||
            if (location != null) {
 | 
			
		||||
                String locationStr = location.getValue();
 | 
			
		||||
 | 
			
		||||
                Log_OC.d(TAG + " #" + mInstanceNumber,
 | 
			
		||||
                    "Location to redirect: " + locationStr);
 | 
			
		||||
                        "Location to redirect: " + location);
 | 
			
		||||
 | 
			
		||||
                result.addLocation(locationStr);
 | 
			
		||||
                redirectionPath.addLocation(location);
 | 
			
		||||
 | 
			
		||||
                // Release the connection to avoid reach the max number of connections per host
 | 
			
		||||
                // due to it will be set a different url
 | 
			
		||||
                exhaustResponse(method.getResponseBodyAsStream());
 | 
			
		||||
                method.releaseConnection();
 | 
			
		||||
 | 
			
		||||
                method.setURI(new URI(locationStr, true));
 | 
			
		||||
                Header destination = method.getRequestHeader("Destination");
 | 
			
		||||
                if (destination == null) {
 | 
			
		||||
                    destination = method.getRequestHeader("destination");
 | 
			
		||||
                }
 | 
			
		||||
                method.setUrl(HttpUrl.parse(location));
 | 
			
		||||
                final String destination = method.getRequestHeader("Destination") != null
 | 
			
		||||
                        ? method.getRequestHeader("Destination")
 | 
			
		||||
                        : method.getRequestHeader("destination");
 | 
			
		||||
 | 
			
		||||
                if (destination != null) {
 | 
			
		||||
                    int suffixIndex = locationStr.lastIndexOf(WEBDAV_PATH_4_0);
 | 
			
		||||
                    String redirectionBase = locationStr.substring(0, suffixIndex);
 | 
			
		||||
                    final int suffixIndex = location.lastIndexOf(getNewFilesWebDavUri().toString());
 | 
			
		||||
                    final String redirectionBase = location.substring(0, suffixIndex);
 | 
			
		||||
                    final String destinationPath = destination.substring(mBaseUri.toString().length());
 | 
			
		||||
 | 
			
		||||
                    String destinationStr = destination.getValue();
 | 
			
		||||
                    String destinationPath = destinationStr.substring(mBaseUri.toString().length());
 | 
			
		||||
                    String redirectedDestination = redirectionBase + destinationPath;
 | 
			
		||||
 | 
			
		||||
                    destination.setValue(redirectedDestination);
 | 
			
		||||
                    method.setRequestHeader(destination);
 | 
			
		||||
                    method.setRequestHeader("destination", redirectionBase + destinationPath);
 | 
			
		||||
                }
 | 
			
		||||
                status = super.executeMethod(method);
 | 
			
		||||
                result.addStatus(status);
 | 
			
		||||
                try {
 | 
			
		||||
                    status = executeRedirectedHttpMethod(method);
 | 
			
		||||
                } catch (HttpException e) {
 | 
			
		||||
                    if(e.getMessage().contains(Integer.toString(HttpConstants.HTTP_MOVED_TEMPORARILY))) {
 | 
			
		||||
                        status = HttpConstants.HTTP_MOVED_TEMPORARILY;
 | 
			
		||||
                    } else  {
 | 
			
		||||
                        throw e;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                redirectionPath.addStatus(status);
 | 
			
		||||
                redirectionsCount++;
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                Log_OC.d(TAG + " #" + mInstanceNumber, "No location to redirect!");
 | 
			
		||||
                status = HttpStatus.SC_NOT_FOUND;
 | 
			
		||||
                status = HttpConstants.HTTP_NOT_FOUND;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
        return redirectionPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -361,26 +247,21 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
 | 
			
		||||
            } catch (IOException io) {
 | 
			
		||||
                Log_OC.e(TAG, "Unexpected exception while exhausting not interesting HTTP response;" +
 | 
			
		||||
                    " will be IGNORED", io);
 | 
			
		||||
                        " will be IGNORED", io);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Sets the connection and wait-for-data timeouts to be applied by default to the methods
 | 
			
		||||
     * performed by this client.
 | 
			
		||||
     */
 | 
			
		||||
    public void setDefaultTimeouts(int defaultDataTimeout, int defaultConnectionTimeout) {
 | 
			
		||||
        if (defaultDataTimeout >= 0) {
 | 
			
		||||
            getParams().setSoTimeout(defaultDataTimeout);
 | 
			
		||||
        }
 | 
			
		||||
        if (defaultConnectionTimeout >= 0) {
 | 
			
		||||
            getHttpConnectionManager().getParams().setConnectionTimeout(defaultConnectionTimeout);
 | 
			
		||||
        }
 | 
			
		||||
    public Uri getNewFilesWebDavUri() {
 | 
			
		||||
        return mCredentials instanceof OwnCloudAnonymousCredentials
 | 
			
		||||
                ? Uri.parse(mBaseUri + NEW_WEBDAV_FILES_PATH_4_0)
 | 
			
		||||
                : Uri.parse(mBaseUri + NEW_WEBDAV_FILES_PATH_4_0 + mCredentials.getUsername());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Uri getWebdavUri() {
 | 
			
		||||
        return Uri.parse(mBaseUri + WEBDAV_PATH_4_0);
 | 
			
		||||
    public Uri getNewUploadsWebDavUri() {
 | 
			
		||||
        return mCredentials instanceof OwnCloudAnonymousCredentials
 | 
			
		||||
                ? Uri.parse(mBaseUri + NEW_WEBDAV_UPLOADS_PATH_4_0)
 | 
			
		||||
                : Uri.parse(mBaseUri + NEW_WEBDAV_UPLOADS_PATH_4_0 + mCredentials.getUsername());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -405,52 +286,32 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
        return mCredentials;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setFollowRedirects(boolean followRedirects) {
 | 
			
		||||
        mFollowRedirects = followRedirects;
 | 
			
		||||
    private void logCookie(Cookie cookie) {
 | 
			
		||||
        Log_OC.d(TAG, "Cookie name: " + cookie.name());
 | 
			
		||||
        Log_OC.d(TAG, "       value: " + cookie.value());
 | 
			
		||||
        Log_OC.d(TAG, "       domain: " + cookie.domain());
 | 
			
		||||
        Log_OC.d(TAG, "       path: " + cookie.path());
 | 
			
		||||
        Log_OC.d(TAG, "       expiryDate: " + cookie.expiresAt());
 | 
			
		||||
        Log_OC.d(TAG, "       secure: " + cookie.secure());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean getFollowRedirects() {
 | 
			
		||||
        return mFollowRedirects;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void logCookiesAtRequest(Header[] headers, String when) {
 | 
			
		||||
    private void logCookiesAtRequest(Headers headers, String when) {
 | 
			
		||||
        int counter = 0;
 | 
			
		||||
        for (int i = 0; i < headers.length; i++) {
 | 
			
		||||
            if (headers[i].getName().toLowerCase().equals("cookie")) {
 | 
			
		||||
                Log_OC.d(TAG + " #" + mInstanceNumber,
 | 
			
		||||
                    "Cookies at request (" + when + ") (" + counter++ + "): " +
 | 
			
		||||
                        headers[i].getValue());
 | 
			
		||||
            }
 | 
			
		||||
        for (final String cookieHeader : headers.toMultimap().get("cookie")) {
 | 
			
		||||
            Log_OC.d(TAG + " #" + mInstanceNumber,
 | 
			
		||||
                    "Cookies at request (" + when + ") (" + counter++ + "): "
 | 
			
		||||
                            + cookieHeader);
 | 
			
		||||
        }
 | 
			
		||||
        if (counter == 0) {
 | 
			
		||||
            Log_OC.d(TAG + " #" + mInstanceNumber, "No cookie at request before");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void logCookiesAtState(String string) {
 | 
			
		||||
        Cookie[] cookies = getState().getCookies();
 | 
			
		||||
        if (cookies.length == 0) {
 | 
			
		||||
            Log_OC.d(TAG + " #" + mInstanceNumber, "No cookie at STATE before");
 | 
			
		||||
        } else {
 | 
			
		||||
            Log_OC.d(TAG + " #" + mInstanceNumber, "Cookies at STATE (before)");
 | 
			
		||||
            for (int i = 0; i < cookies.length; i++) {
 | 
			
		||||
                Log_OC.d(TAG + " #" + mInstanceNumber, "    (" + i + "):" +
 | 
			
		||||
                    "\n        name: " + cookies[i].getName() +
 | 
			
		||||
                    "\n        value: " + cookies[i].getValue() +
 | 
			
		||||
                    "\n        domain: " + cookies[i].getDomain() +
 | 
			
		||||
                    "\n        path: " + cookies[i].getPath()
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void logSetCookiesAtResponse(Header[] headers) {
 | 
			
		||||
    private void logSetCookiesAtResponse(Headers headers) {
 | 
			
		||||
        int counter = 0;
 | 
			
		||||
        for (int i = 0; i < headers.length; i++) {
 | 
			
		||||
            if (headers[i].getName().toLowerCase().equals("set-cookie")) {
 | 
			
		||||
                Log_OC.d(TAG + " #" + mInstanceNumber,
 | 
			
		||||
                    "Set-Cookie (" + counter++ + "): " + headers[i].getValue());
 | 
			
		||||
            }
 | 
			
		||||
        for (final String cookieHeader : headers.toMultimap().get("set-cookie")) {
 | 
			
		||||
            Log_OC.d(TAG + " #" + mInstanceNumber,
 | 
			
		||||
                    "Set-Cookie (" + counter++ + "): " + cookieHeader);
 | 
			
		||||
        }
 | 
			
		||||
        if (counter == 0) {
 | 
			
		||||
            Log_OC.d(TAG + " #" + mInstanceNumber, "No set-cookie");
 | 
			
		||||
@ -458,39 +319,25 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getCookiesString() {
 | 
			
		||||
        Cookie[] cookies = getState().getCookies();
 | 
			
		||||
        String cookiesString = "";
 | 
			
		||||
        for (Cookie cookie : cookies) {
 | 
			
		||||
            cookiesString = cookiesString + cookie.toString() + ";";
 | 
			
		||||
        List<Cookie> cookieList = getCookiesFromUrl(HttpUrl.parse(mBaseUri.toString()));
 | 
			
		||||
 | 
			
		||||
            // logCookie(cookie);
 | 
			
		||||
        if (cookieList != null) {
 | 
			
		||||
            for (Cookie cookie : cookieList) {
 | 
			
		||||
                cookiesString += cookie.toString() + ";";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return cookiesString;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getConnectionTimeout() {
 | 
			
		||||
        return getHttpConnectionManager().getParams().getConnectionTimeout();
 | 
			
		||||
    public void setCookiesForCurrentAccount(List<Cookie> cookies) {
 | 
			
		||||
        getOkHttpClient().cookieJar().saveFromResponse(
 | 
			
		||||
                HttpUrl.parse(getAccount().getBaseUri().toString()),
 | 
			
		||||
                cookies
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getDataTimeout() {
 | 
			
		||||
        return getParams().getSoTimeout();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void logCookie(Cookie cookie) {
 | 
			
		||||
        Log_OC.d(TAG, "Cookie name: " + cookie.getName());
 | 
			
		||||
        Log_OC.d(TAG, "       value: " + cookie.getValue());
 | 
			
		||||
        Log_OC.d(TAG, "       domain: " + cookie.getDomain());
 | 
			
		||||
        Log_OC.d(TAG, "       path: " + cookie.getPath());
 | 
			
		||||
        Log_OC.d(TAG, "       version: " + cookie.getVersion());
 | 
			
		||||
        Log_OC.d(TAG, "       expiryDate: " +
 | 
			
		||||
            (cookie.getExpiryDate() != null ? cookie.getExpiryDate().toString() : "--"));
 | 
			
		||||
        Log_OC.d(TAG, "       comment: " + cookie.getComment());
 | 
			
		||||
        Log_OC.d(TAG, "       secure: " + cookie.getSecure());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void setOwnCloudVersion(OwnCloudVersion version) {
 | 
			
		||||
        mVersion = version;
 | 
			
		||||
    }
 | 
			
		||||
@ -499,14 +346,6 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
        return mVersion;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setContext(Context context) {
 | 
			
		||||
        this.mContext = context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Context getContext() {
 | 
			
		||||
        return mContext;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAccount(OwnCloudAccount account) {
 | 
			
		||||
        this.mAccount = account;
 | 
			
		||||
    }
 | 
			
		||||
@ -515,18 +354,6 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
        return mAccount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Enables or disables silent refresh of credentials, if supported by credentials themselves.
 | 
			
		||||
     */
 | 
			
		||||
    public void setSilentRefreshOfAccountCredentials(boolean silentRefreshOfAccountCredentials) {
 | 
			
		||||
        mSilentRefreshOfAccountCredentials = silentRefreshOfAccountCredentials;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean getSilentRefreshOfAccountCredentials() {
 | 
			
		||||
        return mSilentRefreshOfAccountCredentials;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks the status code of an execution and decides if should be repeated with fresh credentials.
 | 
			
		||||
     *
 | 
			
		||||
@ -546,19 +373,19 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
 | 
			
		||||
            if (invalidated) {
 | 
			
		||||
                if (getCredentials().authTokenCanBeRefreshed() &&
 | 
			
		||||
                    repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS) {
 | 
			
		||||
                        repeatCounter < MAX_REPEAT_COUNT_WITH_FRESH_CREDENTIALS) {
 | 
			
		||||
 | 
			
		||||
                    try {
 | 
			
		||||
                        mAccount.loadCredentials(mContext);
 | 
			
		||||
                        mAccount.loadCredentials(getContext());
 | 
			
		||||
                        // if mAccount.getCredentials().length() == 0 --> refresh failed
 | 
			
		||||
                        setCredentials(mAccount.getCredentials());
 | 
			
		||||
                        credentialsWereRefreshed = true;
 | 
			
		||||
 | 
			
		||||
                    } catch (AccountsException | IOException e) {
 | 
			
		||||
                        Log_OC.e(
 | 
			
		||||
                            TAG,
 | 
			
		||||
                            "Error while trying to refresh auth token for " + mAccount.getSavedAccount().name,
 | 
			
		||||
                            e
 | 
			
		||||
                                TAG,
 | 
			
		||||
                                "Error while trying to refresh auth token for " + mAccount.getSavedAccount().name,
 | 
			
		||||
                                e
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@ -569,7 +396,7 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
                    mOwnCloudClientManager.removeClientFor(mAccount);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            // else: execute will finish with status 401
 | 
			
		||||
            // else: onExecute will finish with status 401
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return credentialsWereRefreshed;
 | 
			
		||||
@ -586,13 +413,13 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
     */
 | 
			
		||||
    private boolean shouldInvalidateAccountCredentials(int httpStatusCode) {
 | 
			
		||||
 | 
			
		||||
        boolean should = (httpStatusCode == HttpStatus.SC_UNAUTHORIZED || isIdPRedirection());   // invalid credentials
 | 
			
		||||
        boolean should = (httpStatusCode == HttpConstants.HTTP_UNAUTHORIZED || isIdPRedirection());   // invalid credentials
 | 
			
		||||
 | 
			
		||||
        should &= (mCredentials != null &&         // real credentials
 | 
			
		||||
            !(mCredentials instanceof OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials));
 | 
			
		||||
                !(mCredentials instanceof OwnCloudCredentialsFactory.OwnCloudAnonymousCredentials));
 | 
			
		||||
 | 
			
		||||
        // test if have all the needed to effectively invalidate ...
 | 
			
		||||
        should &= (mAccount != null && mAccount.getSavedAccount() != null && mContext != null);
 | 
			
		||||
        should &= (mAccount != null && mAccount.getSavedAccount() != null && getContext() != null);
 | 
			
		||||
 | 
			
		||||
        return should;
 | 
			
		||||
    }
 | 
			
		||||
@ -606,10 +433,10 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
     * @return                  'True' if invalidation was successful, 'false' otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    private boolean invalidateAccountCredentials() {
 | 
			
		||||
        AccountManager am = AccountManager.get(mContext);
 | 
			
		||||
        AccountManager am = AccountManager.get(getContext());
 | 
			
		||||
        am.invalidateAuthToken(
 | 
			
		||||
            mAccount.getSavedAccount().type,
 | 
			
		||||
            mCredentials.getAuthToken()
 | 
			
		||||
                mAccount.getSavedAccount().type,
 | 
			
		||||
                mCredentials.getAuthToken()
 | 
			
		||||
        );
 | 
			
		||||
        am.clearPassword(mAccount.getSavedAccount()); // being strict, only needed for Basic Auth credentials
 | 
			
		||||
        return true;
 | 
			
		||||
@ -632,4 +459,12 @@ public class OwnCloudClient extends HttpClient {
 | 
			
		||||
                (mRedirectedLocation.toUpperCase().contains("SAML") ||
 | 
			
		||||
                        mRedirectedLocation.toLowerCase().contains("wayf")));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    public boolean followRedirects() {
 | 
			
		||||
        return mFollowRedirects;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setFollowRedirects(boolean followRedirects) {
 | 
			
		||||
        this.mFollowRedirects = followRedirects;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,9 +24,6 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.security.GeneralSecurityException;
 | 
			
		||||
 | 
			
		||||
import android.accounts.Account;
 | 
			
		||||
import android.accounts.AccountManager;
 | 
			
		||||
import android.accounts.AccountManagerFuture;
 | 
			
		||||
@ -40,21 +37,14 @@ import android.os.Bundle;
 | 
			
		||||
import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
 | 
			
		||||
import com.owncloud.android.lib.common.network.NetworkUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
public class OwnCloudClientFactory {
 | 
			
		||||
    
 | 
			
		||||
    final private static String TAG = OwnCloudClientFactory.class.getSimpleName();
 | 
			
		||||
    
 | 
			
		||||
    /** 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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a OwnCloudClient setup for an ownCloud account
 | 
			
		||||
@ -122,9 +112,6 @@ public class OwnCloudClientFactory {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            //String password = am.getPassword(account);
 | 
			
		||||
            //String password = am.blockingGetAuthToken(account, MainApp.getAuthTokenTypePass(),
 | 
			
		||||
            // false);
 | 
			
		||||
            AccountManagerFuture<Bundle> future =  am.getAuthToken(
 | 
			
		||||
                account,
 | 
			
		||||
                AccountTypeUtils.getAuthTokenTypePass(account.type),
 | 
			
		||||
@ -162,24 +149,12 @@ public class OwnCloudClientFactory {
 | 
			
		||||
     */
 | 
			
		||||
    public static OwnCloudClient createOwnCloudClient(Uri uri, Context context,
 | 
			
		||||
                                                      boolean followRedirects) {
 | 
			
		||||
        try {
 | 
			
		||||
            NetworkUtils.registerAdvancedSslContext(true, context);
 | 
			
		||||
        }  catch (GeneralSecurityException e) {
 | 
			
		||||
            Log_OC.e(TAG, "Advanced SSL Context could not be loaded. Default SSL management in" +
 | 
			
		||||
                    " the system will be used for HTTPS connections", e);
 | 
			
		||||
            
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            Log_OC.e(TAG, "The local server truststore could not be read. Default SSL management" +
 | 
			
		||||
                    " in the system will be used for HTTPS connections", e);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        OwnCloudClient client = new OwnCloudClient(uri, NetworkUtils.getMultiThreadedConnManager());
 | 
			
		||||
        client.setDefaultTimeouts(DEFAULT_DATA_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
 | 
			
		||||
        OwnCloudClient client = new OwnCloudClient(uri);
 | 
			
		||||
 | 
			
		||||
        client.setFollowRedirects(followRedirects);
 | 
			
		||||
 | 
			
		||||
        client.setContext(context);
 | 
			
		||||
        
 | 
			
		||||
        return client;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -32,24 +32,23 @@ 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. 
 | 
			
		||||
 * 
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public interface OwnCloudClientManager {
 | 
			
		||||
 | 
			
		||||
	public OwnCloudClient getClientFor(OwnCloudAccount account, Context context)
 | 
			
		||||
            throws AccountNotFoundException, OperationCanceledException, AuthenticatorException,
 | 
			
		||||
	OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws AccountNotFoundException,
 | 
			
		||||
			OperationCanceledException, AuthenticatorException,
 | 
			
		||||
            IOException;
 | 
			
		||||
    
 | 
			
		||||
    public OwnCloudClient removeClientFor(OwnCloudAccount account);
 | 
			
		||||
    OwnCloudClient removeClientFor(OwnCloudAccount account);
 | 
			
		||||
 | 
			
		||||
    public void saveAllClients(Context context, String accountType)
 | 
			
		||||
    void saveAllClients(Context context, String accountType)
 | 
			
		||||
			throws AccountNotFoundException, AuthenticatorException, 
 | 
			
		||||
			IOException, OperationCanceledException;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -100,5 +100,4 @@ public class OwnCloudClientManagerFactory {
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -40,9 +40,8 @@ public class SimpleFactoryManager implements OwnCloudClientManager {
 | 
			
		||||
    private static final String TAG = SimpleFactoryManager.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public OwnCloudClient getClientFor(OwnCloudAccount account, Context context)
 | 
			
		||||
        throws AccountNotFoundException, OperationCanceledException, AuthenticatorException,
 | 
			
		||||
        IOException {
 | 
			
		||||
    public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws
 | 
			
		||||
            OperationCanceledException, AuthenticatorException, IOException {
 | 
			
		||||
 | 
			
		||||
        Log_OC.d(TAG, "getClientFor(OwnCloudAccount ... : ");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,14 +24,8 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.cookie.CookiePolicy;
 | 
			
		||||
 | 
			
		||||
import android.accounts.Account;
 | 
			
		||||
import android.accounts.AccountManager;
 | 
			
		||||
import android.accounts.AuthenticatorException;
 | 
			
		||||
import android.accounts.OperationCanceledException;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
@ -39,17 +33,23 @@ import android.net.Uri;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
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.OwnCloudSamlSsoCredentials;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.concurrent.ConcurrentHashMap;
 | 
			
		||||
import java.util.concurrent.ConcurrentMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implementation of {@link OwnCloudClientManager}
 | 
			
		||||
 * <p>
 | 
			
		||||
 *
 | 
			
		||||
 * TODO check multithreading safety
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
@ -57,16 +57,15 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
    private static final String TAG = SingleSessionManager.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private ConcurrentMap<String, OwnCloudClient> mClientsWithKnownUsername =
 | 
			
		||||
        new ConcurrentHashMap<String, OwnCloudClient>();
 | 
			
		||||
        new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
    private ConcurrentMap<String, OwnCloudClient> mClientsWithUnknownUsername =
 | 
			
		||||
        new ConcurrentHashMap<String, OwnCloudClient>();
 | 
			
		||||
        new ConcurrentHashMap<>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public OwnCloudClient getClientFor(OwnCloudAccount account, Context context)
 | 
			
		||||
        throws AccountNotFoundException, OperationCanceledException, AuthenticatorException,
 | 
			
		||||
        IOException {
 | 
			
		||||
    public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) throws OperationCanceledException,
 | 
			
		||||
            AuthenticatorException, IOException {
 | 
			
		||||
 | 
			
		||||
        if (Log.isLoggable(TAG, Log.DEBUG)) {
 | 
			
		||||
            Log_OC.d(TAG, "getClientFor starting ");
 | 
			
		||||
@ -80,8 +79,7 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
        String sessionName = account.getCredentials() == null ? "" :
 | 
			
		||||
            AccountUtils.buildAccountName(
 | 
			
		||||
                account.getBaseUri(),
 | 
			
		||||
                account.getCredentials().getAuthToken()
 | 
			
		||||
            );
 | 
			
		||||
                account.getCredentials().getAuthToken());
 | 
			
		||||
 | 
			
		||||
        if (accountName != null) {
 | 
			
		||||
            client = mClientsWithKnownUsername.get(accountName);
 | 
			
		||||
@ -115,16 +113,17 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
                account.getBaseUri(),
 | 
			
		||||
                context.getApplicationContext(),
 | 
			
		||||
                true);    // TODO remove dependency on OwnCloudClientFactory
 | 
			
		||||
            client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
 | 
			
		||||
            client.setAccount(account);
 | 
			
		||||
            client.setContext(context);
 | 
			
		||||
            client.setOwnCloudClientManager(this);
 | 
			
		||||
 | 
			
		||||
            // enable cookie tracking
 | 
			
		||||
            AccountUtils.restoreCookies(account.getSavedAccount(), client, context);
 | 
			
		||||
 | 
			
		||||
            account.loadCredentials(context);
 | 
			
		||||
            client.setCredentials(account.getCredentials());
 | 
			
		||||
 | 
			
		||||
            if (client.getCredentials() instanceof OwnCloudSamlSsoCredentials) {
 | 
			
		||||
                client.disableAutomaticCookiesHandling();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (accountName != null) {
 | 
			
		||||
                mClientsWithKnownUsername.put(accountName, client);
 | 
			
		||||
                if (Log.isLoggable(TAG, Log.VERBOSE)) {
 | 
			
		||||
@ -141,7 +140,9 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
            if (!reusingKnown && Log.isLoggable(TAG, Log.VERBOSE)) {
 | 
			
		||||
                Log_OC.v(TAG, "reusing client for session " + sessionName);
 | 
			
		||||
            }
 | 
			
		||||
            keepCredentialsUpdated(account, client);
 | 
			
		||||
 | 
			
		||||
            keepCredentialsUpdated(client);
 | 
			
		||||
            keepCookiesUpdated(context, account, client);
 | 
			
		||||
            keepUriUpdated(account, client);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -154,7 +155,6 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public OwnCloudClient removeClientFor(OwnCloudAccount account) {
 | 
			
		||||
 | 
			
		||||
        if (Log.isLoggable(TAG, Log.DEBUG)) {
 | 
			
		||||
            Log_OC.d(TAG, "removeClientFor starting ");
 | 
			
		||||
        }
 | 
			
		||||
@ -185,14 +185,11 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
            Log_OC.d(TAG, "removeClientFor finishing ");
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void saveAllClients(Context context, String accountType)
 | 
			
		||||
        throws AccountNotFoundException, AuthenticatorException, IOException,
 | 
			
		||||
        OperationCanceledException {
 | 
			
		||||
    public void saveAllClients(Context context, String accountType) {
 | 
			
		||||
 | 
			
		||||
        if (Log.isLoggable(TAG, Log.DEBUG)) {
 | 
			
		||||
            Log_OC.d(TAG, "Saving sessions... ");
 | 
			
		||||
@ -215,14 +212,19 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void keepCredentialsUpdated(OwnCloudClient reusedClient) {
 | 
			
		||||
        reusedClient.applyCredentials();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void keepCredentialsUpdated(OwnCloudAccount account, OwnCloudClient reusedClient) {
 | 
			
		||||
        OwnCloudCredentials recentCredentials = account.getCredentials();
 | 
			
		||||
        if (recentCredentials != null && !recentCredentials.getAuthToken().equals(
 | 
			
		||||
            reusedClient.getCredentials().getAuthToken())) {
 | 
			
		||||
            reusedClient.setCredentials(recentCredentials);
 | 
			
		||||
    private void keepCookiesUpdated(Context context, OwnCloudAccount account, OwnCloudClient reusedClient) {
 | 
			
		||||
        AccountManager am = AccountManager.get(context.getApplicationContext());
 | 
			
		||||
        if (am != null && account.getSavedAccount() != null) {
 | 
			
		||||
            String recentCookies = am.getUserData(account.getSavedAccount(), AccountUtils.Constants.KEY_COOKIES);
 | 
			
		||||
            String previousCookies = reusedClient.getCookiesString();
 | 
			
		||||
            if (recentCookies != null && previousCookies != "" && !recentCookies.equals(previousCookies)) {
 | 
			
		||||
                AccountUtils.restoreCookies(account.getSavedAccount(), reusedClient, context);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // this method is just a patch; we need to distinguish accounts in the same host but
 | 
			
		||||
@ -232,8 +234,5 @@ public class SingleSessionManager implements OwnCloudClientManager {
 | 
			
		||||
        if (!recentUri.equals(reusedClient.getBaseUri())) {
 | 
			
		||||
            reusedClient.setBaseUri(recentUri);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2017 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2012  Bartek Przybylski
 | 
			
		||||
 *   
 | 
			
		||||
 *   Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
@ -25,11 +25,6 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common.accounts;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Cookie;
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
 | 
			
		||||
import android.accounts.Account;
 | 
			
		||||
import android.accounts.AccountManager;
 | 
			
		||||
import android.accounts.AccountsException;
 | 
			
		||||
@ -38,15 +33,19 @@ import android.accounts.OperationCanceledException;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudAccount;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.FileUtils;
 | 
			
		||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import okhttp3.Cookie;
 | 
			
		||||
 | 
			
		||||
public class AccountUtils {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = AccountUtils.class.getSimpleName();
 | 
			
		||||
@ -61,11 +60,23 @@ public class AccountUtils {
 | 
			
		||||
     */
 | 
			
		||||
    public static String getWebDavUrlForAccount(Context context, Account account)
 | 
			
		||||
        throws AccountNotFoundException {
 | 
			
		||||
        String webDavUrlForAccount = "";
 | 
			
		||||
 | 
			
		||||
        return getBaseUrlForAccount(context, account) + OwnCloudClient.WEBDAV_PATH_4_0;
 | 
			
		||||
        try {
 | 
			
		||||
            OwnCloudCredentials ownCloudCredentials = getCredentialsForAccount(context, account);
 | 
			
		||||
            webDavUrlForAccount = getBaseUrlForAccount(context, account) + OwnCloudClient.NEW_WEBDAV_FILES_PATH_4_0
 | 
			
		||||
                    + ownCloudCredentials.getUsername();
 | 
			
		||||
        } catch (OperationCanceledException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        } catch (AuthenticatorException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return webDavUrlForAccount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Extracts url server from the account
 | 
			
		||||
     *
 | 
			
		||||
@ -86,7 +97,6 @@ public class AccountUtils {
 | 
			
		||||
        return baseurl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the username corresponding to an OC account.
 | 
			
		||||
     *
 | 
			
		||||
@ -132,7 +142,7 @@ public class AccountUtils {
 | 
			
		||||
    public static OwnCloudCredentials getCredentialsForAccount(Context context, Account account)
 | 
			
		||||
        throws OperationCanceledException, AuthenticatorException, IOException {
 | 
			
		||||
 | 
			
		||||
        OwnCloudCredentials credentials = null;
 | 
			
		||||
        OwnCloudCredentials credentials;
 | 
			
		||||
        AccountManager am = AccountManager.get(context);
 | 
			
		||||
 | 
			
		||||
        String supportsOAuth2 = am.getUserData(account, AccountUtils.Constants.KEY_SUPPORTS_OAUTH2);
 | 
			
		||||
@ -176,10 +186,8 @@ public class AccountUtils {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return credentials;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static String buildAccountNameOld(Uri serverBaseUrl, String username) {
 | 
			
		||||
        if (serverBaseUrl.getScheme() == null) {
 | 
			
		||||
            serverBaseUrl = Uri.parse("https://" + serverBaseUrl.toString());
 | 
			
		||||
@ -207,7 +215,6 @@ public class AccountUtils {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) {
 | 
			
		||||
 | 
			
		||||
        // Account Manager
 | 
			
		||||
        AccountManager ac = AccountManager.get(context.getApplicationContext());
 | 
			
		||||
 | 
			
		||||
@ -215,13 +222,11 @@ public class AccountUtils {
 | 
			
		||||
            String cookiesString = client.getCookiesString();
 | 
			
		||||
            if (!"".equals(cookiesString)) {
 | 
			
		||||
                ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString);
 | 
			
		||||
                // Log_OC.d(TAG, "Saving Cookies: "+ cookiesString );
 | 
			
		||||
                 Log_OC.d(TAG, "Saving Cookies: "+ cookiesString );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Restore the client cookies persisted in an account stored in the system AccountManager.
 | 
			
		||||
     *
 | 
			
		||||
@ -239,23 +244,28 @@ public class AccountUtils {
 | 
			
		||||
            // Account Manager
 | 
			
		||||
            AccountManager am = AccountManager.get(context.getApplicationContext());
 | 
			
		||||
 | 
			
		||||
            Uri serverUri = (client.getBaseUri() != null) ? client.getBaseUri() : client.getWebdavUri();
 | 
			
		||||
            Uri serverUri = (client.getBaseUri() != null) ? client.getBaseUri() : client.getNewFilesWebDavUri();
 | 
			
		||||
 | 
			
		||||
            String cookiesString = am.getUserData(account, Constants.KEY_COOKIES);
 | 
			
		||||
            if (cookiesString != null) {
 | 
			
		||||
                String[] cookies = cookiesString.split(";");
 | 
			
		||||
                if (cookies.length > 0) {
 | 
			
		||||
                    for (int i = 0; i < cookies.length; i++) {
 | 
			
		||||
                        Cookie cookie = new Cookie();
 | 
			
		||||
                        int equalPos = cookies[i].indexOf('=');
 | 
			
		||||
                        cookie.setName(cookies[i].substring(0, equalPos));
 | 
			
		||||
                        cookie.setValue(cookies[i].substring(equalPos + 1));
 | 
			
		||||
                        cookie.setDomain(serverUri.getHost());    // VERY IMPORTANT
 | 
			
		||||
                        cookie.setPath(serverUri.getPath());    // VERY IMPORTANT
 | 
			
		||||
 | 
			
		||||
                        client.getState().addCookie(cookie);
 | 
			
		||||
                    }
 | 
			
		||||
                String[] rawCookies = cookiesString.split(";");
 | 
			
		||||
                List<Cookie> cookieList = new ArrayList<>(rawCookies.length);
 | 
			
		||||
                for(String rawCookie : rawCookies) {
 | 
			
		||||
                    rawCookie = rawCookie.replace(" ", "");
 | 
			
		||||
                    final int equalPos = rawCookie.indexOf('=');
 | 
			
		||||
                    if (equalPos == -1) continue;
 | 
			
		||||
                    cookieList.add(new Cookie.Builder()
 | 
			
		||||
                            .name(rawCookie.substring(0, equalPos))
 | 
			
		||||
                            .value(rawCookie.substring(equalPos + 1))
 | 
			
		||||
                            .domain(serverUri.getHost())
 | 
			
		||||
                            .path(
 | 
			
		||||
                                    serverUri.getPath().equals("")
 | 
			
		||||
                                            ? FileUtils.PATH_SEPARATOR
 | 
			
		||||
                                            : serverUri.getPath()
 | 
			
		||||
                            )
 | 
			
		||||
                            .build());
 | 
			
		||||
                }
 | 
			
		||||
                client.setCookiesForCurrentAccount(cookieList);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -279,7 +289,6 @@ public class AccountUtils {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static class Constants {
 | 
			
		||||
        /**
 | 
			
		||||
         * Version should be 3 numbers separated by dot so it can be parsed by
 | 
			
		||||
@ -320,5 +329,4 @@ public class AccountUtils {
 | 
			
		||||
        public static final String KEY_OAUTH2_REFRESH_TOKEN = "oc_oauth2_refresh_token";
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,48 +24,36 @@
 | 
			
		||||
package com.owncloud.android.lib.common.authentication;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.UsernamePasswordCredentials;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthPolicy;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthScope;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthState;
 | 
			
		||||
import org.apache.commons.httpclient.auth.BasicScheme;
 | 
			
		||||
import okhttp3.Credentials;
 | 
			
		||||
 | 
			
		||||
public class OwnCloudBasicCredentials implements OwnCloudCredentials {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = OwnCloudCredentials.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private String mUsername;
 | 
			
		||||
    private String mPassword;
 | 
			
		||||
    private boolean mAuthenticationPreemptive;
 | 
			
		||||
 | 
			
		||||
    public OwnCloudBasicCredentials(String username, String password) {
 | 
			
		||||
        mUsername = username != null ? username : "";
 | 
			
		||||
        mPassword = password != null ? password : "";
 | 
			
		||||
        mAuthenticationPreemptive = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public OwnCloudBasicCredentials(String username, String password, boolean preemptiveMode) {
 | 
			
		||||
        mUsername = username != null ? username : "";
 | 
			
		||||
        mPassword = password != null ? password : "";
 | 
			
		||||
        mAuthenticationPreemptive = preemptiveMode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void applyTo(OwnCloudClient client) {
 | 
			
		||||
        AuthPolicy.registerAuthScheme(AuthState.PREEMPTIVE_AUTH_SCHEME, BasicScheme.class);
 | 
			
		||||
        // Clear previous basic credentials
 | 
			
		||||
        HttpClient.deleteHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER);
 | 
			
		||||
        HttpClient.deleteHeaderForAllRequests(HttpConstants.COOKIE_HEADER);
 | 
			
		||||
 | 
			
		||||
        List<String> authPrefs = new ArrayList<String>(1);
 | 
			
		||||
        authPrefs.add(AuthPolicy.BASIC);
 | 
			
		||||
        client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
 | 
			
		||||
 | 
			
		||||
        client.getParams().setAuthenticationPreemptive(mAuthenticationPreemptive);
 | 
			
		||||
        client.getParams().setCredentialCharset(OwnCloudCredentialsFactory.CREDENTIAL_CHARSET);
 | 
			
		||||
        client.getState().setCredentials(
 | 
			
		||||
            AuthScope.ANY,
 | 
			
		||||
            new UsernamePasswordCredentials(mUsername, mPassword)
 | 
			
		||||
        );
 | 
			
		||||
        HttpClient.addHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER,
 | 
			
		||||
                Credentials.basic(mUsername, mPassword));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -87,5 +75,4 @@ public class OwnCloudBasicCredentials implements OwnCloudCredentials {
 | 
			
		||||
    public boolean authTokenCanBeRefreshed() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -23,16 +23,9 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.owncloud.android.lib.common.authentication;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthPolicy;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthScope;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthState;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.oauth.BearerAuthScheme;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.oauth.BearerCredentials;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
 | 
			
		||||
public class OwnCloudBearerCredentials implements OwnCloudCredentials {
 | 
			
		||||
 | 
			
		||||
@ -46,19 +39,12 @@ public class OwnCloudBearerCredentials implements OwnCloudCredentials {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void applyTo(OwnCloudClient client) {
 | 
			
		||||
        AuthPolicy.registerAuthScheme(BearerAuthScheme.AUTH_POLICY, BearerAuthScheme.class);
 | 
			
		||||
        AuthPolicy.registerAuthScheme(AuthState.PREEMPTIVE_AUTH_SCHEME, BearerAuthScheme.class);
 | 
			
		||||
        // Clear previous credentials
 | 
			
		||||
        HttpClient.deleteHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER);
 | 
			
		||||
        HttpClient.deleteHeaderForAllRequests(HttpConstants.COOKIE_HEADER);
 | 
			
		||||
 | 
			
		||||
        List<String> authPrefs = new ArrayList<>(1);
 | 
			
		||||
        authPrefs.add(BearerAuthScheme.AUTH_POLICY);
 | 
			
		||||
        client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
 | 
			
		||||
 | 
			
		||||
        client.getParams().setAuthenticationPreemptive(true);    // true enforces BASIC AUTH ; library is stupid
 | 
			
		||||
        client.getParams().setCredentialCharset(OwnCloudCredentialsFactory.CREDENTIAL_CHARSET);
 | 
			
		||||
        client.getState().setCredentials(
 | 
			
		||||
            AuthScope.ANY,
 | 
			
		||||
            new BearerCredentials(mAccessToken)
 | 
			
		||||
        );
 | 
			
		||||
        HttpClient.addHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER,
 | 
			
		||||
                HttpConstants.BEARER_AUTHORIZATION_KEY + mAccessToken);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -81,5 +67,4 @@ public class OwnCloudBearerCredentials implements OwnCloudCredentials {
 | 
			
		||||
    public boolean authTokenCanBeRefreshed() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -25,6 +25,8 @@
 | 
			
		||||
package com.owncloud.android.lib.common.authentication;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
 | 
			
		||||
public class OwnCloudCredentialsFactory {
 | 
			
		||||
 | 
			
		||||
@ -64,8 +66,9 @@ public class OwnCloudCredentialsFactory {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void applyTo(OwnCloudClient client) {
 | 
			
		||||
            client.getState().clearCredentials();
 | 
			
		||||
            client.getState().clearCookies();
 | 
			
		||||
            // Clear previous basic credentials
 | 
			
		||||
            HttpClient.deleteHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER);
 | 
			
		||||
            HttpClient.deleteHeaderForAllRequests(HttpConstants.COOKIE_HEADER);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
@ -89,5 +92,4 @@ public class OwnCloudCredentialsFactory {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -23,12 +23,9 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.owncloud.android.lib.common.authentication;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Cookie;
 | 
			
		||||
import org.apache.commons.httpclient.cookie.CookiePolicy;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
 | 
			
		||||
public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
 | 
			
		||||
 | 
			
		||||
@ -42,28 +39,12 @@ public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void applyTo(OwnCloudClient client) {
 | 
			
		||||
        client.getParams().setAuthenticationPreemptive(false);
 | 
			
		||||
        client.getParams().setCredentialCharset(OwnCloudCredentialsFactory.CREDENTIAL_CHARSET);
 | 
			
		||||
        client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
 | 
			
		||||
        // Clear previous credentials
 | 
			
		||||
        HttpClient.deleteHeaderForAllRequests(HttpConstants.AUTHORIZATION_HEADER);
 | 
			
		||||
        HttpClient.deleteHeaderForAllRequests(HttpConstants.COOKIE_HEADER);
 | 
			
		||||
 | 
			
		||||
        HttpClient.addHeaderForAllRequests(HttpConstants.COOKIE_HEADER, mSessionCookie);
 | 
			
		||||
        client.setFollowRedirects(false);
 | 
			
		||||
 | 
			
		||||
        Uri serverUri = client.getBaseUri();
 | 
			
		||||
 | 
			
		||||
        String[] cookies = mSessionCookie.split(";");
 | 
			
		||||
        if (cookies.length > 0) {
 | 
			
		||||
            Cookie cookie = null;
 | 
			
		||||
            for (int i = 0; i < cookies.length; i++) {
 | 
			
		||||
                int equalPos = cookies[i].indexOf('=');
 | 
			
		||||
                if (equalPos >= 0) {
 | 
			
		||||
                    cookie = new Cookie();
 | 
			
		||||
                    cookie.setName(cookies[i].substring(0, equalPos));
 | 
			
		||||
                    cookie.setValue(cookies[i].substring(equalPos + 1));
 | 
			
		||||
                    cookie.setDomain(serverUri.getHost());    // VERY IMPORTANT
 | 
			
		||||
                    cookie.setPath(serverUri.getPath());    // VERY IMPORTANT
 | 
			
		||||
                    client.getState().addCookie(cookie);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@ -86,5 +67,4 @@ public class OwnCloudSamlSsoCredentials implements OwnCloudCredentials {
 | 
			
		||||
    public boolean authTokenCanBeRefreshed() {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,262 +0,0 @@
 | 
			
		||||
/* 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.authentication.oauth;
 | 
			
		||||
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Credentials;
 | 
			
		||||
import org.apache.commons.httpclient.HttpMethod;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthChallengeParser;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthScheme;
 | 
			
		||||
import org.apache.commons.httpclient.auth.AuthenticationException;
 | 
			
		||||
import org.apache.commons.httpclient.auth.InvalidCredentialsException;
 | 
			
		||||
import org.apache.commons.httpclient.auth.MalformedChallengeException;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Bearer authentication scheme as defined in RFC 6750.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class BearerAuthScheme implements AuthScheme /*extends RFC2617Scheme*/ {
 | 
			
		||||
    
 | 
			
		||||
    private static final String TAG = BearerAuthScheme.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    public static final String AUTH_POLICY = "Bearer";
 | 
			
		||||
    
 | 
			
		||||
    /** Whether the bearer authentication process is complete */
 | 
			
		||||
    private boolean mComplete;
 | 
			
		||||
    
 | 
			
		||||
    /** Authentication parameter map */
 | 
			
		||||
    @SuppressWarnings("rawtypes")
 | 
			
		||||
	private Map mParams = null;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Default constructor for the bearer authentication scheme.
 | 
			
		||||
     */
 | 
			
		||||
    public BearerAuthScheme() {
 | 
			
		||||
        mComplete = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for the basic authentication scheme.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param   challenge                       Authentication challenge
 | 
			
		||||
     * 
 | 
			
		||||
     * @throws  MalformedChallengeException     Thrown if the authentication challenge is malformed
 | 
			
		||||
     */
 | 
			
		||||
    public BearerAuthScheme(final String challenge) throws MalformedChallengeException {
 | 
			
		||||
        processChallenge(challenge);
 | 
			
		||||
        mComplete = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns textual designation of the bearer authentication scheme.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return "Bearer"
 | 
			
		||||
     */
 | 
			
		||||
    public String getSchemeName() {
 | 
			
		||||
        return "bearer";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Processes the Bearer challenge.
 | 
			
		||||
     *  
 | 
			
		||||
     * @param   challenge                   The challenge string
 | 
			
		||||
     * 
 | 
			
		||||
     * @throws MalformedChallengeException  Thrown if the authentication challenge is malformed
 | 
			
		||||
     */
 | 
			
		||||
    public void processChallenge(String challenge) throws MalformedChallengeException {
 | 
			
		||||
        String s = AuthChallengeParser.extractScheme(challenge);
 | 
			
		||||
        if (!s.equalsIgnoreCase(getSchemeName())) {
 | 
			
		||||
            throw new MalformedChallengeException(
 | 
			
		||||
              "Invalid " + getSchemeName() + " challenge: " + challenge); 
 | 
			
		||||
        }
 | 
			
		||||
        mParams = AuthChallengeParser.extractParams(challenge);
 | 
			
		||||
        mComplete = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tests if the Bearer authentication process has been completed.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return 'true' if Bearer authorization has been processed, 'false' otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isComplete() {
 | 
			
		||||
        return this.mComplete;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produces bearer authorization string for the given set of 
 | 
			
		||||
     * {@link Credentials}.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param   credentials                     The set of credentials to be used for authentication
 | 
			
		||||
     * @param   method                          Method name is ignored by the bearer authentication scheme
 | 
			
		||||
     * @param   uri                             URI is ignored by the bearer authentication scheme
 | 
			
		||||
     * @throws  InvalidCredentialsException     If authentication credentials are not valid or not applicable 
 | 
			
		||||
     *                                          for this authentication scheme
 | 
			
		||||
     * @throws  AuthenticationException         If authorization string cannot be generated due to an authentication failure
 | 
			
		||||
     * @return  A bearer authorization string
 | 
			
		||||
     */
 | 
			
		||||
    public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException {
 | 
			
		||||
        BearerCredentials bearer;
 | 
			
		||||
        try {
 | 
			
		||||
            bearer = (BearerCredentials) credentials;
 | 
			
		||||
        } catch (ClassCastException e) {
 | 
			
		||||
            throw new InvalidCredentialsException(
 | 
			
		||||
             "Credentials cannot be used for bearer authentication: " 
 | 
			
		||||
              + credentials.getClass().getName());
 | 
			
		||||
        }
 | 
			
		||||
        return BearerAuthScheme.authenticate(bearer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns 'false'. Bearer authentication scheme is request based.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return 'false'.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isConnectionBased() {
 | 
			
		||||
        return false;    
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Produces bearer authorization string for the given set of {@link Credentials}.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param   credentials                     The set of credentials to be used for authentication
 | 
			
		||||
     * @param   method                          The method being authenticated
 | 
			
		||||
     * @throws  InvalidCredentialsException     If authentication credentials are not valid or not applicable for this authentication 
 | 
			
		||||
     *                                          scheme.
 | 
			
		||||
     * @throws AuthenticationException         If authorization string cannot be generated due to an authentication failure.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return a basic authorization string
 | 
			
		||||
     */
 | 
			
		||||
    public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
 | 
			
		||||
        if (method == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Method may not be null");
 | 
			
		||||
        }
 | 
			
		||||
        BearerCredentials bearer = null;
 | 
			
		||||
        try {
 | 
			
		||||
            bearer = (BearerCredentials) credentials;
 | 
			
		||||
        } catch (ClassCastException e) {
 | 
			
		||||
            throw new InvalidCredentialsException(
 | 
			
		||||
                    "Credentials cannot be used for bearer authentication: " 
 | 
			
		||||
                    + credentials.getClass().getName());
 | 
			
		||||
        }
 | 
			
		||||
        return BearerAuthScheme.authenticate(
 | 
			
		||||
            bearer, 
 | 
			
		||||
            method.getParams().getCredentialCharset());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a bearer Authorization header value for the given
 | 
			
		||||
     * {@link BearerCredentials}.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param   credentials     The credentials to encode.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return                  A bearer authorization string
 | 
			
		||||
     */
 | 
			
		||||
    public static String authenticate(BearerCredentials credentials) {
 | 
			
		||||
        return authenticate(credentials, "ISO-8859-1");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a bearer Authorization header value for the given 
 | 
			
		||||
     * {@link BearerCredentials} and charset.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param   credentials         The credentials to encode.
 | 
			
		||||
     * @param   charset             The charset to use for encoding the credentials
 | 
			
		||||
     * 
 | 
			
		||||
     * @return                      A bearer authorization string
 | 
			
		||||
     * 
 | 
			
		||||
     * @since 3.0
 | 
			
		||||
     */
 | 
			
		||||
    public static String authenticate(BearerCredentials credentials, String charset) {
 | 
			
		||||
 | 
			
		||||
        if (credentials == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Credentials may not be null"); 
 | 
			
		||||
        }
 | 
			
		||||
        if (charset == null || charset.length() == 0) {
 | 
			
		||||
            throw new IllegalArgumentException("charset may not be null or empty");
 | 
			
		||||
        }
 | 
			
		||||
        StringBuffer buffer = new StringBuffer();
 | 
			
		||||
        buffer.append(credentials.getAccessToken());
 | 
			
		||||
 | 
			
		||||
        return "Bearer " + buffer.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a String identifying the authentication challenge.  This is
 | 
			
		||||
     * used, in combination with the host and port to determine if
 | 
			
		||||
     * authorization has already been attempted or not.  Schemes which
 | 
			
		||||
     * require multiple requests to complete the authentication should
 | 
			
		||||
     * return a different value for each stage in the request.
 | 
			
		||||
     * 
 | 
			
		||||
     * Additionally, the ID should take into account any changes to the
 | 
			
		||||
     * authentication challenge and return a different value when appropriate.
 | 
			
		||||
     * For example when the realm changes in basic authentication it should be
 | 
			
		||||
     * considered a different authentication attempt and a different value should
 | 
			
		||||
     * be returned.
 | 
			
		||||
     * 
 | 
			
		||||
     * This method simply returns the realm for the challenge.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return String       a String identifying the authentication challenge.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getID() {
 | 
			
		||||
        return getRealm();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns authentication parameter with the given name, if available.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param   name    The name of the parameter to be returned
 | 
			
		||||
     * 
 | 
			
		||||
     * @return          The parameter with the given name
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getParameter(String name) {
 | 
			
		||||
        if (name == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Parameter name may not be null"); 
 | 
			
		||||
        }
 | 
			
		||||
        if (mParams == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return (String) mParams.get(name.toLowerCase());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns authentication realm. The realm may not be null.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return  The authentication realm
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getRealm() {
 | 
			
		||||
        return getParameter("realm");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,16 +24,14 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common.authentication.oauth;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Credentials;
 | 
			
		||||
import org.apache.commons.httpclient.util.LangUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Bearer token {@link Credentials}
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 */
 | 
			
		||||
public class BearerCredentials implements Credentials {
 | 
			
		||||
public class BearerCredentials {
 | 
			
		||||
 | 
			
		||||
    public static final int HASH_SEED = 17;
 | 
			
		||||
    public static final int HASH_OFFSET = 37;
 | 
			
		||||
    
 | 
			
		||||
    private String mAccessToken;
 | 
			
		||||
    
 | 
			
		||||
@ -76,9 +74,7 @@ public class BearerCredentials implements Credentials {
 | 
			
		||||
     * @return The hash code of the access token
 | 
			
		||||
     */
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        int hash = LangUtils.HASH_SEED;
 | 
			
		||||
        hash = LangUtils.hashCode(hash, mAccessToken);
 | 
			
		||||
        return hash;
 | 
			
		||||
       return HASH_SEED * HASH_OFFSET + mAccessToken.hashCode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -93,12 +89,10 @@ public class BearerCredentials implements Credentials {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (this.getClass().equals(o.getClass())) {
 | 
			
		||||
            BearerCredentials that = (BearerCredentials) o;
 | 
			
		||||
            if (LangUtils.equals(mAccessToken, that.mAccessToken)) {
 | 
			
		||||
            if (mAccessToken.equals(that.mAccessToken)) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2017 ownCloud GmbH.
 | 
			
		||||
 *   @author Christian Schabesberger
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -31,21 +32,21 @@ import android.net.Uri;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
 | 
			
		||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 | 
			
		||||
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 org.apache.commons.httpclient.NameValuePair;
 | 
			
		||||
import org.apache.commons.httpclient.methods.PostMethod;
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import okhttp3.MultipartBody;
 | 
			
		||||
import okhttp3.RequestBody;
 | 
			
		||||
 | 
			
		||||
public class OAuth2GetAccessTokenOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
public class OAuth2GetAccessTokenOperation extends RemoteOperation<Map<String, String>> {
 | 
			
		||||
    
 | 
			
		||||
    private String mGrantType;
 | 
			
		||||
    private String mCode;
 | 
			
		||||
@ -82,29 +83,33 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        PostMethod postMethod = null;
 | 
			
		||||
        RemoteOperationResult<Map<String, String>> result = null;
 | 
			
		||||
        
 | 
			
		||||
        try {
 | 
			
		||||
            NameValuePair[] nameValuePairs = new NameValuePair[4];
 | 
			
		||||
            nameValuePairs[0] = new NameValuePair(OAuth2Constants.KEY_GRANT_TYPE, mGrantType);
 | 
			
		||||
            nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CODE, mCode);
 | 
			
		||||
            nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REDIRECT_URI, mRedirectUri);
 | 
			
		||||
            nameValuePairs[3] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
 | 
			
		||||
 | 
			
		||||
            final RequestBody requestBody = new MultipartBody.Builder()
 | 
			
		||||
                    .setType(MultipartBody.FORM)
 | 
			
		||||
                    .addFormDataPart(OAuth2Constants.KEY_GRANT_TYPE, mGrantType)
 | 
			
		||||
                    .addFormDataPart(OAuth2Constants.KEY_CODE, mCode)
 | 
			
		||||
                    .addFormDataPart(OAuth2Constants.KEY_REDIRECT_URI, mRedirectUri)
 | 
			
		||||
                    .addFormDataPart(OAuth2Constants.KEY_CLIENT_ID, mClientId)
 | 
			
		||||
                    .build();
 | 
			
		||||
 | 
			
		||||
            Uri.Builder uriBuilder = client.getBaseUri().buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(mAccessTokenEndpointPath);
 | 
			
		||||
 | 
			
		||||
            postMethod = new PostMethod(uriBuilder.build().toString());
 | 
			
		||||
            postMethod.setRequestBody(nameValuePairs);
 | 
			
		||||
            final PostMethod postMethod = new PostMethod(new URL(
 | 
			
		||||
                    client.getBaseUri().buildUpon()
 | 
			
		||||
                            .appendEncodedPath(mAccessTokenEndpointPath)
 | 
			
		||||
                            .build()
 | 
			
		||||
                            .toString()));
 | 
			
		||||
 | 
			
		||||
            OwnCloudCredentials oauthCredentials = new OwnCloudBasicCredentials(
 | 
			
		||||
                mClientId,
 | 
			
		||||
                mClientSecret
 | 
			
		||||
            );
 | 
			
		||||
            postMethod.setRequestBody(requestBody);
 | 
			
		||||
 | 
			
		||||
            OwnCloudCredentials oauthCredentials =
 | 
			
		||||
                    new OwnCloudBasicCredentials(mClientId, mClientSecret);
 | 
			
		||||
            OwnCloudCredentials oldCredentials = switchClientCredentials(oauthCredentials);
 | 
			
		||||
 | 
			
		||||
            client.executeMethod(postMethod);
 | 
			
		||||
            client.executeHttpMethod(postMethod);
 | 
			
		||||
            switchClientCredentials(oldCredentials);
 | 
			
		||||
 | 
			
		||||
            String response = postMethod.getResponseBodyAsString();
 | 
			
		||||
@ -114,28 +119,22 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation {
 | 
			
		||||
                    mResponseParser.parseAccessTokenResult(tokenJson);
 | 
			
		||||
                if (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null ||
 | 
			
		||||
                        accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) {
 | 
			
		||||
                    result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
 | 
			
		||||
                    result = new RemoteOperationResult<>(ResultCode.OAUTH2_ERROR);
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = new RemoteOperationResult(true, postMethod);
 | 
			
		||||
                    ArrayList<Object> data = new ArrayList<>();
 | 
			
		||||
                    data.add(accessTokenResult);
 | 
			
		||||
                    result.setData(data);
 | 
			
		||||
                    result = new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
                    result.setData(accessTokenResult);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, postMethod);
 | 
			
		||||
                result = new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
                client.exhaustResponse(postMethod.getResponseBodyAsStream());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (postMethod != null)
 | 
			
		||||
                postMethod.releaseConnection();    // let the connection available for other methods
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -144,5 +143,4 @@ public class OAuth2GetAccessTokenOperation extends RemoteOperation {
 | 
			
		||||
        getClient().setCredentials(newCredentials);
 | 
			
		||||
        return previousCredentials;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -2,8 +2,9 @@
 | 
			
		||||
 *   ownCloud Android client application
 | 
			
		||||
 *
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   @author Christian Schabesberger
 | 
			
		||||
 *
 | 
			
		||||
 *   Copyright (C) 2017 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 ownCloud GmbH.
 | 
			
		||||
 *
 | 
			
		||||
 *   This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 *   it under the terms of the GNU General Public License version 2,
 | 
			
		||||
@ -26,19 +27,22 @@ import android.net.Uri;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudBasicCredentials;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 | 
			
		||||
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.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.NameValuePair;
 | 
			
		||||
import org.apache.commons.httpclient.methods.PostMethod;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
public class OAuth2RefreshAccessTokenOperation extends RemoteOperation {
 | 
			
		||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.PostMethod;
 | 
			
		||||
 | 
			
		||||
import okhttp3.MultipartBody;
 | 
			
		||||
import okhttp3.RequestBody;
 | 
			
		||||
 | 
			
		||||
public class OAuth2RefreshAccessTokenOperation extends RemoteOperation<Map<String, String>> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = OAuth2RefreshAccessTokenOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -71,70 +75,55 @@ public class OAuth2RefreshAccessTokenOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        PostMethod postMethod = null;
 | 
			
		||||
    protected RemoteOperationResult<Map<String, String>> run(OwnCloudClient client) {
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            NameValuePair[] nameValuePairs = new NameValuePair[3];
 | 
			
		||||
            nameValuePairs[0] = new NameValuePair(
 | 
			
		||||
                OAuth2Constants.KEY_GRANT_TYPE,
 | 
			
		||||
                OAuth2GrantType.REFRESH_TOKEN.getValue()    // always for this operation
 | 
			
		||||
            );
 | 
			
		||||
            nameValuePairs[1] = new NameValuePair(OAuth2Constants.KEY_CLIENT_ID, mClientId);
 | 
			
		||||
            nameValuePairs[2] = new NameValuePair(OAuth2Constants.KEY_REFRESH_TOKEN, mRefreshToken);
 | 
			
		||||
            final RequestBody requestBody = new MultipartBody.Builder()
 | 
			
		||||
                    .setType(MultipartBody.FORM)
 | 
			
		||||
                    .addFormDataPart(OAuth2Constants.KEY_GRANT_TYPE,
 | 
			
		||||
                            OAuth2GrantType.REFRESH_TOKEN.getValue())
 | 
			
		||||
                    .addFormDataPart(OAuth2Constants.KEY_CLIENT_ID, mClientId)
 | 
			
		||||
                    .addFormDataPart(OAuth2Constants.KEY_REFRESH_TOKEN, mRefreshToken)
 | 
			
		||||
                    .build();
 | 
			
		||||
 | 
			
		||||
            Uri.Builder uriBuilder = client.getBaseUri().buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(mAccessTokenEndpointPath);
 | 
			
		||||
 | 
			
		||||
            postMethod = new PostMethod(uriBuilder.build().toString());
 | 
			
		||||
            postMethod.setRequestBody(nameValuePairs);
 | 
			
		||||
            final PostMethod postMethod = new PostMethod(new URL(
 | 
			
		||||
                    client.getBaseUri().buildUpon()
 | 
			
		||||
                            .appendEncodedPath(mAccessTokenEndpointPath)
 | 
			
		||||
                            .build()
 | 
			
		||||
                            .toString()));
 | 
			
		||||
            postMethod.setRequestBody(requestBody);
 | 
			
		||||
 | 
			
		||||
            OwnCloudCredentials oauthCredentials = new OwnCloudBasicCredentials(
 | 
			
		||||
                    mClientId,
 | 
			
		||||
                    mClientSecret
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            OwnCloudCredentials oldCredentials = switchClientCredentials(oauthCredentials);
 | 
			
		||||
 | 
			
		||||
            client.executeMethod(postMethod);
 | 
			
		||||
            final OwnCloudCredentials oauthCredentials = new OwnCloudBasicCredentials(mClientId, mClientSecret);
 | 
			
		||||
 | 
			
		||||
            final OwnCloudCredentials oldCredentials = switchClientCredentials(oauthCredentials);
 | 
			
		||||
            client.executeHttpMethod(postMethod);
 | 
			
		||||
            switchClientCredentials(oldCredentials);
 | 
			
		||||
 | 
			
		||||
            String response = postMethod.getResponseBodyAsString();
 | 
			
		||||
            Log_OC.d(TAG, "OAUTH2: raw response from POST TOKEN: " + response);
 | 
			
		||||
            final String responseData = postMethod.getResponseBodyAsString();
 | 
			
		||||
            Log_OC.d(TAG, "OAUTH2: raw response from POST TOKEN: " + responseData);
 | 
			
		||||
 | 
			
		||||
            if (response != null && response.length() > 0) {
 | 
			
		||||
                JSONObject tokenJson = new JSONObject(response);
 | 
			
		||||
                Map<String, String> accessTokenResult =
 | 
			
		||||
                    mResponseParser.parseAccessTokenResult(tokenJson);
 | 
			
		||||
                if (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null ||
 | 
			
		||||
                        accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null) {
 | 
			
		||||
                    result = new RemoteOperationResult(ResultCode.OAUTH2_ERROR);
 | 
			
		||||
            if (responseData != null && responseData.length() > 0) {
 | 
			
		||||
                final JSONObject tokenJson = new JSONObject(responseData);
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = new RemoteOperationResult(true, postMethod);
 | 
			
		||||
                    ArrayList<Object> data = new ArrayList<>();
 | 
			
		||||
                    data.add(accessTokenResult);
 | 
			
		||||
                    result.setData(data);
 | 
			
		||||
                }
 | 
			
		||||
                final Map<String, String> accessTokenResult =
 | 
			
		||||
                        mResponseParser.parseAccessTokenResult(tokenJson);
 | 
			
		||||
 | 
			
		||||
                final RemoteOperationResult<Map<String, String>> result = new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
                result.setData(accessTokenResult);
 | 
			
		||||
                return (accessTokenResult.get(OAuth2Constants.KEY_ERROR) != null ||
 | 
			
		||||
                        accessTokenResult.get(OAuth2Constants.KEY_ACCESS_TOKEN) == null)
 | 
			
		||||
                        ? new RemoteOperationResult<>(ResultCode.OAUTH2_ERROR)
 | 
			
		||||
                        : result;
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, postMethod);
 | 
			
		||||
                client.exhaustResponse(postMethod.getResponseBodyAsStream());
 | 
			
		||||
                return new RemoteOperationResult<>(postMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (postMethod != null) {
 | 
			
		||||
                postMethod.releaseConnection();    // let the connection available for other methods
 | 
			
		||||
            }
 | 
			
		||||
            return new RemoteOperationResult<>(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private OwnCloudCredentials switchClientCredentials(OwnCloudCredentials newCredentials) {
 | 
			
		||||
@ -142,5 +131,4 @@ public class OAuth2RefreshAccessTokenOperation extends RemoteOperation {
 | 
			
		||||
        getClient().setCredentials(newCredentials);
 | 
			
		||||
        return previousCredentials;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										172
									
								
								src/com/owncloud/android/lib/common/http/HttpClient.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								src/com/owncloud/android/lib/common/http/HttpClient.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,172 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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.OwnCloudClientManagerFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.http.interceptors.HttpInterceptor;
 | 
			
		||||
import com.owncloud.android.lib.common.http.interceptors.RequestHeaderInterceptor;
 | 
			
		||||
import com.owncloud.android.lib.common.network.AdvancedX509TrustManager;
 | 
			
		||||
import com.owncloud.android.lib.common.network.NetworkUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import javax.net.ssl.SSLContext;
 | 
			
		||||
import javax.net.ssl.TrustManager;
 | 
			
		||||
import javax.net.ssl.X509TrustManager;
 | 
			
		||||
 | 
			
		||||
import okhttp3.Cookie;
 | 
			
		||||
import okhttp3.CookieJar;
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import okhttp3.Protocol;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Client used to perform network operations
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class HttpClient {
 | 
			
		||||
    private static final String TAG = HttpClient.class.toString();
 | 
			
		||||
 | 
			
		||||
    private static OkHttpClient sOkHttpClient;
 | 
			
		||||
    private static HttpInterceptor sOkHttpInterceptor;
 | 
			
		||||
    private static Context sContext;
 | 
			
		||||
    private static HashMap<String, List<Cookie>> sCookieStore = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    public static void setContext(Context context) {
 | 
			
		||||
        sContext = context;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Context getContext() {
 | 
			
		||||
        return sContext;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static OkHttpClient getOkHttpClient() {
 | 
			
		||||
        if (sOkHttpClient == null) {
 | 
			
		||||
            try {
 | 
			
		||||
                final X509TrustManager trustManager = new AdvancedX509TrustManager(
 | 
			
		||||
                        NetworkUtils.getKnownServersStore(sContext));
 | 
			
		||||
                final SSLContext sslContext = SSLContext.getInstance("TLS");
 | 
			
		||||
                sslContext.init(null, new TrustManager[] {trustManager}, null);
 | 
			
		||||
 | 
			
		||||
                // Automatic cookie handling, NOT PERSISTENT
 | 
			
		||||
                CookieJar cookieJar = new CookieJar() {
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
 | 
			
		||||
                        // Avoid duplicated cookies
 | 
			
		||||
                        Set<Cookie> nonDuplicatedCookiesSet = new HashSet<>();
 | 
			
		||||
                        nonDuplicatedCookiesSet.addAll(cookies);
 | 
			
		||||
                        List<Cookie> nonDuplicatedCookiesList = new ArrayList<>();
 | 
			
		||||
                        nonDuplicatedCookiesList.addAll(nonDuplicatedCookiesSet);
 | 
			
		||||
 | 
			
		||||
                        sCookieStore.put(url.host(), nonDuplicatedCookiesList);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    @Override
 | 
			
		||||
                    public List<Cookie> loadForRequest(HttpUrl url) {
 | 
			
		||||
                        List<Cookie> cookies = sCookieStore.get(url.host());
 | 
			
		||||
                        return cookies != null ? cookies : new ArrayList<>();
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
 | 
			
		||||
                        .addInterceptor(getOkHttpInterceptor())
 | 
			
		||||
                        .protocols(Arrays.asList(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(sslContext.getSocketFactory(), trustManager)
 | 
			
		||||
                        .hostnameVerifier((asdf, usdf) -> true)
 | 
			
		||||
                        .cookieJar(cookieJar);
 | 
			
		||||
                        // TODO: Not verifying the hostname against certificate. ask owncloud security human if this is ok.
 | 
			
		||||
                        //.hostnameVerifier(new BrowserCompatHostnameVerifier());
 | 
			
		||||
                sOkHttpClient = clientBuilder.build();
 | 
			
		||||
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                Log_OC.e(TAG, "Could not setup SSL system.", e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return sOkHttpClient;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static HttpInterceptor getOkHttpInterceptor() {
 | 
			
		||||
        if (sOkHttpInterceptor == null) {
 | 
			
		||||
            sOkHttpInterceptor = new HttpInterceptor();
 | 
			
		||||
            addHeaderForAllRequests(HttpConstants.USER_AGENT_HEADER, OwnCloudClientManagerFactory.getUserAgent());
 | 
			
		||||
            addHeaderForAllRequests(HttpConstants.PARAM_SINGLE_COOKIE_HEADER, "true");
 | 
			
		||||
            addHeaderForAllRequests(HttpConstants.ACCEPT_ENCODING_HEADER, HttpConstants.ACCEPT_ENCODING_IDENTITY);
 | 
			
		||||
        }
 | 
			
		||||
        return sOkHttpInterceptor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void disableAutomaticCookiesHandling() {
 | 
			
		||||
        OkHttpClient.Builder clientBuilder = getOkHttpClient().newBuilder();
 | 
			
		||||
        clientBuilder.cookieJar(new CookieJar() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
 | 
			
		||||
                // DO NOTHING
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public List<Cookie> loadForRequest(HttpUrl url) {
 | 
			
		||||
                return new ArrayList<>();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        sOkHttpClient = clientBuilder.build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Add header that will be included for all the requests from now on
 | 
			
		||||
     * @param headerName
 | 
			
		||||
     * @param headerValue
 | 
			
		||||
     */
 | 
			
		||||
    public static void addHeaderForAllRequests(String headerName, String headerValue) {
 | 
			
		||||
        getOkHttpInterceptor()
 | 
			
		||||
                .addRequestInterceptor(
 | 
			
		||||
                        new RequestHeaderInterceptor(headerName, headerValue)
 | 
			
		||||
                );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void deleteHeaderForAllRequests(String headerName) {
 | 
			
		||||
        getOkHttpInterceptor().deleteRequestHeaderInterceptor(headerName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Cookie> getCookiesFromUrl(HttpUrl httpUrl) {
 | 
			
		||||
        return sCookieStore.get(httpUrl.host());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void clearCookies() {
 | 
			
		||||
        sCookieStore.clear();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										189
									
								
								src/com/owncloud/android/lib/common/http/HttpConstants.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								src/com/owncloud/android/lib/common/http/HttpConstants.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,189 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 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 PARAM_SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header";
 | 
			
		||||
    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";
 | 
			
		||||
 | 
			
		||||
    /***********************************************************************************************************
 | 
			
		||||
     ************************************************ 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;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,109 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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.interceptors;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
import okhttp3.Interceptor;
 | 
			
		||||
import okhttp3.Request;
 | 
			
		||||
import okhttp3.Response;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Http interceptor to use multiple interceptors in the same {@link okhttp3.OkHttpClient} instance
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class HttpInterceptor implements Interceptor {
 | 
			
		||||
 | 
			
		||||
    private final ArrayList<RequestInterceptor> mRequestInterceptors = new ArrayList<>();
 | 
			
		||||
    private final ArrayList<ResponseInterceptor> mResponseInterceptors = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Response intercept(Chain chain) throws IOException {
 | 
			
		||||
        Request request = chain.request();
 | 
			
		||||
 | 
			
		||||
        for (RequestInterceptor interceptor : mRequestInterceptors) {
 | 
			
		||||
            request = interceptor.intercept(request);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Response response = chain.proceed(request);
 | 
			
		||||
 | 
			
		||||
        for (ResponseInterceptor interceptor : mResponseInterceptors) {
 | 
			
		||||
            response = interceptor.intercept(response);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface RequestInterceptor {
 | 
			
		||||
        Request intercept(Request request) throws IOException;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface ResponseInterceptor {
 | 
			
		||||
        Response intercept(Response response) throws IOException;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public HttpInterceptor addRequestInterceptor(RequestInterceptor requestInterceptor) {
 | 
			
		||||
        mRequestInterceptors.add(requestInterceptor);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public HttpInterceptor addResponseInterceptor (ResponseInterceptor responseInterceptor) {
 | 
			
		||||
        mResponseInterceptors.add(responseInterceptor);
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<RequestInterceptor> getRequestInterceptors() {
 | 
			
		||||
        return mRequestInterceptors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private ArrayList<RequestHeaderInterceptor> getRequestHeaderInterceptors() {
 | 
			
		||||
        ArrayList<RequestHeaderInterceptor> requestHeaderInterceptors = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        for (RequestInterceptor requestInterceptor : mRequestInterceptors) {
 | 
			
		||||
            if (requestInterceptor instanceof RequestHeaderInterceptor) {
 | 
			
		||||
                requestHeaderInterceptors.add((RequestHeaderInterceptor) requestInterceptor);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return requestHeaderInterceptors;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void deleteRequestHeaderInterceptor(String headerName) {
 | 
			
		||||
        Iterator<RequestInterceptor> requestInterceptorIterator = mRequestInterceptors.iterator();
 | 
			
		||||
        while (requestInterceptorIterator.hasNext()) {
 | 
			
		||||
            RequestInterceptor currentRequestInterceptor = requestInterceptorIterator.next();
 | 
			
		||||
            if (currentRequestInterceptor instanceof RequestHeaderInterceptor &&
 | 
			
		||||
                    ((RequestHeaderInterceptor) currentRequestInterceptor).getHeaderName().equals(headerName)) {
 | 
			
		||||
                requestInterceptorIterator.remove();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<ResponseInterceptor> getResponseInterceptors() {
 | 
			
		||||
        return mResponseInterceptors;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,54 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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.interceptors;
 | 
			
		||||
 | 
			
		||||
import okhttp3.Request;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Intercept requests to update their headers
 | 
			
		||||
 */
 | 
			
		||||
public class RequestHeaderInterceptor implements HttpInterceptor.RequestInterceptor {
 | 
			
		||||
 | 
			
		||||
    private String mHeaderName;
 | 
			
		||||
    private String mHeaderValue;
 | 
			
		||||
 | 
			
		||||
    public RequestHeaderInterceptor(String headerName, String headerValue) {
 | 
			
		||||
        this.mHeaderName = headerName;
 | 
			
		||||
        this.mHeaderValue = headerValue;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Request intercept(Request request) {
 | 
			
		||||
        return request.newBuilder().addHeader(mHeaderName, mHeaderValue).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getHeaderName() {
 | 
			
		||||
        return mHeaderName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getHeaderValue() {
 | 
			
		||||
        return mHeaderValue;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,192 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import okhttp3.Call;
 | 
			
		||||
import okhttp3.Headers;
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
import okhttp3.Request;
 | 
			
		||||
import okhttp3.RequestBody;
 | 
			
		||||
import okhttp3.Response;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wrapper to perform http calls transparently by using:
 | 
			
		||||
 * - OkHttp for non webdav methods
 | 
			
		||||
 * - Dav4Android for webdav methods
 | 
			
		||||
 *
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public abstract class HttpBaseMethod {
 | 
			
		||||
    protected OkHttpClient mOkHttpClient;
 | 
			
		||||
    protected Request mRequest;
 | 
			
		||||
    protected RequestBody mRequestBody;
 | 
			
		||||
    protected Response mResponse;
 | 
			
		||||
    protected String mResponseBodyString;
 | 
			
		||||
    protected Call mCall;
 | 
			
		||||
 | 
			
		||||
    protected HttpBaseMethod(URL url) {
 | 
			
		||||
        mOkHttpClient = HttpClient.getOkHttpClient();
 | 
			
		||||
        mRequest = new Request.Builder()
 | 
			
		||||
                .url(HttpUrl.parse(url.toString()))
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int execute() throws Exception {
 | 
			
		||||
        return onExecute();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void abort() {
 | 
			
		||||
        mCall.cancel();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isAborted() {
 | 
			
		||||
        return mCall.isCanceled();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
    //         For override
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
 | 
			
		||||
    protected abstract int onExecute() throws Exception;
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
    //         Getter
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Request
 | 
			
		||||
 | 
			
		||||
    public Headers getRequestHeaders() {
 | 
			
		||||
        return mRequest.headers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getRequestHeader(String name) {
 | 
			
		||||
        return mRequest.header(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Response
 | 
			
		||||
 | 
			
		||||
    public int getStatusCode() {
 | 
			
		||||
        return mResponse.code();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getStatusMessage() {
 | 
			
		||||
        return mResponse.message();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getResponseBodyAsString() throws IOException {
 | 
			
		||||
        if (mResponseBodyString == null && mResponse.body() != null) {
 | 
			
		||||
            mResponseBodyString = mResponse.body().string();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mResponseBodyString;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public InputStream getResponseBodyAsStream() {
 | 
			
		||||
        if (mResponse.body() != null) {
 | 
			
		||||
            return mResponse.body().byteStream();
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Headers getResponseHeaders() {
 | 
			
		||||
        return mResponse.headers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getResponseHeader(String headerName) {
 | 
			
		||||
        return mResponse.header(headerName);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean getRetryOnConnectionFailure() {
 | 
			
		||||
        return mOkHttpClient.retryOnConnectionFailure();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
    //         Setter
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Connection parameters
 | 
			
		||||
 | 
			
		||||
    public void setReadTimeout(long readTimeout, TimeUnit timeUnit) {
 | 
			
		||||
        mOkHttpClient = mOkHttpClient.newBuilder()
 | 
			
		||||
                .readTimeout(readTimeout, timeUnit)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setConnectionTimeout(long connectionTimeout, TimeUnit timeUnit) {
 | 
			
		||||
        mOkHttpClient = mOkHttpClient.newBuilder()
 | 
			
		||||
                .readTimeout(connectionTimeout, timeUnit)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setFollowRedirects(boolean followRedirects) {
 | 
			
		||||
        mOkHttpClient = mOkHttpClient.newBuilder()
 | 
			
		||||
                .followRedirects(followRedirects)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) {
 | 
			
		||||
        mOkHttpClient = mOkHttpClient.newBuilder()
 | 
			
		||||
                .retryOnConnectionFailure(retryOnConnectionFailure)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Request
 | 
			
		||||
 | 
			
		||||
    public void addRequestHeader(String name, String value) {
 | 
			
		||||
        mRequest = mRequest.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
 | 
			
		||||
     */
 | 
			
		||||
    public void setRequestHeader(String name, String value) {
 | 
			
		||||
        mRequest = mRequest.newBuilder()
 | 
			
		||||
                .header(name, value)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setRequestBody(RequestBody requestBody) {
 | 
			
		||||
        mRequestBody = requestBody;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setUrl(HttpUrl url) {
 | 
			
		||||
        mRequest = mRequest.newBuilder()
 | 
			
		||||
                .url(url)
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OkHttp delete calls wrapper
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class DeleteMethod extends HttpMethod{
 | 
			
		||||
 | 
			
		||||
    public DeleteMethod(URL url) {
 | 
			
		||||
        super(url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws IOException {
 | 
			
		||||
        mRequest = mRequest.newBuilder()
 | 
			
		||||
                .delete()
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        return super.onExecute();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OkHttp get calls wrapper
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class GetMethod extends HttpMethod {
 | 
			
		||||
 | 
			
		||||
    public GetMethod(URL url) {
 | 
			
		||||
        super(url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws IOException {
 | 
			
		||||
        mRequest = mRequest.newBuilder()
 | 
			
		||||
                .get()
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        return super.onExecute();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,52 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import okhttp3.Call;
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wrapper to perform OkHttp calls
 | 
			
		||||
 *
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public abstract class HttpMethod extends HttpBaseMethod {
 | 
			
		||||
 | 
			
		||||
    public HttpMethod(URL url) {
 | 
			
		||||
        super(url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws IOException {
 | 
			
		||||
        mCall = mOkHttpClient.newCall(mRequest);
 | 
			
		||||
        mResponse = mCall.execute();
 | 
			
		||||
        return super.getStatusCode();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * OkHttp post calls wrapper
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class PostMethod extends HttpMethod {
 | 
			
		||||
 | 
			
		||||
    public PostMethod(URL url){
 | 
			
		||||
        super(url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws IOException {
 | 
			
		||||
        mRequest = mRequest.newBuilder()
 | 
			
		||||
                .post(mRequestBody)
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        return super.onExecute();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
 | 
			
		||||
public class PutMethod extends HttpMethod{
 | 
			
		||||
 | 
			
		||||
    public PutMethod(URL url){
 | 
			
		||||
        super(url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws IOException {
 | 
			
		||||
        mRequest = mRequest.newBuilder()
 | 
			
		||||
                .put(mRequestBody)
 | 
			
		||||
                .build();
 | 
			
		||||
 | 
			
		||||
        return super.onExecute();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,56 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.net.URL;
 | 
			
		||||
 | 
			
		||||
import kotlin.Unit;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Copy calls wrapper
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class CopyMethod extends DavMethod {
 | 
			
		||||
 | 
			
		||||
    final String destinationUrl;
 | 
			
		||||
    final boolean forceOverride;
 | 
			
		||||
 | 
			
		||||
    public CopyMethod(URL url, String destinationUrl, boolean forceOverride) {
 | 
			
		||||
        super(url);
 | 
			
		||||
        this.destinationUrl = destinationUrl;
 | 
			
		||||
        this.forceOverride = forceOverride;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws Exception {
 | 
			
		||||
        mDavResource.copy(destinationUrl, forceOverride, response -> {
 | 
			
		||||
            mResponse = response;
 | 
			
		||||
            return Unit.INSTANCE;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return super.getStatusCode();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,33 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
 */
 | 
			
		||||
public class DavConstants {
 | 
			
		||||
    public static final int DEPTH_0 = 0;
 | 
			
		||||
    public static final int DEPTH_1 = 1;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,158 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.Constants;
 | 
			
		||||
import at.bitfire.dav4android.DavOCResource;
 | 
			
		||||
import at.bitfire.dav4android.exception.HttpException;
 | 
			
		||||
import at.bitfire.dav4android.exception.RedirectException;
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
import okhttp3.Protocol;
 | 
			
		||||
import okhttp3.Response;
 | 
			
		||||
import okhttp3.ResponseBody;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Wrapper to perform WebDAV (dav4android) calls
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public abstract class DavMethod extends HttpBaseMethod {
 | 
			
		||||
 | 
			
		||||
    protected DavOCResource mDavResource;
 | 
			
		||||
 | 
			
		||||
    protected DavMethod(URL url) {
 | 
			
		||||
        super(url);
 | 
			
		||||
        mDavResource = new DavOCResource(
 | 
			
		||||
                mOkHttpClient,
 | 
			
		||||
                HttpUrl.parse(url.toString()),
 | 
			
		||||
                Constants.INSTANCE.getLog());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void abort() {
 | 
			
		||||
        mDavResource.cancelCall();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int execute() throws Exception {
 | 
			
		||||
        try {
 | 
			
		||||
            return onExecute();
 | 
			
		||||
        } catch (HttpException httpException) {
 | 
			
		||||
            // Modify responses with information gathered from exceptions
 | 
			
		||||
            if (httpException instanceof RedirectException) {
 | 
			
		||||
                mResponse = new Response.Builder()
 | 
			
		||||
                        .header(
 | 
			
		||||
                                HttpConstants.LOCATION_HEADER, ((RedirectException) httpException).getRedirectLocation()
 | 
			
		||||
                        )
 | 
			
		||||
                        .code(httpException.getCode())
 | 
			
		||||
                        .request(mRequest)
 | 
			
		||||
                        .message(httpException.getMessage())
 | 
			
		||||
                        .protocol(Protocol.HTTP_1_1)
 | 
			
		||||
                        .build();
 | 
			
		||||
 | 
			
		||||
            } else if (mResponse != null) {
 | 
			
		||||
                ResponseBody responseBody = ResponseBody.create(
 | 
			
		||||
                        mResponse.body().contentType(),
 | 
			
		||||
                        httpException.getResponseBody()
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                mResponse = mResponse.newBuilder()
 | 
			
		||||
                        .body(responseBody)
 | 
			
		||||
                        .build();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return httpException.getCode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
    //         Setter
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
 | 
			
		||||
    // Connection parameters
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setReadTimeout(long readTimeout, TimeUnit timeUnit) {
 | 
			
		||||
        super.setReadTimeout(readTimeout, timeUnit);
 | 
			
		||||
        mDavResource = new DavOCResource(
 | 
			
		||||
                mOkHttpClient,
 | 
			
		||||
                HttpUrl.parse(mRequest.url().toString()),
 | 
			
		||||
                Constants.INSTANCE.getLog());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setConnectionTimeout(long connectionTimeout, TimeUnit timeUnit) {
 | 
			
		||||
        super.setConnectionTimeout(connectionTimeout, timeUnit);
 | 
			
		||||
        mDavResource = new DavOCResource(
 | 
			
		||||
                mOkHttpClient,
 | 
			
		||||
                HttpUrl.parse(mRequest.url().toString()),
 | 
			
		||||
                Constants.INSTANCE.getLog());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setFollowRedirects(boolean followRedirects) {
 | 
			
		||||
        super.setFollowRedirects(followRedirects);
 | 
			
		||||
        mDavResource = new DavOCResource(
 | 
			
		||||
                mOkHttpClient,
 | 
			
		||||
                HttpUrl.parse(mRequest.url().toString()),
 | 
			
		||||
                Constants.INSTANCE.getLog());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setRetryOnConnectionFailure(boolean retryOnConnectionFailure) {
 | 
			
		||||
        super.setRetryOnConnectionFailure(retryOnConnectionFailure);
 | 
			
		||||
        mDavResource = new DavOCResource(
 | 
			
		||||
                mOkHttpClient,
 | 
			
		||||
                HttpUrl.parse(mRequest.url().toString()),
 | 
			
		||||
                Constants.INSTANCE.getLog());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setUrl(HttpUrl url){
 | 
			
		||||
        super.setUrl(url);
 | 
			
		||||
        mDavResource = new DavOCResource(
 | 
			
		||||
                mOkHttpClient,
 | 
			
		||||
                HttpUrl.parse(mRequest.url().toString()),
 | 
			
		||||
                Constants.INSTANCE.getLog());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
    //         Getter
 | 
			
		||||
    //////////////////////////////
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean getRetryOnConnectionFailure() {
 | 
			
		||||
        return false; //TODO: implement me
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isAborted() {
 | 
			
		||||
        return mDavResource.isCallAborted();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,15 @@
 | 
			
		||||
package com.owncloud.android.lib.common.http.methods.webdav;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.Property;
 | 
			
		||||
import at.bitfire.dav4android.PropertyUtils;
 | 
			
		||||
 | 
			
		||||
public class DavUtils {
 | 
			
		||||
 | 
			
		||||
    public static final Property.Name[] getAllPropset() {
 | 
			
		||||
        return PropertyUtils.INSTANCE.getAllPropSet();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static final Property.Name[] getQuotaPropSet() {
 | 
			
		||||
        return PropertyUtils.INSTANCE.getQuotaPropset();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.net.URL;
 | 
			
		||||
 | 
			
		||||
import kotlin.Unit;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MkCol calls wrapper
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class MkColMethod extends DavMethod {
 | 
			
		||||
    public MkColMethod(URL url) {
 | 
			
		||||
        super(url);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws Exception {
 | 
			
		||||
        mDavResource.mkCol(null, response -> {
 | 
			
		||||
            mResponse = response;
 | 
			
		||||
            return Unit.INSTANCE;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return super.getStatusCode();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,61 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import kotlin.Unit;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Move calls wrapper
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class MoveMethod extends DavMethod {
 | 
			
		||||
    final String destinationUrl;
 | 
			
		||||
    final boolean forceOverride;
 | 
			
		||||
 | 
			
		||||
    public MoveMethod(URL url, String destinationUrl, boolean forceOverride) {
 | 
			
		||||
        super(url);
 | 
			
		||||
        this.destinationUrl = destinationUrl;
 | 
			
		||||
        this.forceOverride = forceOverride;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws Exception {
 | 
			
		||||
        mDavResource.move(
 | 
			
		||||
                destinationUrl,
 | 
			
		||||
                forceOverride,
 | 
			
		||||
                super.getRequestHeader(HttpConstants.OC_TOTAL_LENGTH_HEADER),
 | 
			
		||||
                super.getRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER), response -> {
 | 
			
		||||
                    mResponse = response;
 | 
			
		||||
                    return Unit.INSTANCE;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
        return super.getStatusCode();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,93 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.Property;
 | 
			
		||||
import at.bitfire.dav4android.Response;
 | 
			
		||||
import at.bitfire.dav4android.exception.DavException;
 | 
			
		||||
import kotlin.Unit;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Propfind calls wrapper
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class PropfindMethod extends DavMethod {
 | 
			
		||||
 | 
			
		||||
    // request
 | 
			
		||||
    private final int mDepth;
 | 
			
		||||
    private final Property.Name[] mPropertiesToRequest;
 | 
			
		||||
 | 
			
		||||
    // response
 | 
			
		||||
    private final List<Response> mMembers;
 | 
			
		||||
    private Response mRoot;
 | 
			
		||||
 | 
			
		||||
    public PropfindMethod(URL url, int depth, Property.Name[] propertiesToRequest) {
 | 
			
		||||
        super(url);
 | 
			
		||||
        mDepth = depth;
 | 
			
		||||
        mPropertiesToRequest = propertiesToRequest;
 | 
			
		||||
        mMembers = new ArrayList<>();
 | 
			
		||||
        mRoot = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws IOException, DavException{
 | 
			
		||||
        mDavResource.propfind(mDepth, mPropertiesToRequest,
 | 
			
		||||
                (Response response, Response.HrefRelation hrefRelation) -> {
 | 
			
		||||
                    switch (hrefRelation) {
 | 
			
		||||
                        case MEMBER:
 | 
			
		||||
                            mMembers.add(response);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case SELF:
 | 
			
		||||
                            mRoot = response;
 | 
			
		||||
                            break;
 | 
			
		||||
                        case OTHER:
 | 
			
		||||
                        default:
 | 
			
		||||
                    }
 | 
			
		||||
                    return Unit.INSTANCE;
 | 
			
		||||
                }, response -> {
 | 
			
		||||
                    mResponse = response;
 | 
			
		||||
                    return Unit.INSTANCE;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
        return getStatusCode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getDepth() {
 | 
			
		||||
        return mDepth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public List<Response> getMembers() {
 | 
			
		||||
        return mMembers;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Response getRoot() {
 | 
			
		||||
        return mRoot;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,59 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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 com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.exception.HttpException;
 | 
			
		||||
import kotlin.Unit;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Put calls wrapper
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class PutMethod extends DavMethod {
 | 
			
		||||
 | 
			
		||||
    public PutMethod(URL url) {
 | 
			
		||||
        super(url);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int onExecute() throws IOException, HttpException {
 | 
			
		||||
        mDavResource.put(
 | 
			
		||||
                mRequestBody,
 | 
			
		||||
                super.getRequestHeader(HttpConstants.IF_MATCH_HEADER),
 | 
			
		||||
                super.getRequestHeader(HttpConstants.CONTENT_TYPE_HEADER),
 | 
			
		||||
                super.getRequestHeader(HttpConstants.OC_TOTAL_LENGTH_HEADER),
 | 
			
		||||
                super.getRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER), response -> {
 | 
			
		||||
                    mResponse = response;
 | 
			
		||||
                    return Unit.INSTANCE;
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
        return super.getStatusCode();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,344 +0,0 @@
 | 
			
		||||
/* 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 java.io.IOException;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.net.InetSocketAddress;
 | 
			
		||||
import java.net.Socket;
 | 
			
		||||
import java.net.SocketAddress;
 | 
			
		||||
import java.net.UnknownHostException;
 | 
			
		||||
import java.security.cert.X509Certificate;
 | 
			
		||||
 | 
			
		||||
import javax.net.SocketFactory;
 | 
			
		||||
import javax.net.ssl.SSLContext;
 | 
			
		||||
import javax.net.ssl.SSLException;
 | 
			
		||||
import javax.net.ssl.SSLHandshakeException;
 | 
			
		||||
import javax.net.ssl.SSLParameters;
 | 
			
		||||
import javax.net.ssl.SSLPeerUnverifiedException;
 | 
			
		||||
import javax.net.ssl.SSLSession;
 | 
			
		||||
import javax.net.ssl.SSLSocket;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.ConnectTimeoutException;
 | 
			
		||||
import org.apache.commons.httpclient.params.HttpConnectionParams;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
 | 
			
		||||
import org.apache.http.conn.ssl.X509HostnameVerifier;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * AdvancedSSLProtocolSocketFactory allows to create SSL {@link Socket}s with
 | 
			
		||||
 * a custom SSLContext and an optional Hostname Verifier.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class AdvancedSslSocketFactory implements SecureProtocolSocketFactory {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = AdvancedSslSocketFactory.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private SSLContext mSslContext = null;
 | 
			
		||||
    private AdvancedX509TrustManager mTrustManager = null;
 | 
			
		||||
    private X509HostnameVerifier mHostnameVerifier = null;
 | 
			
		||||
 | 
			
		||||
    public SSLContext getSslContext() {
 | 
			
		||||
        return mSslContext;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor for AdvancedSSLProtocolSocketFactory.
 | 
			
		||||
     */
 | 
			
		||||
    public AdvancedSslSocketFactory(
 | 
			
		||||
        SSLContext sslContext, AdvancedX509TrustManager trustManager, X509HostnameVerifier hostnameVerifier
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        if (sslContext == null)
 | 
			
		||||
            throw new IllegalArgumentException("AdvancedSslSocketFactory can not be created with a null SSLContext");
 | 
			
		||||
        if (trustManager == null && mHostnameVerifier != null)
 | 
			
		||||
            throw new IllegalArgumentException(
 | 
			
		||||
                "AdvancedSslSocketFactory can not be created with a null Trust Manager and a " +
 | 
			
		||||
                    "not null Hostname Verifier"
 | 
			
		||||
            );
 | 
			
		||||
        mSslContext = sslContext;
 | 
			
		||||
        mTrustManager = trustManager;
 | 
			
		||||
        mHostnameVerifier = hostnameVerifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @see ProtocolSocketFactory#createSocket(java.lang.String, int, java.net.InetAddress, int)
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
 | 
			
		||||
        throws IOException, UnknownHostException {
 | 
			
		||||
 | 
			
		||||
        Socket socket = mSslContext.getSocketFactory().createSocket(host, port, clientHost, clientPort);
 | 
			
		||||
        enableSecureProtocols(socket);
 | 
			
		||||
        verifyPeerIdentity(host, port, socket);
 | 
			
		||||
        return socket;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
    private void logSslInfo() {
 | 
			
		||||
    	if (Build.VERSION.SDK_INT > Build.VERSION_CODES.FROYO) {
 | 
			
		||||
	    	Log_OC.v(TAG, "SUPPORTED SSL PARAMETERS");
 | 
			
		||||
	    	logSslParameters(mSslContext.getSupportedSSLParameters());
 | 
			
		||||
	    	Log_OC.v(TAG, "DEFAULT SSL PARAMETERS");
 | 
			
		||||
	    	logSslParameters(mSslContext.getDefaultSSLParameters());
 | 
			
		||||
	    	Log_OC.i(TAG, "CURRENT PARAMETERS");
 | 
			
		||||
	    	Log_OC.i(TAG, "Protocol: " + mSslContext.getProtocol());
 | 
			
		||||
    	}
 | 
			
		||||
    	Log_OC.i(TAG, "PROVIDER");
 | 
			
		||||
    	logSecurityProvider(mSslContext.getProvider());
 | 
			
		||||
	}
 | 
			
		||||
    
 | 
			
		||||
    private void logSecurityProvider(Provider provider) {
 | 
			
		||||
    	Log_OC.i(TAG, "name: " + provider.getName());
 | 
			
		||||
    	Log_OC.i(TAG, "version: " + provider.getVersion());
 | 
			
		||||
    	Log_OC.i(TAG, "info: " + provider.getInfo());
 | 
			
		||||
    	Enumeration<?> keys = provider.propertyNames();
 | 
			
		||||
    	String key;
 | 
			
		||||
    	while (keys.hasMoreElements()) {
 | 
			
		||||
    		key = (String) keys.nextElement();
 | 
			
		||||
        	Log_OC.i(TAG, "  property " + key + " : " + provider.getProperty(key));
 | 
			
		||||
    	}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void logSslParameters(SSLParameters params) {
 | 
			
		||||
    	Log_OC.v(TAG, "Cipher suites: ");
 | 
			
		||||
    	String [] elements = params.getCipherSuites();
 | 
			
		||||
    	for (int i=0; i<elements.length ; i++) {
 | 
			
		||||
    		Log_OC.v(TAG, "  " + elements[i]);
 | 
			
		||||
    	}
 | 
			
		||||
    	Log_OC.v(TAG, "Protocols: ");
 | 
			
		||||
    	elements = params.getProtocols();
 | 
			
		||||
    	for (int i=0; i<elements.length ; i++) {
 | 
			
		||||
    		Log_OC.v(TAG, "  " + elements[i]);
 | 
			
		||||
    	}
 | 
			
		||||
	}
 | 
			
		||||
	*/
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempts to get a new socket connection to the given host within the
 | 
			
		||||
     * given time limit.
 | 
			
		||||
     *
 | 
			
		||||
     * @param host         the host name/IP
 | 
			
		||||
     * @param port         the port on the host
 | 
			
		||||
     * @param localAddress the local host name/IP to bind the socket to
 | 
			
		||||
     * @param localPort    the port on the local machine
 | 
			
		||||
     * @param params       {@link HttpConnectionParams Http connection parameters}
 | 
			
		||||
     * @return Socket a new socket
 | 
			
		||||
     * @throws IOException          if an I/O error occurs while creating the socket
 | 
			
		||||
     * @throws UnknownHostException if the IP address of the host cannot be
 | 
			
		||||
     *                              determined
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public Socket createSocket(final String host, final int port,
 | 
			
		||||
                               final InetAddress localAddress, final int localPort,
 | 
			
		||||
                               final HttpConnectionParams params) throws IOException,
 | 
			
		||||
        UnknownHostException, ConnectTimeoutException {
 | 
			
		||||
        Log_OC.d(TAG, "Creating SSL Socket with remote " + host + ":" + port + ", local " + localAddress + ":" +
 | 
			
		||||
            localPort + ", params: " + params);
 | 
			
		||||
        if (params == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Parameters may not be null");
 | 
			
		||||
        }
 | 
			
		||||
        int timeout = params.getConnectionTimeout();
 | 
			
		||||
 | 
			
		||||
        //logSslInfo();
 | 
			
		||||
 | 
			
		||||
        SocketFactory socketfactory = mSslContext.getSocketFactory();
 | 
			
		||||
        Log_OC.d(TAG, " ... with connection timeout " + timeout + " and socket timeout " + params.getSoTimeout());
 | 
			
		||||
        Socket socket = socketfactory.createSocket();
 | 
			
		||||
        enableSecureProtocols(socket);
 | 
			
		||||
        SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
 | 
			
		||||
        SocketAddress remoteaddr = new InetSocketAddress(host, port);
 | 
			
		||||
        socket.setSoTimeout(params.getSoTimeout());
 | 
			
		||||
        WriteTimeoutEnforcer.setSoWriteTimeout(params.getSoTimeout(), socket);
 | 
			
		||||
        socket.bind(localaddr);
 | 
			
		||||
        ServerNameIndicator.setServerNameIndication(host, (SSLSocket) socket);
 | 
			
		||||
        socket.connect(remoteaddr, timeout);
 | 
			
		||||
        verifyPeerIdentity(host, port, socket);
 | 
			
		||||
        return socket;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @see ProtocolSocketFactory#createSocket(java.lang.String, int)
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public Socket createSocket(String host, int port) throws IOException,
 | 
			
		||||
        UnknownHostException {
 | 
			
		||||
        Log_OC.d(TAG, "Creating SSL Socket with remote " + host + ":" + port);
 | 
			
		||||
        Socket socket = mSslContext.getSocketFactory().createSocket(host, port);
 | 
			
		||||
        enableSecureProtocols(socket);
 | 
			
		||||
        verifyPeerIdentity(host, port, socket);
 | 
			
		||||
        return socket;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
 | 
			
		||||
        UnknownHostException {
 | 
			
		||||
        Socket sslSocket = mSslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
 | 
			
		||||
        enableSecureProtocols(sslSocket);
 | 
			
		||||
        verifyPeerIdentity(host, port, sslSocket);
 | 
			
		||||
        return sslSocket;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public boolean equals(Object obj) {
 | 
			
		||||
        return ((obj != null) && obj.getClass().equals(
 | 
			
		||||
            AdvancedSslSocketFactory.class));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int hashCode() {
 | 
			
		||||
        return AdvancedSslSocketFactory.class.hashCode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public X509HostnameVerifier getHostNameVerifier() {
 | 
			
		||||
        return mHostnameVerifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public void setHostNameVerifier(X509HostnameVerifier hostnameVerifier) {
 | 
			
		||||
        mHostnameVerifier = hostnameVerifier;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Verifies the identity of the server.
 | 
			
		||||
     *
 | 
			
		||||
     * The server certificate is verified first.
 | 
			
		||||
     *
 | 
			
		||||
     * Then, the host name is compared with the content of the server certificate using the current host name verifier,
 | 
			
		||||
     * if any.
 | 
			
		||||
     *
 | 
			
		||||
     * @param socket
 | 
			
		||||
     */
 | 
			
		||||
    private void verifyPeerIdentity(String host, int port, Socket socket) throws IOException {
 | 
			
		||||
        try {
 | 
			
		||||
            CertificateCombinedException failInHandshake = null;
 | 
			
		||||
            /// 1. VERIFY THE SERVER CERTIFICATE through the registered TrustManager 
 | 
			
		||||
            ///	(that should be an instance of AdvancedX509TrustManager) 
 | 
			
		||||
            try {
 | 
			
		||||
                SSLSocket sock = (SSLSocket) socket;    // a new SSLSession instance is created as a "side effect" 
 | 
			
		||||
                sock.startHandshake();
 | 
			
		||||
 | 
			
		||||
            } catch (RuntimeException e) {
 | 
			
		||||
 | 
			
		||||
                if (e instanceof CertificateCombinedException) {
 | 
			
		||||
                    failInHandshake = (CertificateCombinedException) e;
 | 
			
		||||
                } else {
 | 
			
		||||
                    Throwable cause = e.getCause();
 | 
			
		||||
                    Throwable previousCause = null;
 | 
			
		||||
                    while (cause != null &&
 | 
			
		||||
                        cause != previousCause &&
 | 
			
		||||
                        !(cause instanceof CertificateCombinedException)) {
 | 
			
		||||
                        previousCause = cause;
 | 
			
		||||
                        cause = cause.getCause();
 | 
			
		||||
                    }
 | 
			
		||||
                    if (cause != null && cause instanceof CertificateCombinedException) {
 | 
			
		||||
                        failInHandshake = (CertificateCombinedException) cause;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (failInHandshake == null) {
 | 
			
		||||
                    throw e;
 | 
			
		||||
                }
 | 
			
		||||
                failInHandshake.setHostInUrl(host);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /// 2. VERIFY HOSTNAME
 | 
			
		||||
            SSLSession newSession = null;
 | 
			
		||||
            boolean verifiedHostname = true;
 | 
			
		||||
            if (mHostnameVerifier != null) {
 | 
			
		||||
                if (failInHandshake != null) {
 | 
			
		||||
                    /// 2.1 : a new SSLSession instance was NOT created in the handshake
 | 
			
		||||
                    X509Certificate serverCert = failInHandshake.getServerCertificate();
 | 
			
		||||
                    try {
 | 
			
		||||
                        mHostnameVerifier.verify(host, serverCert);
 | 
			
		||||
                    } catch (SSLException e) {
 | 
			
		||||
                        verifiedHostname = false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    /// 2.2 : a new SSLSession instance was created in the handshake
 | 
			
		||||
                    newSession = ((SSLSocket) socket).getSession();
 | 
			
		||||
                    if (!mTrustManager.isKnownServer((X509Certificate) (newSession.getPeerCertificates()[0]))) {
 | 
			
		||||
                        verifiedHostname = mHostnameVerifier.verify(host, newSession);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /// 3. Combine the exceptions to throw, if any
 | 
			
		||||
            if (!verifiedHostname) {
 | 
			
		||||
                SSLPeerUnverifiedException pue = new SSLPeerUnverifiedException(
 | 
			
		||||
                    "Names in the server certificate do not match to " + host + " in the URL"
 | 
			
		||||
                );
 | 
			
		||||
                if (failInHandshake == null) {
 | 
			
		||||
                    failInHandshake = new CertificateCombinedException(
 | 
			
		||||
                        (X509Certificate) newSession.getPeerCertificates()[0]
 | 
			
		||||
                    );
 | 
			
		||||
                    failInHandshake.setHostInUrl(host);
 | 
			
		||||
                }
 | 
			
		||||
                failInHandshake.setSslPeerUnverifiedException(pue);
 | 
			
		||||
                pue.initCause(failInHandshake);
 | 
			
		||||
                throw pue;
 | 
			
		||||
 | 
			
		||||
            } else if (failInHandshake != null) {
 | 
			
		||||
                SSLHandshakeException hse = new SSLHandshakeException("Server certificate could not be verified");
 | 
			
		||||
                hse.initCause(failInHandshake);
 | 
			
		||||
                throw hse;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (IOException io) {
 | 
			
		||||
            try {
 | 
			
		||||
                socket.close();
 | 
			
		||||
            } catch (Exception x) {
 | 
			
		||||
                // NOTHING - irrelevant exception for the caller 
 | 
			
		||||
            }
 | 
			
		||||
            throw io;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Grants that all protocols supported by the Security Provider in mSslContext are enabled in socket.
 | 
			
		||||
     *
 | 
			
		||||
     * Grants also that no unsupported protocol is tried to be enabled. That would trigger an exception, breaking
 | 
			
		||||
     * the connection process although some protocols are supported.
 | 
			
		||||
     *
 | 
			
		||||
     * This is not cosmetic: not all the supported protocols are enabled by default. Too see an overview of
 | 
			
		||||
     * supported and enabled protocols in the stock Security Provider in Android see the tables in
 | 
			
		||||
     * http://developer.android.com/reference/javax/net/ssl/SSLSocket.html.
 | 
			
		||||
     *
 | 
			
		||||
     * @param socket
 | 
			
		||||
     */
 | 
			
		||||
    private void enableSecureProtocols(Socket socket) {
 | 
			
		||||
        SSLParameters params = mSslContext.getSupportedSSLParameters();
 | 
			
		||||
        String[] supportedProtocols = params.getProtocols();
 | 
			
		||||
        ((SSLSocket) socket).setEnabledProtocols(supportedProtocols);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -100,7 +100,7 @@ public class AdvancedX509TrustManager implements X509TrustManager {
 | 
			
		||||
     * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],
 | 
			
		||||
     *      String authType)
 | 
			
		||||
     */
 | 
			
		||||
    public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
 | 
			
		||||
    public void checkServerTrusted(X509Certificate[] certificates, String authType) {
 | 
			
		||||
        if (!isKnownServer(certificates[0])) {
 | 
			
		||||
        	CertificateCombinedException result = new CertificateCombinedException(certificates[0]);
 | 
			
		||||
        	try {
 | 
			
		||||
 | 
			
		||||
@ -1,22 +1,22 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -24,64 +24,51 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common.network;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.methods.RequestEntity;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
 | 
			
		||||
import okhttp3.MediaType;
 | 
			
		||||
import okio.BufferedSink;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A RequestEntity that represents a PIECE of a file.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * A Request body that represents a file chunk and include information about the progress when uploading it
 | 
			
		||||
 *
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class ChunkFromFileChannelRequestEntity implements RequestEntity, ProgressiveDataTransferer {
 | 
			
		||||
public class ChunkFromFileRequestBody extends FileRequestBody {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = ChunkFromFileRequestBody.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = ChunkFromFileChannelRequestEntity.class.getSimpleName();
 | 
			
		||||
    
 | 
			
		||||
    //private final File mFile;
 | 
			
		||||
    private final FileChannel mChannel;
 | 
			
		||||
    private final String mContentType;
 | 
			
		||||
    private final long mChunkSize;
 | 
			
		||||
    private final File mFile;
 | 
			
		||||
    private long mOffset;
 | 
			
		||||
    private long mTransferred;
 | 
			
		||||
    Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
 | 
			
		||||
    private ByteBuffer mBuffer = ByteBuffer.allocate(4096);
 | 
			
		||||
 | 
			
		||||
    public ChunkFromFileChannelRequestEntity(
 | 
			
		||||
        final FileChannel channel, final String contentType, long chunkSize, final File file
 | 
			
		||||
    ) {
 | 
			
		||||
        super();
 | 
			
		||||
    public ChunkFromFileRequestBody(File file, MediaType contentType, FileChannel channel, long chunkSize) {
 | 
			
		||||
        super(file, contentType);
 | 
			
		||||
        if (channel == null) {
 | 
			
		||||
            throw new IllegalArgumentException("File may not be null");
 | 
			
		||||
        }
 | 
			
		||||
        if (chunkSize <= 0) {
 | 
			
		||||
            throw new IllegalArgumentException("Chunk size must be greater than zero");
 | 
			
		||||
        }
 | 
			
		||||
        mChannel = channel;
 | 
			
		||||
        mContentType = contentType;
 | 
			
		||||
        mChunkSize = chunkSize;
 | 
			
		||||
        mFile = file;
 | 
			
		||||
        this.mChannel = channel;
 | 
			
		||||
        this.mChunkSize = chunkSize;
 | 
			
		||||
        mOffset = 0;
 | 
			
		||||
        mTransferred = 0;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public void setOffset(long offset) {
 | 
			
		||||
        mOffset = offset;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public long getContentLength() {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long contentLength() {
 | 
			
		||||
        try {
 | 
			
		||||
            return Math.min(mChunkSize, mChannel.size() - mChannel.position());
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
@ -89,39 +76,10 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getContentType() {
 | 
			
		||||
        return mContentType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isRepeatable() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addDatatransferProgressListener(OnDatatransferProgressListener listener) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.add(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.addAll(listeners);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.remove(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    public void writeRequest(final OutputStream out) throws IOException {
 | 
			
		||||
        int readCount = 0;
 | 
			
		||||
        Iterator<OnDatatransferProgressListener> it = null;
 | 
			
		||||
    public void writeTo(BufferedSink sink) {
 | 
			
		||||
        int readCount;
 | 
			
		||||
        Iterator<OnDatatransferProgressListener> it;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            mChannel.position(mOffset);
 | 
			
		||||
@ -129,13 +87,20 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
 | 
			
		||||
            if (size == 0) size = -1;
 | 
			
		||||
            long maxCount = Math.min(mOffset + mChunkSize, mChannel.size());
 | 
			
		||||
            while (mChannel.position() < maxCount) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                Log_OC.d(TAG, "Sink buffer size: " + sink.buffer().size());
 | 
			
		||||
 | 
			
		||||
                readCount = mChannel.read(mBuffer);
 | 
			
		||||
                try {
 | 
			
		||||
                    out.write(mBuffer.array(), 0, readCount);
 | 
			
		||||
                } catch (IOException io) {
 | 
			
		||||
                    // work-around try catch to filter exception in writing
 | 
			
		||||
                    throw new FileRequestEntity.WriteException(io);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Log_OC.d(TAG, "Read " + readCount + " bytes from file channel to " + mBuffer.toString());
 | 
			
		||||
 | 
			
		||||
                sink.buffer().write(mBuffer.array(), 0 ,readCount);
 | 
			
		||||
 | 
			
		||||
                sink.flush();
 | 
			
		||||
 | 
			
		||||
                Log_OC.d(TAG, "Write " + readCount + " bytes to sink buffer with size " + sink.buffer().size());
 | 
			
		||||
 | 
			
		||||
                mBuffer.clear();
 | 
			
		||||
                if (mTransferred < maxCount) {  // condition to avoid accumulate progress for repeated chunks
 | 
			
		||||
                    mTransferred += readCount;
 | 
			
		||||
@ -148,20 +113,23 @@ public class ChunkFromFileChannelRequestEntity implements RequestEntity, Progres
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (IOException io) {
 | 
			
		||||
            // any read problem will be handled as if the file is not there
 | 
			
		||||
            if (io instanceof FileNotFoundException) {
 | 
			
		||||
                throw io;
 | 
			
		||||
            } else {
 | 
			
		||||
                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file");
 | 
			
		||||
                fnf.initCause(io);
 | 
			
		||||
                throw fnf;
 | 
			
		||||
            }
 | 
			
		||||
            Log.d(TAG, "Chunk with size " + mChunkSize + " written in request body");
 | 
			
		||||
 | 
			
		||||
        } catch (FileRequestEntity.WriteException we) {
 | 
			
		||||
            throw we.getWrapped();
 | 
			
		||||
        } catch (Exception exception) {
 | 
			
		||||
 | 
			
		||||
            Log.e(TAG, exception.toString());
 | 
			
		||||
//            // any read problem will be handled as if the file is not there
 | 
			
		||||
//            if (io instanceof FileNotFoundException) {
 | 
			
		||||
//                throw io;
 | 
			
		||||
//            } else {
 | 
			
		||||
//                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file");
 | 
			
		||||
//                fnf.initCause(io);
 | 
			
		||||
//                throw fnf;
 | 
			
		||||
//            }
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setOffset(long offset) {
 | 
			
		||||
        this.mOffset = offset;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										120
									
								
								src/com/owncloud/android/lib/common/network/FileRequestBody.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/com/owncloud/android/lib/common/network/FileRequestBody.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,120 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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.util.Log;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import okhttp3.MediaType;
 | 
			
		||||
import okhttp3.RequestBody;
 | 
			
		||||
import okio.BufferedSink;
 | 
			
		||||
import okio.Okio;
 | 
			
		||||
import okio.Source;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Request body that represents a file and include information about the progress when uploading it
 | 
			
		||||
 *
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class FileRequestBody extends RequestBody implements ProgressiveDataTransferer {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = FileRequestBody.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    protected File mFile;
 | 
			
		||||
    private MediaType mContentType;
 | 
			
		||||
    Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    public FileRequestBody(File file, MediaType contentType) {
 | 
			
		||||
        mFile = file;
 | 
			
		||||
        mContentType = contentType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public MediaType contentType() {
 | 
			
		||||
        return mContentType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public long contentLength() {
 | 
			
		||||
        return mFile.length();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void writeTo(BufferedSink sink) {
 | 
			
		||||
        Source source;
 | 
			
		||||
        Iterator<OnDatatransferProgressListener> it;
 | 
			
		||||
        try {
 | 
			
		||||
            source = Okio.source(mFile);
 | 
			
		||||
 | 
			
		||||
            long transferred = 0;
 | 
			
		||||
            long read;
 | 
			
		||||
 | 
			
		||||
            while ((read = source.read(sink.buffer(), 4096)) != -1) {
 | 
			
		||||
                transferred += read;
 | 
			
		||||
                sink.flush();
 | 
			
		||||
                synchronized (mDataTransferListeners) {
 | 
			
		||||
                    it = mDataTransferListeners.iterator();
 | 
			
		||||
                    while (it.hasNext()) {
 | 
			
		||||
                        it.next().onTransferProgress(read, transferred, mFile.length(), mFile.getAbsolutePath());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Log.d(TAG, "File with name " + mFile.getName() + " and size " + mFile.length() +
 | 
			
		||||
                    " written in request body");
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addDatatransferProgressListener(OnDatatransferProgressListener listener) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.add(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.addAll(listeners);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.remove(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,166 +0,0 @@
 | 
			
		||||
/* 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 java.io.File;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.io.RandomAccessFile;
 | 
			
		||||
import java.nio.ByteBuffer;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.methods.RequestEntity;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A RequestEntity that represents a File.
 | 
			
		||||
 * 
 | 
			
		||||
 */
 | 
			
		||||
public class FileRequestEntity implements RequestEntity, ProgressiveDataTransferer {
 | 
			
		||||
 | 
			
		||||
    final File mFile;
 | 
			
		||||
    final String mContentType;
 | 
			
		||||
    Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
 | 
			
		||||
 | 
			
		||||
    public FileRequestEntity(final File file, final String contentType) {
 | 
			
		||||
        super();
 | 
			
		||||
        this.mFile = file;
 | 
			
		||||
        this.mContentType = contentType;
 | 
			
		||||
        if (file == null) {
 | 
			
		||||
            throw new IllegalArgumentException("File may not be null");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public long getContentLength() {
 | 
			
		||||
        return mFile.length();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getContentType() {
 | 
			
		||||
        return mContentType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isRepeatable() {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addDatatransferProgressListener(OnDatatransferProgressListener listener) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.add(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addDatatransferProgressListeners(Collection<OnDatatransferProgressListener> listeners) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.addAll(listeners);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void removeDatatransferProgressListener(OnDatatransferProgressListener listener) {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.remove(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    @Override
 | 
			
		||||
    public void writeRequest(final OutputStream out) throws IOException {
 | 
			
		||||
        ByteBuffer tmp = ByteBuffer.allocate(4096);
 | 
			
		||||
        int readResult = 0;
 | 
			
		||||
        
 | 
			
		||||
        RandomAccessFile raf = new RandomAccessFile(mFile, "r");
 | 
			
		||||
        FileChannel channel = raf.getChannel();
 | 
			
		||||
        Iterator<OnDatatransferProgressListener> it = null;
 | 
			
		||||
        long transferred = 0;
 | 
			
		||||
        long size = mFile.length();
 | 
			
		||||
        if (size == 0) size = -1;
 | 
			
		||||
        try {
 | 
			
		||||
            while ((readResult = channel.read(tmp)) >= 0) {
 | 
			
		||||
                try {
 | 
			
		||||
                    out.write(tmp.array(), 0, readResult);
 | 
			
		||||
                } catch (IOException io) {
 | 
			
		||||
                    // work-around try catch to filter exception in writing
 | 
			
		||||
                    throw new WriteException(io);
 | 
			
		||||
                }
 | 
			
		||||
                tmp.clear();
 | 
			
		||||
                transferred += readResult;
 | 
			
		||||
                synchronized (mDataTransferListeners) {
 | 
			
		||||
                    it = mDataTransferListeners.iterator();
 | 
			
		||||
                    while (it.hasNext()) {
 | 
			
		||||
                        it.next().onTransferProgress(readResult, transferred, size, mFile.getAbsolutePath());
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (IOException io) {
 | 
			
		||||
            // any read problem will be handled as if the file is not there
 | 
			
		||||
            if (io instanceof FileNotFoundException) {
 | 
			
		||||
                throw io;
 | 
			
		||||
            } else {
 | 
			
		||||
                FileNotFoundException fnf = new FileNotFoundException("Exception reading source file");
 | 
			
		||||
                fnf.initCause(io);
 | 
			
		||||
                throw fnf;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (WriteException we) {
 | 
			
		||||
            throw we.getWrapped();
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            try {
 | 
			
		||||
                channel.close();
 | 
			
		||||
                raf.close();
 | 
			
		||||
            } catch (IOException io) {
 | 
			
		||||
                // ignore failures closing source file
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static class WriteException extends Exception {
 | 
			
		||||
        IOException mWrapped;
 | 
			
		||||
 | 
			
		||||
        WriteException(IOException wrapped) {
 | 
			
		||||
            mWrapped = wrapped;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IOException getWrapped() {
 | 
			
		||||
            return mWrapped;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -29,19 +29,13 @@ import java.io.FileInputStream;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.security.GeneralSecurityException;
 | 
			
		||||
import java.security.KeyStore;
 | 
			
		||||
import java.security.KeyStoreException;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.security.cert.Certificate;
 | 
			
		||||
import java.security.cert.CertificateException;
 | 
			
		||||
 | 
			
		||||
import javax.net.ssl.SSLContext;
 | 
			
		||||
import javax.net.ssl.TrustManager;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.Protocol;
 | 
			
		||||
import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
 | 
			
		||||
import org.apache.http.conn.ssl.X509HostnameVerifier;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
@ -64,67 +58,7 @@ public class NetworkUtils {
 | 
			
		||||
    /** Standard name for protocol TLS version 1.0 in JSSE API */
 | 
			
		||||
    public static final String PROTOCOL_TLSv1_0 = "TLSv1";
 | 
			
		||||
 | 
			
		||||
    /** Connection manager for all the OwnCloudClients */
 | 
			
		||||
    private static MultiThreadedHttpConnectionManager mConnManager = null;
 | 
			
		||||
    
 | 
			
		||||
    private static Protocol mDefaultHttpsProtocol = null;
 | 
			
		||||
 | 
			
		||||
    private static AdvancedSslSocketFactory mAdvancedSslSocketFactory = null;
 | 
			
		||||
 | 
			
		||||
    private static X509HostnameVerifier mHostnameVerifier = null;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Registers or unregisters the proper components for advanced SSL handling.
 | 
			
		||||
     * @throws IOException 
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressWarnings("deprecation")
 | 
			
		||||
	public static void registerAdvancedSslContext(boolean register, Context context) 
 | 
			
		||||
    		throws GeneralSecurityException, IOException {
 | 
			
		||||
        Protocol pr = null;
 | 
			
		||||
        try {
 | 
			
		||||
            pr = Protocol.getProtocol("https");
 | 
			
		||||
            if (pr != null && mDefaultHttpsProtocol == null) {
 | 
			
		||||
                mDefaultHttpsProtocol = pr;
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IllegalStateException e) {
 | 
			
		||||
            // nothing to do here; really
 | 
			
		||||
        }
 | 
			
		||||
        boolean isRegistered = (pr != null && pr.getSocketFactory() instanceof AdvancedSslSocketFactory);
 | 
			
		||||
        if (register && !isRegistered) {
 | 
			
		||||
            Protocol.registerProtocol("https", new Protocol("https", getAdvancedSslSocketFactory(context), 443));
 | 
			
		||||
            
 | 
			
		||||
        } else if (!register && isRegistered) {
 | 
			
		||||
            if (mDefaultHttpsProtocol != null) {
 | 
			
		||||
                Protocol.registerProtocol("https", mDefaultHttpsProtocol);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static AdvancedSslSocketFactory getAdvancedSslSocketFactory(Context context) 
 | 
			
		||||
    		throws GeneralSecurityException, IOException {
 | 
			
		||||
        if (mAdvancedSslSocketFactory  == null) {
 | 
			
		||||
            KeyStore trustStore = getKnownServersStore(context);
 | 
			
		||||
            AdvancedX509TrustManager trustMgr = new AdvancedX509TrustManager(trustStore);
 | 
			
		||||
            TrustManager[] tms = new TrustManager[] { trustMgr };
 | 
			
		||||
                
 | 
			
		||||
            SSLContext sslContext;
 | 
			
		||||
            try {
 | 
			
		||||
            	sslContext = SSLContext.getInstance("TLSv1.2");
 | 
			
		||||
            } catch (NoSuchAlgorithmException e) {
 | 
			
		||||
            	Log_OC.w(TAG, "TLSv1.2 is not supported in this device; falling through TLSv1.0");
 | 
			
		||||
            	sslContext = SSLContext.getInstance("TLSv1");
 | 
			
		||||
            	// should be available in any device; see reference of supported protocols in 
 | 
			
		||||
            	// http://developer.android.com/reference/javax/net/ssl/SSLSocket.html
 | 
			
		||||
            }
 | 
			
		||||
            sslContext.init(null, tms, null);
 | 
			
		||||
                    
 | 
			
		||||
            mHostnameVerifier = new BrowserCompatHostnameVerifier();
 | 
			
		||||
            mAdvancedSslSocketFactory = new AdvancedSslSocketFactory(sslContext, trustMgr, mHostnameVerifier);
 | 
			
		||||
        }
 | 
			
		||||
        return mAdvancedSslSocketFactory;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private static String LOCAL_TRUSTSTORE_FILENAME = "knownServers.bks";
 | 
			
		||||
    
 | 
			
		||||
@ -147,7 +81,7 @@ public class NetworkUtils {
 | 
			
		||||
     * @throws CertificateException         When an exception occurred while loading the certificates from the local 
 | 
			
		||||
     * 										trust store.
 | 
			
		||||
     */
 | 
			
		||||
    private static KeyStore getKnownServersStore(Context context) 
 | 
			
		||||
    public static KeyStore getKnownServersStore(Context context)
 | 
			
		||||
    		throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
 | 
			
		||||
        if (mKnownServersStore == null) {
 | 
			
		||||
            //mKnownServersStore = KeyStore.getInstance("BKS");
 | 
			
		||||
@ -183,16 +117,6 @@ public class NetworkUtils {
 | 
			
		||||
            fos.close();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    static public MultiThreadedHttpConnectionManager getMultiThreadedConnManager() {
 | 
			
		||||
        if (mConnManager == null) {
 | 
			
		||||
            mConnManager = new MultiThreadedHttpConnectionManager();
 | 
			
		||||
            mConnManager.getParams().setDefaultMaxConnectionsPerHost(5);
 | 
			
		||||
            mConnManager.getParams().setMaxTotalConnections(5);
 | 
			
		||||
        }
 | 
			
		||||
        return mConnManager;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isCertInKnownServersStore(Certificate cert, Context context) 
 | 
			
		||||
    		throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
 | 
			
		||||
 | 
			
		||||
@ -26,5 +26,5 @@
 | 
			
		||||
package com.owncloud.android.lib.common.network;
 | 
			
		||||
 | 
			
		||||
public interface OnDatatransferProgressListener {
 | 
			
		||||
    public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String fileAbsoluteName);
 | 
			
		||||
}
 | 
			
		||||
    void onTransferProgress(long read, long transferred, long percent, String absolutePath);
 | 
			
		||||
}
 | 
			
		||||
@ -27,7 +27,6 @@ package com.owncloud.android.lib.common.network;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public interface ProgressiveDataTransferer {
 | 
			
		||||
 | 
			
		||||
    public void addDatatransferProgressListener (OnDatatransferProgressListener listener);
 | 
			
		||||
 | 
			
		||||
@ -27,14 +27,16 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common.network;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 com.owncloud.android.lib.common.operations.RemoteOperation}, and the status codes corresponding to all
 | 
			
		||||
 * {@link RemoteOperation}, and the status codes corresponding to all
 | 
			
		||||
 * of them.
 | 
			
		||||
 *
 | 
			
		||||
 * The last status code saved corresponds to the first response not being a redirection, unless the sequence exceeds
 | 
			
		||||
@ -108,7 +110,7 @@ public class RedirectionPath {
 | 
			
		||||
     */
 | 
			
		||||
    public String getLastPermanentLocation() {
 | 
			
		||||
        for (int i = mLastStatus; i >= 0; i--) {
 | 
			
		||||
            if (mStatuses[i] == HttpStatus.SC_MOVED_PERMANENTLY && i <= mLastLocation) {
 | 
			
		||||
            if (mStatuses[i] == HttpConstants.HTTP_MOVED_PERMANENTLY && i <= mLastLocation) {
 | 
			
		||||
                return mLocations[i];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1,276 +0,0 @@
 | 
			
		||||
/** ownCloud Android Library is available under MIT license
 | 
			
		||||
 *
 | 
			
		||||
 *   @author Christian Schabesberger
 | 
			
		||||
 *   Copyright (C) 2018 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 java.math.BigDecimal;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
 | 
			
		||||
import org.apache.jackrabbit.webdav.property.DavProperty;
 | 
			
		||||
import org.apache.jackrabbit.webdav.property.DavPropertyName;
 | 
			
		||||
import org.apache.jackrabbit.webdav.property.DavPropertySet;
 | 
			
		||||
import org.apache.jackrabbit.webdav.xml.Namespace;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
public class WebdavEntry {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = WebdavEntry.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    public static final String NAMESPACE_OC = "http://owncloud.org/ns";
 | 
			
		||||
    public static final String EXTENDED_PROPERTY_NAME_PERMISSIONS = "permissions";
 | 
			
		||||
    public static final String EXTENDED_PROPERTY_NAME_REMOTE_ID = "id";
 | 
			
		||||
    public static final String EXTENDED_PROPERTY_NAME_SIZE = "size";
 | 
			
		||||
    public static final String EXTENDED_PROPERTY_NAME_PRIVATE_LINK = "privatelink";
 | 
			
		||||
 | 
			
		||||
    public static final String PROPERTY_QUOTA_USED_BYTES = "quota-used-bytes";
 | 
			
		||||
    public static final String PROPERTY_QUOTA_AVAILABLE_BYTES = "quota-available-bytes";
 | 
			
		||||
 | 
			
		||||
    private static final int CODE_PROP_NOT_FOUND = 404;
 | 
			
		||||
 | 
			
		||||
    private String mName, mPath, mUri, mContentType, mEtag, mPermissions, mRemoteId, mPrivateLink;
 | 
			
		||||
    private long mContentLength, mCreateTimestamp, mModifiedTimestamp, mSize;
 | 
			
		||||
    private BigDecimal mQuotaUsedBytes, mQuotaAvailableBytes;
 | 
			
		||||
 | 
			
		||||
    public WebdavEntry(MultiStatusResponse ms, String splitElement) {
 | 
			
		||||
        resetData();
 | 
			
		||||
        if (ms.getStatus().length != 0) {
 | 
			
		||||
            mUri = ms.getHref();
 | 
			
		||||
 | 
			
		||||
            mPath = mUri.split(splitElement, 2)[1];
 | 
			
		||||
 | 
			
		||||
            int status = ms.getStatus()[0].getStatusCode();
 | 
			
		||||
            if (status == CODE_PROP_NOT_FOUND) {
 | 
			
		||||
                status = ms.getStatus()[1].getStatusCode();
 | 
			
		||||
            }
 | 
			
		||||
            DavPropertySet propSet = ms.getProperties(status);
 | 
			
		||||
            @SuppressWarnings("rawtypes")
 | 
			
		||||
            DavProperty prop = propSet.get(DavPropertyName.DISPLAYNAME);
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                mName = (String) prop.getName().toString();
 | 
			
		||||
                mName = mName.substring(1, mName.length() - 1);
 | 
			
		||||
            } else {
 | 
			
		||||
                String[] tmp = mPath.split("/");
 | 
			
		||||
                if (tmp.length > 0)
 | 
			
		||||
                    mName = tmp[tmp.length - 1];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // use unknown mimetype as default behavior
 | 
			
		||||
            // {DAV:}getcontenttype
 | 
			
		||||
            mContentType = "application/octet-stream";
 | 
			
		||||
            prop = propSet.get(DavPropertyName.GETCONTENTTYPE);
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                mContentType = (String) prop.getValue();
 | 
			
		||||
                // dvelasco: some builds of ownCloud server 4.0.x added a trailing ';'
 | 
			
		||||
                // to the MIME type ; if looks fixed, but let's be cautious
 | 
			
		||||
                if (mContentType.indexOf(";") >= 0) {
 | 
			
		||||
                    mContentType = mContentType.substring(0, mContentType.indexOf(";"));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // check if it's a folder in the standard way: see RFC2518 12.2 . RFC4918 14.3
 | 
			
		||||
            // {DAV:}resourcetype
 | 
			
		||||
            prop = propSet.get(DavPropertyName.RESOURCETYPE);
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                Object value = prop.getValue();
 | 
			
		||||
                if (value != null) {
 | 
			
		||||
                    mContentType = "DIR";   // a specific attribute would be better,
 | 
			
		||||
                    // but this is enough;
 | 
			
		||||
                    // unless while we have no reason to distinguish
 | 
			
		||||
                    // MIME types for folders
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // {DAV:}getcontentlength
 | 
			
		||||
            prop = propSet.get(DavPropertyName.GETCONTENTLENGTH);
 | 
			
		||||
            if (prop != null)
 | 
			
		||||
                mContentLength = Long.parseLong((String) prop.getValue());
 | 
			
		||||
 | 
			
		||||
            // {DAV:}getlastmodified
 | 
			
		||||
            prop = propSet.get(DavPropertyName.GETLASTMODIFIED);
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                Date d = WebdavUtils
 | 
			
		||||
                    .parseResponseDate((String) prop.getValue());
 | 
			
		||||
                mModifiedTimestamp = (d != null) ? d.getTime() : 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            prop = propSet.get(DavPropertyName.CREATIONDATE);
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                Date d = WebdavUtils
 | 
			
		||||
                    .parseResponseDate((String) prop.getValue());
 | 
			
		||||
                mCreateTimestamp = (d != null) ? d.getTime() : 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // {DAV:}getetag
 | 
			
		||||
            prop = propSet.get(DavPropertyName.GETETAG);
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                mEtag = (String) prop.getValue();
 | 
			
		||||
                mEtag = WebdavUtils.parseEtag(mEtag);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // {DAV:}quota-used-bytes
 | 
			
		||||
            prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_USED_BYTES));
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                String quotaUsedBytesSt = (String) prop.getValue();
 | 
			
		||||
                try {
 | 
			
		||||
                    mQuotaUsedBytes = new BigDecimal(quotaUsedBytesSt);
 | 
			
		||||
                } catch (NumberFormatException e) {
 | 
			
		||||
                    Log_OC.w(TAG, "No value for QuotaUsedBytes - NumberFormatException");
 | 
			
		||||
                } catch (NullPointerException e) {
 | 
			
		||||
                    Log_OC.w(TAG, "No value for QuotaUsedBytes - NullPointerException");
 | 
			
		||||
                }
 | 
			
		||||
                Log_OC.d(TAG, "QUOTA_USED_BYTES " + quotaUsedBytesSt);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // {DAV:}quota-available-bytes
 | 
			
		||||
            prop = propSet.get(DavPropertyName.create(PROPERTY_QUOTA_AVAILABLE_BYTES));
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                String quotaAvailableBytesSt = (String) prop.getValue();
 | 
			
		||||
                try {
 | 
			
		||||
                    mQuotaAvailableBytes = new BigDecimal(quotaAvailableBytesSt);
 | 
			
		||||
                } catch (NumberFormatException e) {
 | 
			
		||||
                    Log_OC.w(TAG, "No value for QuotaAvailableBytes - NumberFormatException");
 | 
			
		||||
                } catch (NullPointerException e) {
 | 
			
		||||
                    Log_OC.w(TAG, "No value for QuotaAvailableBytes");
 | 
			
		||||
                }
 | 
			
		||||
                Log_OC.d(TAG, "QUOTA_AVAILABLE_BYTES " + quotaAvailableBytesSt);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // OC permissions property <oc:permissions>
 | 
			
		||||
            prop = propSet.get(
 | 
			
		||||
                EXTENDED_PROPERTY_NAME_PERMISSIONS, Namespace.getNamespace(NAMESPACE_OC)
 | 
			
		||||
            );
 | 
			
		||||
            if (prop != null && prop.getValue() != null) {
 | 
			
		||||
                mPermissions = prop.getValue().toString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // OC remote id property <oc:id>
 | 
			
		||||
            prop = propSet.get(
 | 
			
		||||
                EXTENDED_PROPERTY_NAME_REMOTE_ID, Namespace.getNamespace(NAMESPACE_OC)
 | 
			
		||||
            );
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                mRemoteId = prop.getValue().toString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // OC size property <oc:size>
 | 
			
		||||
            prop = propSet.get(
 | 
			
		||||
                EXTENDED_PROPERTY_NAME_SIZE, Namespace.getNamespace(NAMESPACE_OC)
 | 
			
		||||
            );
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                mSize = Long.parseLong((String) prop.getValue());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // OC privatelink property <oc:privatelink>
 | 
			
		||||
            prop = propSet.get(
 | 
			
		||||
                EXTENDED_PROPERTY_NAME_PRIVATE_LINK, Namespace.getNamespace(NAMESPACE_OC)
 | 
			
		||||
            );
 | 
			
		||||
            if (prop != null) {
 | 
			
		||||
                mPrivateLink = prop.getValue().toString();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            Log_OC.e("WebdavEntry",
 | 
			
		||||
                "General fuckup, no status for webdav response");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String path() {
 | 
			
		||||
        return mPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String decodedPath() {
 | 
			
		||||
        return Uri.decode(mPath);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String name() {
 | 
			
		||||
        return mName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isDirectory() {
 | 
			
		||||
        return mContentType.equals("DIR");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String contentType() {
 | 
			
		||||
        return mContentType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String uri() {
 | 
			
		||||
        return mUri;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long contentLength() {
 | 
			
		||||
        return mContentLength;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long createTimestamp() {
 | 
			
		||||
        return mCreateTimestamp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long modifiedTimestamp() {
 | 
			
		||||
        return mModifiedTimestamp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String etag() {
 | 
			
		||||
        return mEtag;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String permissions() {
 | 
			
		||||
        return mPermissions;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String remoteId() {
 | 
			
		||||
        return mRemoteId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public long size() {
 | 
			
		||||
        return mSize;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BigDecimal quotaUsedBytes() {
 | 
			
		||||
        return mQuotaUsedBytes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BigDecimal quotaAvailableBytes() {
 | 
			
		||||
        return mQuotaAvailableBytes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String privateLink() {
 | 
			
		||||
        return mPrivateLink;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void resetData() {
 | 
			
		||||
        mName = mUri = mContentType = mPermissions = null;
 | 
			
		||||
        mRemoteId = null;
 | 
			
		||||
        mContentLength = mCreateTimestamp = mModifiedTimestamp = 0;
 | 
			
		||||
        mSize = 0;
 | 
			
		||||
        mQuotaUsedBytes = null;
 | 
			
		||||
        mQuotaAvailableBytes = null;
 | 
			
		||||
        mPrivateLink = null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -32,11 +32,7 @@ import java.util.Locale;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Header;
 | 
			
		||||
import org.apache.commons.httpclient.HttpMethod;
 | 
			
		||||
import org.apache.jackrabbit.webdav.property.DavPropertyName;
 | 
			
		||||
import org.apache.jackrabbit.webdav.property.DavPropertyNameSet;
 | 
			
		||||
import org.apache.jackrabbit.webdav.xml.Namespace;
 | 
			
		||||
import com.owncloud.android.lib.common.http.methods.HttpBaseMethod;
 | 
			
		||||
 | 
			
		||||
public class WebdavUtils {
 | 
			
		||||
    public static final SimpleDateFormat DISPLAY_DATE_FORMAT = new SimpleDateFormat(
 | 
			
		||||
@ -85,72 +81,6 @@ public class WebdavUtils {
 | 
			
		||||
        return encodedPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Builds a DavPropertyNameSet with all prop
 | 
			
		||||
     * For using instead of DavConstants.PROPFIND_ALL_PROP
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static DavPropertyNameSet getAllPropSet(){
 | 
			
		||||
        DavPropertyNameSet propSet = new DavPropertyNameSet();
 | 
			
		||||
        propSet.add(DavPropertyName.DISPLAYNAME);
 | 
			
		||||
        propSet.add(DavPropertyName.GETCONTENTTYPE);
 | 
			
		||||
        propSet.add(DavPropertyName.RESOURCETYPE);
 | 
			
		||||
        propSet.add(DavPropertyName.GETCONTENTLENGTH);
 | 
			
		||||
        propSet.add(DavPropertyName.GETLASTMODIFIED);
 | 
			
		||||
        propSet.add(DavPropertyName.CREATIONDATE);
 | 
			
		||||
        propSet.add(DavPropertyName.GETETAG);
 | 
			
		||||
        propSet.add(DavPropertyName.create(WebdavEntry.PROPERTY_QUOTA_USED_BYTES));
 | 
			
		||||
        propSet.add(DavPropertyName.create(WebdavEntry.PROPERTY_QUOTA_AVAILABLE_BYTES));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PERMISSIONS,
 | 
			
		||||
                Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_REMOTE_ID,
 | 
			
		||||
                Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE,
 | 
			
		||||
                Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PRIVATE_LINK,
 | 
			
		||||
            Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
 | 
			
		||||
        return propSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Builds a DavPropertyNameSet with properties for files
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public static DavPropertyNameSet getFilePropSet(){
 | 
			
		||||
        DavPropertyNameSet propSet = new DavPropertyNameSet();
 | 
			
		||||
        propSet.add(DavPropertyName.DISPLAYNAME);
 | 
			
		||||
        propSet.add(DavPropertyName.GETCONTENTTYPE);
 | 
			
		||||
        propSet.add(DavPropertyName.RESOURCETYPE);
 | 
			
		||||
        propSet.add(DavPropertyName.GETCONTENTLENGTH);
 | 
			
		||||
        propSet.add(DavPropertyName.GETLASTMODIFIED);
 | 
			
		||||
        propSet.add(DavPropertyName.CREATIONDATE);
 | 
			
		||||
        propSet.add(DavPropertyName.GETETAG);
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PERMISSIONS,
 | 
			
		||||
                Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_REMOTE_ID,
 | 
			
		||||
                Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE,
 | 
			
		||||
                Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_SIZE,
 | 
			
		||||
            Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
        propSet.add(WebdavEntry.EXTENDED_PROPERTY_NAME_PRIVATE_LINK,
 | 
			
		||||
            Namespace.getNamespace(WebdavEntry.NAMESPACE_OC));
 | 
			
		||||
 | 
			
		||||
        return propSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Builds a DavPropertyNameSet with properties for user quotas
 | 
			
		||||
     * @return set of quota properties
 | 
			
		||||
     */
 | 
			
		||||
    public static DavPropertyNameSet getQuotaPropSet() {
 | 
			
		||||
        DavPropertyNameSet propSet = new DavPropertyNameSet();
 | 
			
		||||
        propSet.add(DavPropertyName.create(WebdavEntry.PROPERTY_QUOTA_AVAILABLE_BYTES));
 | 
			
		||||
        propSet.add(DavPropertyName.create(WebdavEntry.PROPERTY_QUOTA_USED_BYTES));
 | 
			
		||||
        return propSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @param rawEtag
 | 
			
		||||
@ -169,28 +99,26 @@ public class WebdavUtils {
 | 
			
		||||
        return rawEtag;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @param method
 | 
			
		||||
     * @return
 | 
			
		||||
     * @param httpBaseMethod from which to get the etag
 | 
			
		||||
     * @return etag from response
 | 
			
		||||
     */
 | 
			
		||||
    public static String getEtagFromResponse(HttpMethod method) {
 | 
			
		||||
        Header eTag = method.getResponseHeader("OC-ETag");
 | 
			
		||||
    public static String getEtagFromResponse(HttpBaseMethod httpBaseMethod) {
 | 
			
		||||
        String eTag = httpBaseMethod.getResponseHeader("OC-ETag");
 | 
			
		||||
        if (eTag == null) {
 | 
			
		||||
            eTag = method.getResponseHeader("oc-etag");
 | 
			
		||||
            eTag = httpBaseMethod.getResponseHeader("oc-etag");
 | 
			
		||||
        }
 | 
			
		||||
        if (eTag == null) {
 | 
			
		||||
            eTag = method.getResponseHeader("ETag");
 | 
			
		||||
            eTag = httpBaseMethod.getResponseHeader("ETag");
 | 
			
		||||
        }
 | 
			
		||||
        if (eTag == null) {
 | 
			
		||||
            eTag = method.getResponseHeader("etag");
 | 
			
		||||
            eTag = httpBaseMethod.getResponseHeader("etag");
 | 
			
		||||
        }
 | 
			
		||||
        String result = "";
 | 
			
		||||
        if (eTag != null) {
 | 
			
		||||
            result = parseEtag(eTag.getValue());
 | 
			
		||||
            result = eTag;
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,27 +1,3 @@
 | 
			
		||||
/* 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.accounts.Account;
 | 
			
		||||
@ -39,16 +15,9 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import okhttp3.OkHttpClient;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Operation which execution involves one or several interactions with an ownCloud server.
 | 
			
		||||
 *
 | 
			
		||||
 * Provides methods to execute the operation both synchronously or asynchronously.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public abstract class RemoteOperation implements Runnable {
 | 
			
		||||
public abstract class RemoteOperation<T extends Object> implements Runnable {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = RemoteOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -65,82 +34,32 @@ public abstract class RemoteOperation implements Runnable {
 | 
			
		||||
    /**
 | 
			
		||||
     * ownCloud account in the remote ownCloud server to operate
 | 
			
		||||
     */
 | 
			
		||||
    private Account mAccount = null;
 | 
			
		||||
    protected Account mAccount = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Android Application context
 | 
			
		||||
     */
 | 
			
		||||
    private Context mContext = null;
 | 
			
		||||
    protected Context mContext = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Object to interact with the remote server
 | 
			
		||||
     */
 | 
			
		||||
    private OwnCloudClient mClient = null;
 | 
			
		||||
    protected OwnCloudClient mClient = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Object to interact with the remote server
 | 
			
		||||
     */
 | 
			
		||||
    protected OkHttpClient mHttpClient = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Callback object to notify about the execution of the remote operation
 | 
			
		||||
     */
 | 
			
		||||
    private OnRemoteOperationListener mListener = null;
 | 
			
		||||
    protected OnRemoteOperationListener mListener = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Handler to the thread where mListener methods will be called
 | 
			
		||||
     */
 | 
			
		||||
    private Handler mListenerHandler = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Abstract method to implement the operation in derived classes.
 | 
			
		||||
     */
 | 
			
		||||
    protected abstract RemoteOperationResult run(OwnCloudClient client);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Synchronously executes the remote operation on the received ownCloud account.
 | 
			
		||||
     *
 | 
			
		||||
     * Do not call this method from the main thread.
 | 
			
		||||
     *
 | 
			
		||||
     * 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 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
 | 
			
		||||
     *
 | 
			
		||||
     * 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 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();
 | 
			
		||||
    }
 | 
			
		||||
    protected Handler mListenerHandler = null;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -219,6 +138,126 @@ public abstract class RemoteOperation implements Runnable {
 | 
			
		||||
        return runnerThread;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected void grantOwnCloudClient() throws
 | 
			
		||||
            AccountUtils.AccountNotFoundException, OperationCanceledException, AuthenticatorException, IOException {
 | 
			
		||||
        if (mClient == null) {
 | 
			
		||||
            if (mAccount != null && mContext != null) {
 | 
			
		||||
                OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
 | 
			
		||||
                mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
 | 
			
		||||
                        getClientFor(ocAccount, mContext);
 | 
			
		||||
            } 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.
 | 
			
		||||
     *
 | 
			
		||||
     * Do not call this method from the main thread.
 | 
			
		||||
     *
 | 
			
		||||
     * 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
 | 
			
		||||
     *
 | 
			
		||||
     * 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
 | 
			
		||||
     *
 | 
			
		||||
     * 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.
 | 
			
		||||
     *
 | 
			
		||||
     * Considers and performs silent refresh of account credentials if possible, and if
 | 
			
		||||
     * {@link RemoteOperation#setSilentRefreshOfAccountCredentials(boolean)} was called with
 | 
			
		||||
     * parameter 'true' before the execution.
 | 
			
		||||
     *
 | 
			
		||||
     * @return      Remote operation result
 | 
			
		||||
     */
 | 
			
		||||
    private RemoteOperationResult<T> runOperation() {
 | 
			
		||||
 | 
			
		||||
        RemoteOperationResult<T> result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            grantOwnCloudClient();
 | 
			
		||||
            result = run(mClient);
 | 
			
		||||
 | 
			
		||||
        } catch (AccountsException | IOException e) {
 | 
			
		||||
            Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Asynchronous execution of the operation
 | 
			
		||||
@ -237,65 +276,10 @@ public abstract class RemoteOperation implements Runnable {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mListenerHandler != null && mListener != null) {
 | 
			
		||||
            mListenerHandler.post(new Runnable() {
 | 
			
		||||
                @Override
 | 
			
		||||
                public void run() {
 | 
			
		||||
                    mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            mListenerHandler.post(() ->
 | 
			
		||||
                    mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend));
 | 
			
		||||
        } else if (mListener != null) {
 | 
			
		||||
            mListener.onRemoteOperationFinish(RemoteOperation.this, resultToSend);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Run operation for asynchronous or synchronous 'execute' method.
 | 
			
		||||
     *
 | 
			
		||||
     * Considers and performs silent refresh of account credentials if possible, and if
 | 
			
		||||
     * {@link RemoteOperation#setSilentRefreshOfAccountCredentials(boolean)} was called with
 | 
			
		||||
     * parameter 'true' before the execution.
 | 
			
		||||
     *
 | 
			
		||||
     * @return      Remote operation result
 | 
			
		||||
     */
 | 
			
		||||
    private RemoteOperationResult runOperation() {
 | 
			
		||||
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            grantOwnCloudClient();
 | 
			
		||||
            result = run(mClient);
 | 
			
		||||
 | 
			
		||||
        } catch (AccountsException | IOException e) {
 | 
			
		||||
            Log_OC.e(TAG, "Error while trying to access to " + mAccount.name, e);
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private void grantOwnCloudClient() throws
 | 
			
		||||
        AccountUtils.AccountNotFoundException, OperationCanceledException, AuthenticatorException, IOException {
 | 
			
		||||
        if (mClient == null) {
 | 
			
		||||
            if (mAccount != null && mContext != null) {
 | 
			
		||||
                OwnCloudAccount ocAccount = new OwnCloudAccount(mAccount, mContext);
 | 
			
		||||
                mClient = OwnCloudClientManagerFactory.getDefaultSingleton().
 | 
			
		||||
                    getClientFor(ocAccount, mContext);
 | 
			
		||||
 | 
			
		||||
            } 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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -24,6 +24,17 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.common.operations;
 | 
			
		||||
 | 
			
		||||
import android.accounts.Account;
 | 
			
		||||
import android.accounts.AccountsException;
 | 
			
		||||
 | 
			
		||||
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 com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.FileNotFoundException;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
@ -34,35 +45,18 @@ import java.net.SocketException;
 | 
			
		||||
import java.net.SocketTimeoutException;
 | 
			
		||||
import java.net.UnknownHostException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import android.accounts.Account;
 | 
			
		||||
import android.accounts.AccountsException;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
 | 
			
		||||
import com.owncloud.android.lib.common.network.CertificateCombinedException;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.ConnectTimeoutException;
 | 
			
		||||
import org.apache.commons.httpclient.Header;
 | 
			
		||||
import org.apache.commons.httpclient.HttpException;
 | 
			
		||||
import org.apache.commons.httpclient.HttpMethod;
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.DavException;
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.net.ssl.SSLException;
 | 
			
		||||
import javax.net.ssl.SSLPeerUnverifiedException;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.exception.DavException;
 | 
			
		||||
import at.bitfire.dav4android.exception.HttpException;
 | 
			
		||||
import okhttp3.Headers;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The result of a remote operation required to an ownCloud server.
 | 
			
		||||
 *
 | 
			
		||||
 * Provides a common classification of remote operation results for all the
 | 
			
		||||
 * application.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class RemoteOperationResult implements Serializable {
 | 
			
		||||
public class RemoteOperationResult<T extends Object>
 | 
			
		||||
        implements Serializable {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Generated - should be refreshed every time the class changes!!
 | 
			
		||||
@ -121,7 +115,8 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
        LOCAL_FILE_NOT_FOUND,
 | 
			
		||||
        SERVICE_UNAVAILABLE,
 | 
			
		||||
        SPECIFIC_SERVICE_UNAVAILABLE,
 | 
			
		||||
        SPECIFIC_UNSUPPORTED_MEDIA_TYPE
 | 
			
		||||
        SPECIFIC_UNSUPPORTED_MEDIA_TYPE,
 | 
			
		||||
        SPECIFIC_METHOD_NOT_ALLOWED
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean mSuccess = false;
 | 
			
		||||
@ -132,8 +127,7 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
    private String mRedirectedLocation;
 | 
			
		||||
    private ArrayList<String> mAuthenticate = new ArrayList<>();
 | 
			
		||||
    private String mLastPermanentLocation = null;
 | 
			
		||||
 | 
			
		||||
    private ArrayList<Object> mData;
 | 
			
		||||
    private T mData = null;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Public constructor from result code.
 | 
			
		||||
@ -147,7 +141,22 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
        mSuccess = (code == ResultCode.OK || code == ResultCode.OK_SSL ||
 | 
			
		||||
                code == ResultCode.OK_NO_SSL ||
 | 
			
		||||
                code == ResultCode.OK_REDIRECT_TO_NON_SECURE_CONNECTION);
 | 
			
		||||
        mData = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -171,33 +180,34 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
        } else if (e instanceof SocketTimeoutException) {
 | 
			
		||||
            mCode = ResultCode.TIMEOUT;
 | 
			
		||||
 | 
			
		||||
        } else if (e instanceof ConnectTimeoutException) {
 | 
			
		||||
            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 AccountNotFoundException) {
 | 
			
		||||
        } 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) {
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
            if(e instanceof SSLPeerUnverifiedException) {
 | 
			
		||||
                mCode = ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED;
 | 
			
		||||
            } else {
 | 
			
		||||
                mCode = ResultCode.SSL_ERROR;
 | 
			
		||||
                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) {
 | 
			
		||||
@ -206,7 +216,6 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
        } else {
 | 
			
		||||
            mCode = ResultCode.UNKNOWN_ERROR;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -216,25 +225,21 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
     *
 | 
			
		||||
     * 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.
 | 
			
		||||
     * response body
 | 
			
		||||
     *
 | 
			
		||||
     * @param success    The operation was considered successful or not.
 | 
			
		||||
     * @param httpMethod HTTP/DAV method already executed which response will be examined to interpret the
 | 
			
		||||
     *                   result.
 | 
			
		||||
     * @param httpMethod
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     */
 | 
			
		||||
    public RemoteOperationResult(boolean success, HttpMethod httpMethod) throws IOException {
 | 
			
		||||
        this(
 | 
			
		||||
                success,
 | 
			
		||||
                httpMethod.getStatusCode(),
 | 
			
		||||
                httpMethod.getStatusText(),
 | 
			
		||||
    public RemoteOperationResult(HttpBaseMethod httpMethod) throws IOException {
 | 
			
		||||
        this(httpMethod.getStatusCode(),
 | 
			
		||||
                httpMethod.getStatusMessage(),
 | 
			
		||||
                httpMethod.getResponseHeaders()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        if (mHttpCode == HttpStatus.SC_BAD_REQUEST) {   // 400
 | 
			
		||||
 | 
			
		||||
        if (mHttpCode == HttpConstants.HTTP_BAD_REQUEST) {   // 400
 | 
			
		||||
            String bodyResponse = httpMethod.getResponseBodyAsString();
 | 
			
		||||
            // do not get for other HTTP codes!; could not be available
 | 
			
		||||
 | 
			
		||||
            // 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();
 | 
			
		||||
@ -250,34 +255,45 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mHttpCode == HttpStatus.SC_FORBIDDEN) {  // 403
 | 
			
		||||
 | 
			
		||||
            parseErrorMessageAndSetCode(httpMethod, ResultCode.SPECIFIC_FORBIDDEN);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mHttpCode == HttpStatus.SC_UNSUPPORTED_MEDIA_TYPE) {    // 415
 | 
			
		||||
 | 
			
		||||
            parseErrorMessageAndSetCode(httpMethod, ResultCode.SPECIFIC_UNSUPPORTED_MEDIA_TYPE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mHttpCode == HttpStatus.SC_SERVICE_UNAVAILABLE) {   // 503
 | 
			
		||||
 | 
			
		||||
            parseErrorMessageAndSetCode(httpMethod, ResultCode.SPECIFIC_SERVICE_UNAVAILABLE);
 | 
			
		||||
        // 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
 | 
			
		||||
                );
 | 
			
		||||
            default:
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Parse the error message included in the body response, if any, and set the specific result
 | 
			
		||||
     * code
 | 
			
		||||
     * @param httpMethod HTTP/DAV method already executed which response body will be parsed to get
 | 
			
		||||
     *                   the specific error message
 | 
			
		||||
     * @param resultCode specific result code
 | 
			
		||||
     *
 | 
			
		||||
     * @param bodyResponse okHttp response body
 | 
			
		||||
     * @param resultCode our own custom result code
 | 
			
		||||
     * @throws IOException
 | 
			
		||||
     */
 | 
			
		||||
    private void parseErrorMessageAndSetCode(HttpMethod httpMethod, ResultCode resultCode)
 | 
			
		||||
            throws IOException {
 | 
			
		||||
 | 
			
		||||
        String bodyResponse = httpMethod.getResponseBodyAsString();
 | 
			
		||||
    private void parseErrorMessageAndSetCode(String bodyResponse, ResultCode resultCode) {
 | 
			
		||||
 | 
			
		||||
        if (bodyResponse != null && bodyResponse.length() > 0) {
 | 
			
		||||
            InputStream is = new ByteArrayInputStream(bodyResponse.getBytes());
 | 
			
		||||
@ -301,31 +317,29 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
     * 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).
 | 
			
		||||
     *
 | 
			
		||||
     * If all the fields come from the same HTTP/DAV response, {@link #RemoteOperationResult(boolean, HttpMethod)}
 | 
			
		||||
     * should be used instead.
 | 
			
		||||
     *
 | 
			
		||||
     * Determines a {@link ResultCode} depending on the HTTP code and HTTP response headers received.
 | 
			
		||||
     *
 | 
			
		||||
     * @param success     The operation was considered successful or not.
 | 
			
		||||
     * @param httpCode    HTTP status code returned by an HTTP/DAV method.
 | 
			
		||||
     * @param httpPhrase  HTTP status line phrase returned by an HTTP/DAV method
 | 
			
		||||
     * @param httpHeaders HTTP response header returned by an HTTP/DAV method
 | 
			
		||||
     * @param headers HTTP response header returned by an HTTP/DAV method
 | 
			
		||||
     */
 | 
			
		||||
    public RemoteOperationResult(boolean success, int httpCode, String httpPhrase, Header[] httpHeaders) {
 | 
			
		||||
        this(success, httpCode, httpPhrase);
 | 
			
		||||
        if (httpHeaders != null) {
 | 
			
		||||
            for (Header httpHeader : httpHeaders) {
 | 
			
		||||
                if ("location".equals(httpHeader.getName().toLowerCase())) {
 | 
			
		||||
                    mRedirectedLocation = httpHeader.getValue();
 | 
			
		||||
    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".equals(header.getKey().toLowerCase())) {
 | 
			
		||||
                    mRedirectedLocation = header.getValue().get(0);
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if ("www-authenticate".equals(httpHeader.getName().toLowerCase())) {
 | 
			
		||||
                    mAuthenticate.add(httpHeader.getValue().toLowerCase());
 | 
			
		||||
                if ("www-authenticate".equals(header.getKey().toLowerCase())) {
 | 
			
		||||
                    mAuthenticate.add(header.getValue().get(0).toLowerCase());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (isIdPRedirection()) {
 | 
			
		||||
            mCode = ResultCode.UNAUTHORIZED;    // overrides default ResultCode.UNKNOWN
 | 
			
		||||
            // overrides default ResultCode.UNKNOWN
 | 
			
		||||
            mCode = ResultCode.UNAUTHORIZED;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -334,58 +348,47 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
     *
 | 
			
		||||
     * Determines a {@link ResultCode} depending of the type of the exception.
 | 
			
		||||
     *
 | 
			
		||||
     * @param success    Operation was successful or not.
 | 
			
		||||
     * @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(boolean success, int httpCode, String httpPhrase) {
 | 
			
		||||
        mSuccess = success;
 | 
			
		||||
    private RemoteOperationResult(int httpCode, String httpPhrase) {
 | 
			
		||||
        mHttpCode = httpCode;
 | 
			
		||||
        mHttpPhrase = httpPhrase;
 | 
			
		||||
 | 
			
		||||
        if (success) {
 | 
			
		||||
            mCode = ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
        } else if (httpCode > 0) {
 | 
			
		||||
        if (httpCode > 0) {
 | 
			
		||||
            switch (httpCode) {
 | 
			
		||||
                case HttpStatus.SC_UNAUTHORIZED:                    // 401
 | 
			
		||||
                case HttpConstants.HTTP_UNAUTHORIZED:                    // 401
 | 
			
		||||
                    mCode = ResultCode.UNAUTHORIZED;
 | 
			
		||||
                    break;
 | 
			
		||||
                case HttpStatus.SC_FORBIDDEN:                       // 403
 | 
			
		||||
                case HttpConstants.HTTP_FORBIDDEN:                       // 403
 | 
			
		||||
                    mCode = ResultCode.FORBIDDEN;
 | 
			
		||||
                    break;
 | 
			
		||||
                case HttpStatus.SC_NOT_FOUND:                       // 404
 | 
			
		||||
                case HttpConstants.HTTP_NOT_FOUND:                       // 404
 | 
			
		||||
                    mCode = ResultCode.FILE_NOT_FOUND;
 | 
			
		||||
                    break;
 | 
			
		||||
                case HttpStatus.SC_CONFLICT:                        // 409
 | 
			
		||||
                case HttpConstants.HTTP_CONFLICT:                        // 409
 | 
			
		||||
                    mCode = ResultCode.CONFLICT;
 | 
			
		||||
                    break;
 | 
			
		||||
                case HttpStatus.SC_INTERNAL_SERVER_ERROR:           // 500
 | 
			
		||||
                case HttpConstants.HTTP_INTERNAL_SERVER_ERROR:           // 500
 | 
			
		||||
                    mCode = ResultCode.INSTANCE_NOT_CONFIGURED;     // assuming too much...
 | 
			
		||||
                    break;
 | 
			
		||||
                case HttpStatus.SC_SERVICE_UNAVAILABLE:             // 503
 | 
			
		||||
                case HttpConstants.HTTP_SERVICE_UNAVAILABLE:             // 503
 | 
			
		||||
                    mCode = ResultCode.SERVICE_UNAVAILABLE;
 | 
			
		||||
                    break;
 | 
			
		||||
                case HttpStatus.SC_INSUFFICIENT_STORAGE:            // 507
 | 
			
		||||
                case HttpConstants.HTTP_INSUFFICIENT_STORAGE:            // 507
 | 
			
		||||
                    mCode = ResultCode.QUOTA_EXCEEDED;              // surprise!
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    mCode = ResultCode.UNHANDLED_HTTP_CODE;         // UNKNOWN ERROR
 | 
			
		||||
                    Log_OC.d(TAG,
 | 
			
		||||
                            "RemoteOperationResult has processed UNHANDLED_HTTP_CODE: " +
 | 
			
		||||
 | 
			
		||||
                                    mHttpCode + " " + mHttpPhrase
 | 
			
		||||
                    );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setData(ArrayList<Object> items) {
 | 
			
		||||
        mData = items;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<Object> getData() {
 | 
			
		||||
        return mData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isSuccess() {
 | 
			
		||||
        return mSuccess;
 | 
			
		||||
@ -449,9 +452,6 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
            } else if (mException instanceof SocketTimeoutException) {
 | 
			
		||||
                return "Socket timeout exception";
 | 
			
		||||
 | 
			
		||||
            } else if (mException instanceof ConnectTimeoutException) {
 | 
			
		||||
                return "Connect timeout exception";
 | 
			
		||||
 | 
			
		||||
            } else if (mException instanceof MalformedURLException) {
 | 
			
		||||
                return "Malformed URL exception";
 | 
			
		||||
 | 
			
		||||
@ -476,9 +476,9 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
            } else if (mException instanceof IOException) {
 | 
			
		||||
                return "Unrecovered transport exception";
 | 
			
		||||
 | 
			
		||||
            } else if (mException instanceof AccountNotFoundException) {
 | 
			
		||||
            } else if (mException instanceof AccountUtils.AccountNotFoundException) {
 | 
			
		||||
                Account failedAccount =
 | 
			
		||||
                        ((AccountNotFoundException) mException).getFailedAccount();
 | 
			
		||||
                        ((AccountUtils.AccountNotFoundException) mException).getFailedAccount();
 | 
			
		||||
                return mException.getMessage() + " (" +
 | 
			
		||||
                        (failedAccount != null ? failedAccount.name : "NULL") + ")";
 | 
			
		||||
 | 
			
		||||
@ -530,7 +530,7 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isServerFail() {
 | 
			
		||||
        return (mHttpCode >= HttpStatus.SC_INTERNAL_SERVER_ERROR);
 | 
			
		||||
        return (mHttpCode >= HttpConstants.HTTP_INTERNAL_SERVER_ERROR);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isException() {
 | 
			
		||||
@ -572,4 +572,15 @@ public class RemoteOperationResult implements Serializable {
 | 
			
		||||
        mLastPermanentLocation = lastPermanentLocation;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
    public void setSuccess(boolean success) {
 | 
			
		||||
        this.mSuccess = success;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setData(T data) {
 | 
			
		||||
        mData = data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public T getData() {
 | 
			
		||||
        return mData;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
package com.owncloud.android.lib.common.utils;
 | 
			
		||||
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedWriter;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileWriter;
 | 
			
		||||
@ -7,10 +9,6 @@ import java.io.IOException;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
 | 
			
		||||
import android.os.Environment;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class Log_OC {
 | 
			
		||||
    private static final String SIMPLE_DATE_FORMAT = "yyyy/MM/dd HH:mm:ss";
 | 
			
		||||
    private static final String LOG_FOLDER_NAME = "log";
 | 
			
		||||
@ -63,11 +61,6 @@ public class Log_OC {
 | 
			
		||||
        Log.w(TAG, message);
 | 
			
		||||
        appendLog(TAG+" : "+ message);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    public static void wtf(String TAG, String message) {
 | 
			
		||||
        Log.wtf(TAG, message);
 | 
			
		||||
        appendLog(TAG+" : "+ message);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start doing logging
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										71
									
								
								src/com/owncloud/android/lib/common/utils/RandomUtils.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/com/owncloud/android/lib/common/utils/RandomUtils.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,151 +0,0 @@
 | 
			
		||||
/* 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 java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.RandomAccessFile;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.methods.PutMethod;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.network.ChunkFromFileChannelRequestEntity;
 | 
			
		||||
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
 | 
			
		||||
import com.owncloud.android.lib.common.network.WebdavUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation {
 | 
			
		||||
 | 
			
		||||
    private static final int LAST_CHUNK_TIMEOUT = 900000; //15 mins.
 | 
			
		||||
 | 
			
		||||
    public static final long CHUNK_SIZE = 1024000;
 | 
			
		||||
    private static final String OC_CHUNKED_HEADER = "OC-Chunked";
 | 
			
		||||
    private static final String OC_CHUNK_SIZE_HEADER = "OC-Chunk-Size";
 | 
			
		||||
    private static final String OC_CHUNK_X_OC_MTIME_HEADER = "X-OC-Mtime";
 | 
			
		||||
    private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    public ChunkedUploadRemoteFileOperation(String storagePath, String remotePath, String mimeType,
 | 
			
		||||
                                            String fileLastModifTimestamp) {
 | 
			
		||||
        super(storagePath, remotePath, mimeType, fileLastModifTimestamp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ChunkedUploadRemoteFileOperation(
 | 
			
		||||
        String storagePath, String remotePath, String mimeType, String requiredEtag,
 | 
			
		||||
        String fileLastModifTimestamp
 | 
			
		||||
    ) {
 | 
			
		||||
        super(storagePath, remotePath, mimeType, requiredEtag, fileLastModifTimestamp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOException {
 | 
			
		||||
        int status = -1;
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
 | 
			
		||||
        FileChannel channel = null;
 | 
			
		||||
        RandomAccessFile raf = null;
 | 
			
		||||
        try {
 | 
			
		||||
            File file = new File(mLocalPath);
 | 
			
		||||
            raf = new RandomAccessFile(file, "r");
 | 
			
		||||
            channel = raf.getChannel();
 | 
			
		||||
            mEntity = new ChunkFromFileChannelRequestEntity(channel, mMimeType, CHUNK_SIZE, file);
 | 
			
		||||
            synchronized (mDataTransferListeners) {
 | 
			
		||||
                ((ProgressiveDataTransferer) mEntity)
 | 
			
		||||
                    .addDatatransferProgressListeners(mDataTransferListeners);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            long offset = 0;
 | 
			
		||||
            String uriPrefix = client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath) +
 | 
			
		||||
                "-chunking-" + Math.abs((new Random()).nextInt(9000) + 1000) + "-";
 | 
			
		||||
            long totalLength = file.length();
 | 
			
		||||
            long chunkCount = (long) Math.ceil((double) totalLength / CHUNK_SIZE);
 | 
			
		||||
            String chunkSizeStr = String.valueOf(CHUNK_SIZE);
 | 
			
		||||
            String totalLengthStr = String.valueOf(file.length());
 | 
			
		||||
            for (int chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++, offset += CHUNK_SIZE) {
 | 
			
		||||
                if (chunkIndex == chunkCount - 1) {
 | 
			
		||||
                    chunkSizeStr = String.valueOf(CHUNK_SIZE * chunkCount - totalLength);
 | 
			
		||||
                }
 | 
			
		||||
                if (mPutMethod != null) {
 | 
			
		||||
                    mPutMethod.releaseConnection();     // let the connection available
 | 
			
		||||
                    // for other methods
 | 
			
		||||
                }
 | 
			
		||||
                mPutMethod = new PutMethod(uriPrefix + chunkCount + "-" + chunkIndex);
 | 
			
		||||
                if (mRequiredEtag != null && mRequiredEtag.length() > 0) {
 | 
			
		||||
                    mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\"");
 | 
			
		||||
                }
 | 
			
		||||
                mPutMethod.addRequestHeader(OC_CHUNKED_HEADER, OC_CHUNKED_HEADER);
 | 
			
		||||
                mPutMethod.addRequestHeader(OC_CHUNK_SIZE_HEADER, chunkSizeStr);
 | 
			
		||||
                mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, totalLengthStr);
 | 
			
		||||
 | 
			
		||||
                mPutMethod.addRequestHeader(OC_CHUNK_X_OC_MTIME_HEADER, mFileLastModifTimestamp);
 | 
			
		||||
 | 
			
		||||
                ((ChunkFromFileChannelRequestEntity) mEntity).setOffset(offset);
 | 
			
		||||
                mPutMethod.setRequestEntity(mEntity);
 | 
			
		||||
                if (mCancellationRequested.get()) {
 | 
			
		||||
                    mPutMethod.abort();
 | 
			
		||||
                    // next method will throw an exception
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (chunkIndex == chunkCount - 1) {
 | 
			
		||||
                    // Added a high timeout to the last chunk due to when the last chunk
 | 
			
		||||
                    // arrives to the server with the last PUT, all chunks get assembled
 | 
			
		||||
                    // within that PHP request, so last one takes longer.
 | 
			
		||||
                    mPutMethod.getParams().setSoTimeout(LAST_CHUNK_TIMEOUT);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                status = client.executeMethod(mPutMethod);
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult(
 | 
			
		||||
                    isSuccess(status),
 | 
			
		||||
                    mPutMethod
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
 | 
			
		||||
                Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath +
 | 
			
		||||
                    ", chunk index " + chunkIndex + ", count " + chunkCount +
 | 
			
		||||
                    ", HTTP result status " + status);
 | 
			
		||||
 | 
			
		||||
                if (!isSuccess(status))
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (channel != null)
 | 
			
		||||
                channel.close();
 | 
			
		||||
            if (raf != null)
 | 
			
		||||
                raf.close();
 | 
			
		||||
            if (mPutMethod != null)
 | 
			
		||||
                mPutMethod.releaseConnection();    // let the connection available for other methods
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -27,28 +27,25 @@ package com.owncloud.android.lib.resources.files;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
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.RemoteOperationResult.ResultCode;
 | 
			
		||||
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.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.DavException;
 | 
			
		||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
 | 
			
		||||
import org.apache.jackrabbit.webdav.Status;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.CopyMethod;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 * <p/>
 | 
			
		||||
 *
 | 
			
		||||
 * Allows renaming the moving file/folder at the same time.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 */
 | 
			
		||||
public class CopyRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
@ -62,7 +59,6 @@ public class CopyRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    private boolean mOverwrite;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor.
 | 
			
		||||
     * <p/>
 | 
			
		||||
@ -78,7 +74,6 @@ public class CopyRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
        mOverwrite = overwrite;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Performs the rename operation.
 | 
			
		||||
     *
 | 
			
		||||
@ -93,36 +88,35 @@ public class CopyRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
        /// check parameters
 | 
			
		||||
        if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) {
 | 
			
		||||
            return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
            return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mTargetRemotePath.equals(mSrcRemotePath)) {
 | 
			
		||||
            // nothing to do!
 | 
			
		||||
            return new RemoteOperationResult(ResultCode.OK);
 | 
			
		||||
            return new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mTargetRemotePath.startsWith(mSrcRemotePath)) {
 | 
			
		||||
            return new RemoteOperationResult(ResultCode.INVALID_COPY_INTO_DESCENDANT);
 | 
			
		||||
            return new RemoteOperationResult<>(ResultCode.INVALID_COPY_INTO_DESCENDANT);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// perform remote operation
 | 
			
		||||
        CopyMethod copyMethod = null;
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        try {
 | 
			
		||||
            copyMethod = new CopyMethod(
 | 
			
		||||
                    client.getWebdavUri() + WebdavUtils.encodePath(mSrcRemotePath),
 | 
			
		||||
                    client.getWebdavUri() + WebdavUtils.encodePath(mTargetRemotePath),
 | 
			
		||||
                    mOverwrite
 | 
			
		||||
            );
 | 
			
		||||
            int status = client.executeMethod(copyMethod, COPY_READ_TIMEOUT, COPY_CONNECTION_TIMEOUT);
 | 
			
		||||
            CopyMethod copyMethod = new CopyMethod(new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mSrcRemotePath)),
 | 
			
		||||
                    client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mTargetRemotePath),
 | 
			
		||||
                    mOverwrite);
 | 
			
		||||
 | 
			
		||||
            /// process response
 | 
			
		||||
            if (status == HttpStatus.SC_MULTI_STATUS) {
 | 
			
		||||
                result = processPartialError(copyMethod);
 | 
			
		||||
            copyMethod.setReadTimeout(COPY_READ_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            copyMethod.setConnectionTimeout(COPY_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
 | 
			
		||||
            } else if (status == HttpStatus.SC_PRECONDITION_FAILED && !mOverwrite) {
 | 
			
		||||
            final int status = client.executeHttpMethod(copyMethod);
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
 | 
			
		||||
            if(status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT) {
 | 
			
		||||
                result = new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
            } else if (status == HttpConstants.HTTP_PRECONDITION_FAILED && !mOverwrite) {
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult<>(ResultCode.INVALID_OVERWRITE);
 | 
			
		||||
                client.exhaustResponse(copyMethod.getResponseBodyAsStream());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -130,7 +124,7 @@ public class CopyRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
                /// http://www.webdav.org/specs/rfc4918.html#rfc.section.9.9.4
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(isSuccess(status), copyMethod);
 | 
			
		||||
                result = new RemoteOperationResult<>(copyMethod);
 | 
			
		||||
                client.exhaustResponse(copyMethod.getResponseBodyAsStream());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -138,67 +132,11 @@ public class CopyRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
                    result.getLogMessage());
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log.e(TAG, "Copy " + mSrcRemotePath + " to " + mTargetRemotePath + ": " +
 | 
			
		||||
                    result.getLogMessage(), e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (copyMethod != null)
 | 
			
		||||
                copyMethod.releaseConnection();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Analyzes a multistatus response from the OC server to generate an appropriate result.
 | 
			
		||||
     * <p/>
 | 
			
		||||
     * In WebDAV, a COPY request on collections (folders) can be PARTIALLY successful: some
 | 
			
		||||
     * children are copied, some other aren't.
 | 
			
		||||
     * <p/>
 | 
			
		||||
     * According to the WebDAV specification, a multistatus response SHOULD NOT include partial
 | 
			
		||||
     * successes (201, 204) nor for descendants of already failed children (424) in the response
 | 
			
		||||
     * entity. But SHOULD NOT != MUST NOT, so take carefully.
 | 
			
		||||
     *
 | 
			
		||||
     * @param copyMethod Copy operation just finished with a multistatus response
 | 
			
		||||
     * @return A result for the {@link com.owncloud.android.lib.resources.files.CopyRemoteFileOperation} caller
 | 
			
		||||
     * @throws java.io.IOException                       If the response body could not be parsed
 | 
			
		||||
     * @throws org.apache.jackrabbit.webdav.DavException If the status code is other than MultiStatus or if obtaining
 | 
			
		||||
     *                                                   the response XML document fails
 | 
			
		||||
     */
 | 
			
		||||
    private RemoteOperationResult processPartialError(CopyMethod copyMethod)
 | 
			
		||||
            throws IOException, DavException {
 | 
			
		||||
        // Adding a list of failed descendants to the result could be interesting; or maybe not.
 | 
			
		||||
        // For the moment, let's take the easy way.
 | 
			
		||||
 | 
			
		||||
        /// check that some error really occurred
 | 
			
		||||
        MultiStatusResponse[] responses = copyMethod.getResponseBodyAsMultiStatus().getResponses();
 | 
			
		||||
        Status[] status;
 | 
			
		||||
        boolean failFound = false;
 | 
			
		||||
        for (int i = 0; i < responses.length && !failFound; i++) {
 | 
			
		||||
            status = responses[i].getStatus();
 | 
			
		||||
            failFound = (
 | 
			
		||||
                    status != null &&
 | 
			
		||||
                            status.length > 0 &&
 | 
			
		||||
                            status[0].getStatusCode() > 299
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
        if (failFound) {
 | 
			
		||||
            result = new RemoteOperationResult(ResultCode.PARTIAL_COPY_DONE);
 | 
			
		||||
        } else {
 | 
			
		||||
            result = new RemoteOperationResult(true, copyMethod);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected boolean isSuccess(int status) {
 | 
			
		||||
        return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,16 +24,22 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.MkColMethod;
 | 
			
		||||
 | 
			
		||||
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.MkColMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.network.WebdavUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 | 
			
		||||
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.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remote operation performing the creation of a new folder in the ownCloud server.
 | 
			
		||||
@ -48,20 +54,19 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
 | 
			
		||||
    private static final int READ_TIMEOUT = 30000;
 | 
			
		||||
    private static final int CONNECTION_TIMEOUT = 5000;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected String mRemotePath;
 | 
			
		||||
    protected boolean mCreateFullPath;
 | 
			
		||||
    private String mRemotePath;
 | 
			
		||||
    private boolean mCreateFullPath;
 | 
			
		||||
    protected boolean createChunksFolder;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
     * @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
 | 
			
		||||
     *                       if don't exist yet.
 | 
			
		||||
     * @param createFullPath 'True' means that all the ancestor folders should be created.
 | 
			
		||||
     */
 | 
			
		||||
    public CreateRemoteFolderOperation(String remotePath, boolean createFullPath) {
 | 
			
		||||
        mRemotePath = remotePath;
 | 
			
		||||
        mCreateFullPath = createFullPath;
 | 
			
		||||
        createChunksFolder = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -71,7 +76,7 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
        OwnCloudVersion version = client.getOwnCloudVersion();
 | 
			
		||||
        boolean versionWithForbiddenChars =
 | 
			
		||||
            (version != null && version.isVersionWithForbiddenCharacters());
 | 
			
		||||
@ -85,41 +90,38 @@ public class CreateRemoteFolderOperation extends RemoteOperation {
 | 
			
		||||
                    result = createFolder(client);    // second (and last) try
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
            result = new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private RemoteOperationResult createFolder(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        MkColMethod mkcol = null;
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
        try {
 | 
			
		||||
            mkcol = new MkColMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
 | 
			
		||||
            client.executeMethod(mkcol, READ_TIMEOUT, CONNECTION_TIMEOUT);
 | 
			
		||||
            result = new RemoteOperationResult(mkcol.succeeded(), mkcol);
 | 
			
		||||
            Uri webDavUri = createChunksFolder ? client.getNewUploadsWebDavUri() : client.getNewFilesWebDavUri();
 | 
			
		||||
            final MkColMethod mkcol = new MkColMethod(new URL(webDavUri + WebdavUtils.encodePath(mRemotePath)));
 | 
			
		||||
            mkcol.setReadTimeout(READ_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            mkcol.setConnectionTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            final int status = client.executeHttpMethod(mkcol);
 | 
			
		||||
 | 
			
		||||
            result = (status == HttpConstants.HTTP_CREATED)
 | 
			
		||||
                    ? new RemoteOperationResult<>(ResultCode.OK)
 | 
			
		||||
                    : new RemoteOperationResult<>(mkcol);
 | 
			
		||||
            Log_OC.d(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage());
 | 
			
		||||
            client.exhaustResponse(mkcol.getResponseBodyAsStream());
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Create directory " + mRemotePath + ": " + result.getLogMessage(), e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (mkcol != null)
 | 
			
		||||
                mkcol.releaseConnection();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private RemoteOperationResult createParentFolder(String parentPath, OwnCloudClient client) {
 | 
			
		||||
        RemoteOperation operation = new CreateRemoteFolderOperation(parentPath,
 | 
			
		||||
            mCreateFullPath);
 | 
			
		||||
        RemoteOperation operation = new CreateRemoteFolderOperation(parentPath, mCreateFullPath);
 | 
			
		||||
        return operation.execute(client);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -24,21 +24,9 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Header;
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
@ -46,6 +34,16 @@ import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Iterator;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remote operation performing the download of a remote file in the ownCloud server.
 | 
			
		||||
 *
 | 
			
		||||
@ -88,7 +86,7 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
                result.getLogMessage());
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " +
 | 
			
		||||
                result.getLogMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
@ -98,28 +96,30 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private RemoteOperationResult downloadFile(OwnCloudClient client, File targetFile) throws
 | 
			
		||||
        IOException, OperationCancelledException {
 | 
			
		||||
            Exception {
 | 
			
		||||
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
        int status;
 | 
			
		||||
        boolean savedFile = false;
 | 
			
		||||
        mGet = new GetMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
 | 
			
		||||
        mGet = new GetMethod(new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mRemotePath)));
 | 
			
		||||
        Iterator<OnDatatransferProgressListener> it;
 | 
			
		||||
 | 
			
		||||
        FileOutputStream fos = null;
 | 
			
		||||
        BufferedInputStream bis = null;
 | 
			
		||||
        try {
 | 
			
		||||
            status = client.executeMethod(mGet);
 | 
			
		||||
            status = client.executeHttpMethod(mGet);
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                targetFile.createNewFile();
 | 
			
		||||
                bis = new BufferedInputStream(mGet.getResponseBodyAsStream());
 | 
			
		||||
                fos = new FileOutputStream(targetFile);
 | 
			
		||||
                long transferred = 0;
 | 
			
		||||
 | 
			
		||||
                Header contentLength = mGet.getResponseHeader("Content-Length");
 | 
			
		||||
                long totalToTransfer = (contentLength != null &&
 | 
			
		||||
                    contentLength.getValue().length() > 0) ?
 | 
			
		||||
                    Long.parseLong(contentLength.getValue()) : 0;
 | 
			
		||||
                String contentLength = mGet.getResponseHeader(HttpConstants.CONTENT_LENGTH_HEADER);
 | 
			
		||||
                long totalToTransfer =
 | 
			
		||||
                        (contentLength != null
 | 
			
		||||
                                && contentLength.length() > 0)
 | 
			
		||||
                        ? Long.parseLong(contentLength)
 | 
			
		||||
                        : 0;
 | 
			
		||||
 | 
			
		||||
                byte[] bytes = new byte[4096];
 | 
			
		||||
                int readResult;
 | 
			
		||||
@ -142,18 +142,23 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
                }
 | 
			
		||||
                if (transferred == totalToTransfer) {  // Check if the file is completed
 | 
			
		||||
                    savedFile = true;
 | 
			
		||||
                    Header modificationTime = mGet.getResponseHeader("Last-Modified");
 | 
			
		||||
                    if (modificationTime == null) {
 | 
			
		||||
                        modificationTime = mGet.getResponseHeader("last-modified");
 | 
			
		||||
                    }
 | 
			
		||||
                    final String modificationTime =
 | 
			
		||||
                            mGet.getResponseHeaders().get("Last-Modified") != null
 | 
			
		||||
                            ? mGet.getResponseHeaders().get("Last-Modified")
 | 
			
		||||
                            :  mGet.getResponseHeader("last-modified");
 | 
			
		||||
 | 
			
		||||
                    if (modificationTime != null) {
 | 
			
		||||
                        Date d = WebdavUtils.parseResponseDate(modificationTime.getValue());
 | 
			
		||||
                        final Date d = WebdavUtils.parseResponseDate(modificationTime);
 | 
			
		||||
                        mModificationTimestamp = (d != null) ? d.getTime() : 0;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        Log_OC.e(TAG, "Could not read modification time from response downloading " + mRemotePath);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    mEtag = WebdavUtils.getEtagFromResponse(mGet);
 | 
			
		||||
 | 
			
		||||
                    // Get rid of extra quotas
 | 
			
		||||
                    mEtag = mEtag.replace("\"", "");
 | 
			
		||||
 | 
			
		||||
                    if (mEtag.length() == 0) {
 | 
			
		||||
                        Log_OC.e(TAG, "Could not read eTag from response downloading " + mRemotePath);
 | 
			
		||||
                    }
 | 
			
		||||
@ -168,21 +173,21 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
            } // else, body read by RemoteOperationResult constructor
 | 
			
		||||
 | 
			
		||||
            result = new RemoteOperationResult(isSuccess(status), mGet);
 | 
			
		||||
 | 
			
		||||
            result = isSuccess(status)
 | 
			
		||||
                    ? new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK)
 | 
			
		||||
                    : new RemoteOperationResult<>(mGet);
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (fos != null) fos.close();
 | 
			
		||||
            if (bis != null) bis.close();
 | 
			
		||||
            if (!savedFile && targetFile.exists()) {
 | 
			
		||||
                targetFile.delete();
 | 
			
		||||
            }
 | 
			
		||||
            mGet.releaseConnection();    // let the connection available for other methods
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getTmpPath() {
 | 
			
		||||
@ -212,4 +217,4 @@ public class DownloadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
    public String getEtag() {
 | 
			
		||||
        return mEtag;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,22 +1,22 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -24,47 +24,50 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.DavConstants;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
 | 
			
		||||
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.network.RedirectionPath;
 | 
			
		||||
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.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Operation to check the existence or absence of a path in a remote server.
 | 
			
		||||
 * 
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class ExistenceCheckRemoteOperation extends RemoteOperation {
 | 
			
		||||
    
 | 
			
		||||
    /** Maximum time to wait for a response from the server in MILLISECONDs.  */
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Maximum time to wait for a response from the server in MILLISECONDs.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int TIMEOUT = 10000;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = ExistenceCheckRemoteOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private static final int FORBIDDEN_ERROR = 403;
 | 
			
		||||
    private static final int SERVICE_UNAVAILABLE_ERROR = 503;
 | 
			
		||||
    
 | 
			
		||||
    private String mPath;
 | 
			
		||||
    private boolean mSuccessIfAbsent;
 | 
			
		||||
 | 
			
		||||
    /** Sequence of redirections followed. Available only after executing the operation */
 | 
			
		||||
    /**
 | 
			
		||||
     * Sequence of redirections followed. Available only after executing the operation
 | 
			
		||||
     */
 | 
			
		||||
    private RedirectionPath mRedirectionPath = null;
 | 
			
		||||
        // TODO move to {@link RemoteOperation}, that needs a nice refactoring
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Full constructor. Success of the operation will depend upon the value of successIfAbsent.
 | 
			
		||||
     *
 | 
			
		||||
     * @param remotePath        Path to append to the URL owned by the client instance.
 | 
			
		||||
     * @param successIfAbsent   When 'true', the operation finishes in success if the path does
 | 
			
		||||
     *                          NOT exist in the remote server (HTTP 404).
 | 
			
		||||
     * @param remotePath      Path to append to the URL owned by the client instance.
 | 
			
		||||
     * @param successIfAbsent When 'true', the operation finishes in success if the path does
 | 
			
		||||
     *                        NOT exist in the remote server (HTTP 404).
 | 
			
		||||
     */
 | 
			
		||||
    public ExistenceCheckRemoteOperation(String remotePath, boolean successIfAbsent) {
 | 
			
		||||
        mPath = (remotePath != null) ? remotePath : "";
 | 
			
		||||
@ -72,69 +75,73 @@ public class ExistenceCheckRemoteOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
	protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        PropFindMethod propfind = null;
 | 
			
		||||
        boolean previousFollowRedirects = client.getFollowRedirects();
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
 | 
			
		||||
        boolean previousFollowRedirects = client.followRedirects();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            propfind = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mPath),
 | 
			
		||||
                    WebdavUtils.getAllPropSet(), DavConstants.DEPTH_0);
 | 
			
		||||
            PropfindMethod propfindMethod = new PropfindMethod(
 | 
			
		||||
                    new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mPath)),
 | 
			
		||||
                    0,
 | 
			
		||||
                    DavUtils.getAllPropset()
 | 
			
		||||
            );
 | 
			
		||||
            propfindMethod.setReadTimeout(TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            propfindMethod.setConnectionTimeout(TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
 | 
			
		||||
            client.setFollowRedirects(false);
 | 
			
		||||
            int status = client.executeMethod(propfind, TIMEOUT, TIMEOUT);
 | 
			
		||||
            int status = client.executeHttpMethod(propfindMethod);
 | 
			
		||||
 | 
			
		||||
            if (previousFollowRedirects) {
 | 
			
		||||
                mRedirectionPath = client.followRedirection(propfind);
 | 
			
		||||
                mRedirectionPath = client.followRedirection(propfindMethod);
 | 
			
		||||
                status = mRedirectionPath.getLastStatus();
 | 
			
		||||
            }
 | 
			
		||||
            if (status != FORBIDDEN_ERROR && status != SERVICE_UNAVAILABLE_ERROR) {
 | 
			
		||||
                client.exhaustResponse(propfind.getResponseBodyAsStream());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /**
 | 
			
		||||
             *  PROPFIND method
 | 
			
		||||
             *  404 NOT FOUND: path doesn't exist,
 | 
			
		||||
             *  207 MULTI_STATUS: path exists.
 | 
			
		||||
             */
 | 
			
		||||
            boolean success = ((status == HttpStatus.SC_OK || status == HttpStatus.SC_MULTI_STATUS) &&
 | 
			
		||||
                    !mSuccessIfAbsent) ||
 | 
			
		||||
                    (status == HttpStatus.SC_MULTI_STATUS && !mSuccessIfAbsent) ||
 | 
			
		||||
                    (status == HttpStatus.SC_NOT_FOUND && mSuccessIfAbsent);
 | 
			
		||||
            result = new RemoteOperationResult(
 | 
			
		||||
                success,
 | 
			
		||||
                propfind
 | 
			
		||||
            );
 | 
			
		||||
            Log_OC.d(TAG, "Existence check for " + client.getWebdavUri() +
 | 
			
		||||
 | 
			
		||||
            Log_OC.d(TAG, "Existence check for " + client.getNewFilesWebDavUri() +
 | 
			
		||||
                    WebdavUtils.encodePath(mPath) + " targeting for " +
 | 
			
		||||
                    (mSuccessIfAbsent ? " absence " : " existence ") +
 | 
			
		||||
                    "finished with HTTP status " + status + (!success?"(FAIL)":""));
 | 
			
		||||
            
 | 
			
		||||
                    "finished with HTTP status " + status + (!isSuccess(status) ? "(FAIL)" : ""));
 | 
			
		||||
 | 
			
		||||
            return isSuccess(status)
 | 
			
		||||
                    ? new RemoteOperationResult<>(OK)
 | 
			
		||||
                    : new RemoteOperationResult<>(propfindMethod);
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            Log_OC.e(TAG, "Existence check for " + client.getWebdavUri() +
 | 
			
		||||
            final RemoteOperationResult result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Existence check for " + client.getNewFilesWebDavUri() +
 | 
			
		||||
                    WebdavUtils.encodePath(mPath) + " targeting for " +
 | 
			
		||||
                    (mSuccessIfAbsent ? " absence " : " existence ") + ": " +
 | 
			
		||||
                    result.getLogMessage(), result.getException());
 | 
			
		||||
            
 | 
			
		||||
            return result;
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (propfind != null)
 | 
			
		||||
                propfind.releaseConnection();
 | 
			
		||||
            client.setFollowRedirects(previousFollowRedirects);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the sequence of redirections followed during the execution of the operation.
 | 
			
		||||
     *
 | 
			
		||||
     * @return      Sequence of redirections followed, if any, or NULL if the operation was not executed.
 | 
			
		||||
     * @return Sequence of redirections followed, if any, or NULL if the operation was not executed.
 | 
			
		||||
     */
 | 
			
		||||
    public RedirectionPath getRedirectionPath() {
 | 
			
		||||
        return mRedirectionPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return      'True' if the operation was executed and at least one redirection was followed.
 | 
			
		||||
     * @return 'True' if the operation was executed and at least one redirection was followed.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean wasRedirected() {
 | 
			
		||||
        return (mRedirectionPath != null && mRedirectionPath.getRedirectionsCount() > 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return ((status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_MULTI_STATUS) && !mSuccessIfAbsent)
 | 
			
		||||
                || (status == HttpConstants.HTTP_MULTI_STATUS && !mSuccessIfAbsent)
 | 
			
		||||
                || (status == HttpConstants.HTTP_NOT_FOUND && mSuccessIfAbsent);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,17 +24,16 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
public class FileUtils {
 | 
			
		||||
 | 
			
		||||
	private static final  String TAG = FileUtils.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
	public static final String PATH_SEPARATOR = "/";
 | 
			
		||||
 | 
			
		||||
	public static final String FINAL_CHUNKS_FILE = ".file";
 | 
			
		||||
 | 
			
		||||
	public static String getParentPath(String remotePath) {
 | 
			
		||||
		String parentPath = new File(remotePath).getParent();
 | 
			
		||||
@ -82,5 +81,4 @@ public class FileUtils {
 | 
			
		||||
		}
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,31 +24,29 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.DavException;
 | 
			
		||||
import org.apache.jackrabbit.webdav.MultiStatusResponse;
 | 
			
		||||
import org.apache.jackrabbit.webdav.Status;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.MoveMethod;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.util.Log;
 | 
			
		||||
 | 
			
		||||
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.RemoteOperationResult.ResultCode;
 | 
			
		||||
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.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
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.
 | 
			
		||||
 * <p>
 | 
			
		||||
 *
 | 
			
		||||
 * Allows renaming the moving file/folder at the same time.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class MoveRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
@ -59,28 +57,29 @@ public class MoveRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    private String mSrcRemotePath;
 | 
			
		||||
    private String mTargetRemotePath;
 | 
			
		||||
 | 
			
		||||
    private boolean mOverwrite;
 | 
			
		||||
 | 
			
		||||
    protected boolean moveChunkedFile = false;
 | 
			
		||||
    protected String mFileLastModifTimestamp;
 | 
			
		||||
    protected long mFileLength;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor.
 | 
			
		||||
     * <p>
 | 
			
		||||
     *
 | 
			
		||||
     * TODO Paths should finish in "/" in the case of folders. ?
 | 
			
		||||
     *
 | 
			
		||||
     * @param srcRemotePath    Remote path of the file/folder to move.
 | 
			
		||||
     * @param targetRemotePath Remove path desired for the file/folder after moving it.
 | 
			
		||||
     * @param targetRemotePath Remote path desired for the file/folder after moving it.
 | 
			
		||||
     */
 | 
			
		||||
    public MoveRemoteFileOperation(
 | 
			
		||||
        String srcRemotePath, String targetRemotePath, boolean overwrite
 | 
			
		||||
    ) {
 | 
			
		||||
    public MoveRemoteFileOperation(String srcRemotePath,
 | 
			
		||||
                                   String targetRemotePath,
 | 
			
		||||
                                   boolean overwrite) {
 | 
			
		||||
 | 
			
		||||
        mSrcRemotePath = srcRemotePath;
 | 
			
		||||
        mTargetRemotePath = targetRemotePath;
 | 
			
		||||
        mOverwrite = overwrite;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Performs the rename operation.
 | 
			
		||||
     *
 | 
			
		||||
@ -95,45 +94,52 @@ public class MoveRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
        /// check parameters
 | 
			
		||||
        if (!FileUtils.isValidPath(mTargetRemotePath, versionWithForbiddenChars)) {
 | 
			
		||||
            return new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
            return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mTargetRemotePath.equals(mSrcRemotePath)) {
 | 
			
		||||
            // nothing to do!
 | 
			
		||||
            return new RemoteOperationResult(ResultCode.OK);
 | 
			
		||||
            return new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mTargetRemotePath.startsWith(mSrcRemotePath)) {
 | 
			
		||||
            return new RemoteOperationResult(ResultCode.INVALID_MOVE_INTO_DESCENDANT);
 | 
			
		||||
            return new RemoteOperationResult<>(ResultCode.INVALID_MOVE_INTO_DESCENDANT);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// perform remote operation
 | 
			
		||||
        MoveMethod move = null;
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
        try {
 | 
			
		||||
            move = new MoveMethod(
 | 
			
		||||
                client.getWebdavUri() + WebdavUtils.encodePath(mSrcRemotePath),
 | 
			
		||||
                client.getWebdavUri() + WebdavUtils.encodePath(mTargetRemotePath),
 | 
			
		||||
                mOverwrite
 | 
			
		||||
            );
 | 
			
		||||
            int status = client.executeMethod(move, MOVE_READ_TIMEOUT, MOVE_CONNECTION_TIMEOUT);
 | 
			
		||||
            // 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
 | 
			
		||||
            Uri srcWebDavUri = moveChunkedFile ? client.getNewUploadsWebDavUri() : client.getNewFilesWebDavUri();
 | 
			
		||||
 | 
			
		||||
            final MoveMethod move = new MoveMethod(
 | 
			
		||||
                    new URL(srcWebDavUri + WebdavUtils.encodePath(mSrcRemotePath)),
 | 
			
		||||
                client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mTargetRemotePath),
 | 
			
		||||
                    mOverwrite);
 | 
			
		||||
 | 
			
		||||
            if (moveChunkedFile) {
 | 
			
		||||
                move.addRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER, mFileLastModifTimestamp);
 | 
			
		||||
                move.addRequestHeader(HttpConstants.OC_TOTAL_LENGTH_HEADER, String.valueOf(mFileLength));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            move.setReadTimeout(MOVE_READ_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            move.setConnectionTimeout(MOVE_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
 | 
			
		||||
            final int status = client.executeHttpMethod(move);
 | 
			
		||||
            /// process response
 | 
			
		||||
            if (status == HttpStatus.SC_MULTI_STATUS) {
 | 
			
		||||
                result = processPartialError(move);
 | 
			
		||||
            if(isSuccess(status)) {
 | 
			
		||||
                result = new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
            } else if (status == HttpConstants.HTTP_PRECONDITION_FAILED && !mOverwrite) {
 | 
			
		||||
 | 
			
		||||
            } else if (status == HttpStatus.SC_PRECONDITION_FAILED && !mOverwrite) {
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
 | 
			
		||||
                result = new RemoteOperationResult<>(ResultCode.INVALID_OVERWRITE);
 | 
			
		||||
                client.exhaustResponse(move.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 = new RemoteOperationResult(isSuccess(status), move);
 | 
			
		||||
                result = new RemoteOperationResult<>(move);
 | 
			
		||||
                client.exhaustResponse(move.getResponseBodyAsStream());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -141,67 +147,15 @@ public class MoveRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
                result.getLogMessage());
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log.e(TAG, "Move " + mSrcRemotePath + " to " + mTargetRemotePath + ": " +
 | 
			
		||||
                result.getLogMessage(), e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (move != null)
 | 
			
		||||
                move.releaseConnection();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Analyzes a multistatus response from the OC server to generate an appropriate result.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * In WebDAV, a MOVE request on collections (folders) can be PARTIALLY successful: some
 | 
			
		||||
     * children are moved, some other aren't.
 | 
			
		||||
     * <p>
 | 
			
		||||
     * According to the WebDAV specification, a multistatus response SHOULD NOT include partial
 | 
			
		||||
     * successes (201, 204) nor for descendants of already failed children (424) in the response
 | 
			
		||||
     * entity. But SHOULD NOT != MUST NOT, so take carefully.
 | 
			
		||||
     *
 | 
			
		||||
     * @param move Move operation just finished with a multistatus response
 | 
			
		||||
     * @throws IOException  If the response body could not be parsed
 | 
			
		||||
     * @throws DavException If the status code is other than MultiStatus or if obtaining
 | 
			
		||||
     *                      the response XML document fails
 | 
			
		||||
     * @return A result for the {@link MoveRemoteFileOperation} caller
 | 
			
		||||
     */
 | 
			
		||||
    private RemoteOperationResult processPartialError(MoveMethod move)
 | 
			
		||||
        throws IOException, DavException {
 | 
			
		||||
        // Adding a list of failed descendants to the result could be interesting; or maybe not.
 | 
			
		||||
        // For the moment, let's take the easy way.
 | 
			
		||||
 | 
			
		||||
        /// check that some error really occurred
 | 
			
		||||
        MultiStatusResponse[] responses = move.getResponseBodyAsMultiStatus().getResponses();
 | 
			
		||||
        Status[] status = null;
 | 
			
		||||
        boolean failFound = false;
 | 
			
		||||
        for (int i = 0; i < responses.length && !failFound; i++) {
 | 
			
		||||
            status = responses[i].getStatus();
 | 
			
		||||
            failFound = (
 | 
			
		||||
                status != null &&
 | 
			
		||||
                    status.length > 0 &&
 | 
			
		||||
                    status[0].getStatusCode() > 299
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
        if (failFound) {
 | 
			
		||||
            result = new RemoteOperationResult(ResultCode.PARTIAL_MOVE_DONE);
 | 
			
		||||
        } else {
 | 
			
		||||
            result = new RemoteOperationResult(true, move);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    protected boolean isSuccess(int status) {
 | 
			
		||||
        return status == HttpStatus.SC_CREATED || status == HttpStatus.SC_NO_CONTENT;
 | 
			
		||||
        return status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -23,20 +23,20 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.DavConstants;
 | 
			
		||||
import org.apache.jackrabbit.webdav.MultiStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.network.WebdavEntry;
 | 
			
		||||
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.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.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.http.methods.webdav.DavConstants.DEPTH_0;
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remote operation performing the read a file from the ownCloud server.
 | 
			
		||||
@ -45,7 +45,7 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ReadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
public class ReadRemoteFileOperation extends RemoteOperation<RemoteFile> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = ReadRemoteFileOperation.class.getSimpleName();
 | 
			
		||||
    private static final int SYNC_READ_TIMEOUT = 40000;
 | 
			
		||||
@ -53,7 +53,6 @@ public class ReadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    private String mRemotePath;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
@ -69,51 +68,41 @@ public class ReadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
     * @param client Client object to communicate with the remote ownCloud server.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        PropFindMethod propfind = null;
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
    protected RemoteOperationResult<RemoteFile> run(OwnCloudClient client) {
 | 
			
		||||
        PropfindMethod propfind;
 | 
			
		||||
        RemoteOperationResult<RemoteFile> result;
 | 
			
		||||
 | 
			
		||||
        /// take the duty of check the server for the current state of the file there
 | 
			
		||||
        try {
 | 
			
		||||
            // remote request
 | 
			
		||||
            propfind = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath),
 | 
			
		||||
                WebdavUtils.getFilePropSet(),    // PropFind Properties
 | 
			
		||||
                DavConstants.DEPTH_0);
 | 
			
		||||
            int status;
 | 
			
		||||
            status = client.executeMethod(propfind, SYNC_READ_TIMEOUT, SYNC_CONNECTION_TIMEOUT);
 | 
			
		||||
            propfind = new PropfindMethod(new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mRemotePath)),
 | 
			
		||||
                    DEPTH_0,
 | 
			
		||||
                    DavUtils.getAllPropset());
 | 
			
		||||
 | 
			
		||||
            boolean isSuccess = (
 | 
			
		||||
                status == HttpStatus.SC_MULTI_STATUS ||
 | 
			
		||||
                    status == HttpStatus.SC_OK
 | 
			
		||||
            );
 | 
			
		||||
            if (isSuccess) {
 | 
			
		||||
                // Parse response
 | 
			
		||||
                MultiStatus resp = propfind.getResponseBodyAsMultiStatus();
 | 
			
		||||
                WebdavEntry we = new WebdavEntry(resp.getResponses()[0],
 | 
			
		||||
                    client.getWebdavUri().getPath());
 | 
			
		||||
                RemoteFile remoteFile = new RemoteFile(we);
 | 
			
		||||
                ArrayList<Object> files = new ArrayList<Object>();
 | 
			
		||||
                files.add(remoteFile);
 | 
			
		||||
            propfind.setReadTimeout(SYNC_READ_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            propfind.setConnectionTimeout(SYNC_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            final int status = client.executeHttpMethod(propfind);
 | 
			
		||||
 | 
			
		||||
                // Result of the operation
 | 
			
		||||
                result = new RemoteOperationResult(true, propfind);
 | 
			
		||||
                result.setData(files);
 | 
			
		||||
            if (status == HttpConstants.HTTP_MULTI_STATUS
 | 
			
		||||
                    || status == HttpConstants.HTTP_OK) {
 | 
			
		||||
 | 
			
		||||
                final RemoteFile file = new RemoteFile(propfind.getRoot(), client.getCredentials().getUsername());
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult<>(OK);
 | 
			
		||||
                result.setData(file);
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, propfind);
 | 
			
		||||
                result = new RemoteOperationResult<>(propfind);
 | 
			
		||||
                client.exhaustResponse(propfind.getResponseBodyAsStream());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            Log_OC.e(TAG, "Synchronizing  file " + mRemotePath + ": " + result.getLogMessage(),
 | 
			
		||||
                result.getException());
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (propfind != null)
 | 
			
		||||
                propfind.releaseConnection();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,22 +1,22 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -24,33 +24,36 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.DavConstants;
 | 
			
		||||
import org.apache.jackrabbit.webdav.MultiStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.network.WebdavEntry;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
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.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.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.Response;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ReadRemoteFolderOperation extends RemoteOperation {
 | 
			
		||||
public class ReadRemoteFolderOperation extends RemoteOperation<ArrayList<RemoteFile>> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = ReadRemoteFolderOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private String mRemotePath;
 | 
			
		||||
    private ArrayList<Object> mFolderAndFiles;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
@ -67,110 +70,60 @@ public class ReadRemoteFolderOperation extends RemoteOperation {
 | 
			
		||||
     * @param client Client object to communicate with the remote ownCloud server.
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        PropFindMethod query = null;
 | 
			
		||||
    protected RemoteOperationResult<ArrayList<RemoteFile>> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<ArrayList<RemoteFile>> result = null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // remote request
 | 
			
		||||
            query = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath),
 | 
			
		||||
                WebdavUtils.getAllPropSet(),    // PropFind Properties
 | 
			
		||||
                DavConstants.DEPTH_1);
 | 
			
		||||
            int status = client.executeMethod(query);
 | 
			
		||||
            PropfindMethod propfindMethod = new PropfindMethod(
 | 
			
		||||
                    new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mRemotePath)),
 | 
			
		||||
                    DavConstants.DEPTH_1,
 | 
			
		||||
                    DavUtils.getAllPropset());
 | 
			
		||||
 | 
			
		||||
            // check and process response
 | 
			
		||||
            boolean isSuccess = (
 | 
			
		||||
                status == HttpStatus.SC_MULTI_STATUS ||
 | 
			
		||||
                    status == HttpStatus.SC_OK
 | 
			
		||||
            );
 | 
			
		||||
            if (isSuccess) {
 | 
			
		||||
                // get data from remote folder
 | 
			
		||||
                MultiStatus dataInServer = query.getResponseBodyAsMultiStatus();
 | 
			
		||||
                readData(dataInServer, client);
 | 
			
		||||
            client.setFollowRedirects(true);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(propfindMethod);
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                ArrayList<RemoteFile> mFolderAndFiles = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
                // parse data from remote folder
 | 
			
		||||
                mFolderAndFiles.add(
 | 
			
		||||
                        new RemoteFile(propfindMethod.getRoot(), client.getCredentials().getUsername())
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                // loop to update every child
 | 
			
		||||
                for (Response resource : propfindMethod.getMembers()) {
 | 
			
		||||
                    RemoteFile file = new RemoteFile(resource, client.getCredentials().getUsername());
 | 
			
		||||
                    mFolderAndFiles.add(file);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Result of the operation
 | 
			
		||||
                result = new RemoteOperationResult(true, query);
 | 
			
		||||
                // Add data to the result
 | 
			
		||||
                if (result.isSuccess()) {
 | 
			
		||||
                    result.setData(mFolderAndFiles);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // synchronization failed
 | 
			
		||||
                result = new RemoteOperationResult(false, query);
 | 
			
		||||
                result = new RemoteOperationResult<>(OK);
 | 
			
		||||
                result.setData(mFolderAndFiles);
 | 
			
		||||
 | 
			
		||||
            } else { // synchronization failed
 | 
			
		||||
                result = new RemoteOperationResult<> (propfindMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (query != null)
 | 
			
		||||
                query.releaseConnection();  // let the connection available for other methods
 | 
			
		||||
            if (result.isSuccess()) {
 | 
			
		||||
                Log_OC.i(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage());
 | 
			
		||||
            } else {
 | 
			
		||||
                if (result.isException()) {
 | 
			
		||||
                    Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage(),
 | 
			
		||||
                        result.getException());
 | 
			
		||||
                            result.getException());
 | 
			
		||||
                } else {
 | 
			
		||||
                    Log_OC.e(TAG, "Synchronized " + mRemotePath + ": " + result.getLogMessage());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isMultiStatus(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_MULTI_STATUS);
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return status == HttpConstants.HTTP_MULTI_STATUS ||
 | 
			
		||||
                status == HttpConstants.HTTP_OK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read the data retrieved from the server about the contents of the target folder
 | 
			
		||||
     *
 | 
			
		||||
     * @param remoteData Full response got from the server with the data of the target
 | 
			
		||||
     *                   folder and its direct children.
 | 
			
		||||
     * @param client     Client instance to the remote server where the data were
 | 
			
		||||
     *                   retrieved.
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    private void readData(MultiStatus remoteData, OwnCloudClient client) {
 | 
			
		||||
        mFolderAndFiles = new ArrayList<Object>();
 | 
			
		||||
 | 
			
		||||
        // parse data from remote folder 
 | 
			
		||||
        WebdavEntry we = new WebdavEntry(remoteData.getResponses()[0],
 | 
			
		||||
            client.getWebdavUri().getPath());
 | 
			
		||||
        mFolderAndFiles.add(fillOCFile(we));
 | 
			
		||||
 | 
			
		||||
        // loop to update every child
 | 
			
		||||
        RemoteFile remoteFile = null;
 | 
			
		||||
        for (int i = 1; i < remoteData.getResponses().length; ++i) {
 | 
			
		||||
            /// new OCFile instance with the data from the server
 | 
			
		||||
            we = new WebdavEntry(remoteData.getResponses()[i], client.getWebdavUri().getPath());
 | 
			
		||||
            remoteFile = fillOCFile(we);
 | 
			
		||||
            mFolderAndFiles.add(remoteFile);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates and populates a new {@link RemoteFile} object with the data read from the server.
 | 
			
		||||
     *
 | 
			
		||||
     * @param we WebDAV entry read from the server for a WebDAV resource (remote file or folder).
 | 
			
		||||
     * @return New OCFile instance representing the remote resource described by we.
 | 
			
		||||
     */
 | 
			
		||||
    private RemoteFile fillOCFile(WebdavEntry we) {
 | 
			
		||||
        RemoteFile file = new RemoteFile(we.decodedPath());
 | 
			
		||||
        file.setCreationTimestamp(we.createTimestamp());
 | 
			
		||||
        file.setLength(we.contentLength());
 | 
			
		||||
        file.setMimeType(we.contentType());
 | 
			
		||||
        file.setModifiedTimestamp(we.modifiedTimestamp());
 | 
			
		||||
        file.setEtag(we.etag());
 | 
			
		||||
        file.setPermissions(we.permissions());
 | 
			
		||||
        file.setRemoteId(we.remoteId());
 | 
			
		||||
        file.setSize(we.size());
 | 
			
		||||
        file.setQuotaUsedBytes(we.quotaUsedBytes());
 | 
			
		||||
        file.setQuotaAvailableBytes(we.quotaAvailableBytes());
 | 
			
		||||
        file.setPrivateLink(we.privateLink());
 | 
			
		||||
        return file;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,18 +24,36 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.os.Parcel;
 | 
			
		||||
import android.os.Parcelable;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.network.WebdavEntry;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import at.bitfire.dav4android.Property;
 | 
			
		||||
import at.bitfire.dav4android.Response;
 | 
			
		||||
import at.bitfire.dav4android.property.CreationDate;
 | 
			
		||||
import at.bitfire.dav4android.property.GetContentLength;
 | 
			
		||||
import at.bitfire.dav4android.property.GetContentType;
 | 
			
		||||
import at.bitfire.dav4android.property.GetETag;
 | 
			
		||||
import at.bitfire.dav4android.property.GetLastModified;
 | 
			
		||||
import at.bitfire.dav4android.property.QuotaAvailableBytes;
 | 
			
		||||
import at.bitfire.dav4android.property.QuotaUsedBytes;
 | 
			
		||||
import at.bitfire.dav4android.property.owncloud.OCId;
 | 
			
		||||
import at.bitfire.dav4android.property.owncloud.OCPermissions;
 | 
			
		||||
import at.bitfire.dav4android.property.owncloud.OCPrivatelink;
 | 
			
		||||
import at.bitfire.dav4android.property.owncloud.OCSize;
 | 
			
		||||
import okhttp3.HttpUrl;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.OwnCloudClient.NEW_WEBDAV_FILES_PATH_4_0;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Contains the data of a Remote File from a WebDavEntry
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author Christian Schabesberger
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RemoteFile implements Parcelable, Serializable {
 | 
			
		||||
@ -156,7 +174,7 @@ public class RemoteFile implements Parcelable, Serializable {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create new {@link RemoteFile} with given path.
 | 
			
		||||
     * <p>
 | 
			
		||||
     *
 | 
			
		||||
     * The path received must be URL-decoded. Path separator must be OCFile.PATH_SEPARATOR, and it must be the first character in 'path'.
 | 
			
		||||
     *
 | 
			
		||||
     * @param path The remote path of the file.
 | 
			
		||||
@ -167,21 +185,52 @@ public class RemoteFile implements Parcelable, Serializable {
 | 
			
		||||
            throw new IllegalArgumentException("Trying to create a OCFile with a non valid remote path: " + path);
 | 
			
		||||
        }
 | 
			
		||||
        mRemotePath = path;
 | 
			
		||||
        mCreationTimestamp = 0;
 | 
			
		||||
        mLength = 0;
 | 
			
		||||
        mMimeType = "DIR";
 | 
			
		||||
        mQuotaUsedBytes = BigDecimal.ZERO;
 | 
			
		||||
        mQuotaAvailableBytes = BigDecimal.ZERO;
 | 
			
		||||
        mPrivateLink = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public RemoteFile(WebdavEntry webdavEntry) {
 | 
			
		||||
        this(webdavEntry.decodedPath());
 | 
			
		||||
        this.setCreationTimestamp(webdavEntry.createTimestamp());
 | 
			
		||||
        this.setLength(webdavEntry.contentLength());
 | 
			
		||||
        this.setMimeType(webdavEntry.contentType());
 | 
			
		||||
        this.setModifiedTimestamp(webdavEntry.modifiedTimestamp());
 | 
			
		||||
        this.setEtag(webdavEntry.etag());
 | 
			
		||||
        this.setPermissions(webdavEntry.permissions());
 | 
			
		||||
        this.setRemoteId(webdavEntry.remoteId());
 | 
			
		||||
        this.setSize(webdavEntry.size());
 | 
			
		||||
        this.setQuotaUsedBytes(webdavEntry.quotaUsedBytes());
 | 
			
		||||
        this.setQuotaAvailableBytes(webdavEntry.quotaAvailableBytes());
 | 
			
		||||
        this.setPrivateLink(webdavEntry.privateLink());
 | 
			
		||||
    public RemoteFile(final Response davResource, String userName) {
 | 
			
		||||
        this(getRemotePathFromUrl(davResource.getHref(), userName));
 | 
			
		||||
        final List<Property> properties = davResource.getProperties();
 | 
			
		||||
 | 
			
		||||
        for(Property property : properties) {
 | 
			
		||||
            if(property instanceof CreationDate)
 | 
			
		||||
                this.setCreationTimestamp(
 | 
			
		||||
                        Long.parseLong(((CreationDate) property).getCreationDate()));
 | 
			
		||||
            if(property instanceof GetContentLength)
 | 
			
		||||
                this.setLength(((GetContentLength) property).getContentLength());
 | 
			
		||||
            if(property instanceof  GetContentType)
 | 
			
		||||
                this.setMimeType(((GetContentType) property).getType());
 | 
			
		||||
            if(property instanceof GetLastModified)
 | 
			
		||||
                this.setModifiedTimestamp(((GetLastModified) property).getLastModified());
 | 
			
		||||
            if(property instanceof GetETag)
 | 
			
		||||
                this.setEtag(((GetETag) property).getETag());
 | 
			
		||||
            if(property instanceof OCPermissions)
 | 
			
		||||
                this.setPermissions(((OCPermissions) property).getPermission());
 | 
			
		||||
            if(property instanceof OCId)
 | 
			
		||||
                this.setRemoteId(((OCId) property).getId());
 | 
			
		||||
            if(property instanceof OCSize)
 | 
			
		||||
                this.setSize(((OCSize) property).getSize());
 | 
			
		||||
            if(property instanceof  QuotaUsedBytes)
 | 
			
		||||
                this.setQuotaUsedBytes(
 | 
			
		||||
                        BigDecimal.valueOf(((QuotaUsedBytes) property).getQuotaUsedBytes()));
 | 
			
		||||
            if(property instanceof QuotaAvailableBytes)
 | 
			
		||||
                this.setQuotaAvailableBytes(
 | 
			
		||||
                        BigDecimal.valueOf(((QuotaAvailableBytes) property).getQuotaAvailableBytes()));
 | 
			
		||||
            if(property instanceof OCPrivatelink)
 | 
			
		||||
                this.setPrivateLink(((OCPrivatelink) property).getLink());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private static String getRemotePathFromUrl(HttpUrl url, String displayName) {
 | 
			
		||||
        final String davPath = NEW_WEBDAV_FILES_PATH_4_0 + displayName;
 | 
			
		||||
        final String pathToOc = url.encodedPath().split(davPath)[0];
 | 
			
		||||
        return Uri.decode(url.encodedPath()).replace(pathToOc + davPath, "");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -262,5 +311,4 @@ public class RemoteFile implements Parcelable, Serializable {
 | 
			
		||||
        dest.writeSerializable(mQuotaAvailableBytes);
 | 
			
		||||
        dest.writeString(mPrivateLink);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,29 +24,33 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
 | 
			
		||||
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.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.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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
 | 
			
		||||
 */
 | 
			
		||||
public class RemoveRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
    private static final String TAG = RemoveRemoteFileOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private static final int REMOVE_READ_TIMEOUT = 30000;
 | 
			
		||||
    private static final int REMOVE_CONNECTION_TIMEOUT = 5000;
 | 
			
		||||
 | 
			
		||||
    private String mRemotePath;
 | 
			
		||||
 | 
			
		||||
    protected boolean removeChunksFolder = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
@ -63,30 +67,31 @@ public class RemoveRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        DeleteMethod delete = null;
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            delete = new DeleteMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
 | 
			
		||||
            int status = client.executeMethod(delete, REMOVE_READ_TIMEOUT, REMOVE_CONNECTION_TIMEOUT);
 | 
			
		||||
            Uri srcWebDavUri = removeChunksFolder ? client.getNewUploadsWebDavUri() : client.getNewFilesWebDavUri();
 | 
			
		||||
 | 
			
		||||
            DeleteMethod deleteMethod = new DeleteMethod(
 | 
			
		||||
                    new URL(srcWebDavUri + WebdavUtils.encodePath(mRemotePath)));
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(deleteMethod);
 | 
			
		||||
 | 
			
		||||
            result = isSuccess(status) ?
 | 
			
		||||
                    new RemoteOperationResult<>(OK) :
 | 
			
		||||
                    new RemoteOperationResult<>(deleteMethod);
 | 
			
		||||
 | 
			
		||||
            delete.getResponseBodyAsString();   // exhaust the response, although not interesting
 | 
			
		||||
            result = new RemoteOperationResult(
 | 
			
		||||
                (delete.succeeded() || status == HttpStatus.SC_NOT_FOUND),
 | 
			
		||||
                delete
 | 
			
		||||
            );
 | 
			
		||||
            Log_OC.i(TAG, "Remove " + mRemotePath + ": " + result.getLogMessage());
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Remove " + mRemotePath + ": " + result.getLogMessage(), e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (delete != null)
 | 
			
		||||
                delete.releaseConnection();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_NO_CONTENT;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -24,17 +24,17 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import android.os.RemoteException;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.DavMethodBase;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
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.RemoteOperationResult.ResultCode;
 | 
			
		||||
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.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,6 @@ public class RenameRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
    private String mNewName;
 | 
			
		||||
    private String mNewRemotePath;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
@ -88,51 +87,48 @@ public class RenameRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
 | 
			
		||||
        LocalMoveMethod move = null;
 | 
			
		||||
 | 
			
		||||
        OwnCloudVersion version = client.getOwnCloudVersion();
 | 
			
		||||
        boolean versionWithForbiddenChars =
 | 
			
		||||
        final OwnCloudVersion version = client.getOwnCloudVersion();
 | 
			
		||||
        final boolean versionWithForbiddenChars =
 | 
			
		||||
            (version != null && version.isVersionWithForbiddenCharacters());
 | 
			
		||||
        boolean noInvalidChars = FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars);
 | 
			
		||||
 | 
			
		||||
        if (noInvalidChars) {
 | 
			
		||||
            try {
 | 
			
		||||
                if (mNewName.equals(mOldName)) {
 | 
			
		||||
                    return new RemoteOperationResult(ResultCode.OK);
 | 
			
		||||
                }
 | 
			
		||||
        if(!FileUtils.isValidPath(mNewRemotePath, versionWithForbiddenChars))
 | 
			
		||||
            return new RemoteOperationResult<>(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
 | 
			
		||||
                if (targetPathIsUsed(client)) {
 | 
			
		||||
                    return new RemoteOperationResult(ResultCode.INVALID_OVERWRITE);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                move = new LocalMoveMethod(client.getWebdavUri() +
 | 
			
		||||
                    WebdavUtils.encodePath(mOldRemotePath),
 | 
			
		||||
                    client.getWebdavUri() + WebdavUtils.encodePath(mNewRemotePath));
 | 
			
		||||
                client.executeMethod(move, RENAME_READ_TIMEOUT, RENAME_CONNECTION_TIMEOUT);
 | 
			
		||||
                result = new RemoteOperationResult(move.succeeded(), move);
 | 
			
		||||
                Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " +
 | 
			
		||||
                            result.getLogMessage()
 | 
			
		||||
                );
 | 
			
		||||
                client.exhaustResponse(move.getResponseBodyAsStream());
 | 
			
		||||
 | 
			
		||||
            } catch (Exception e) {
 | 
			
		||||
                result = new RemoteOperationResult(e);
 | 
			
		||||
                Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " +
 | 
			
		||||
                    ((mNewRemotePath == null) ? mNewName : mNewRemotePath) + ": " +
 | 
			
		||||
                    result.getLogMessage(), e);
 | 
			
		||||
 | 
			
		||||
            } finally {
 | 
			
		||||
                if (move != null)
 | 
			
		||||
                    move.releaseConnection();
 | 
			
		||||
        try {
 | 
			
		||||
            if (mNewName.equals(mOldName)) {
 | 
			
		||||
                return new RemoteOperationResult<>(ResultCode.OK);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            result = new RemoteOperationResult(ResultCode.INVALID_CHARACTER_IN_NAME);
 | 
			
		||||
        }
 | 
			
		||||
            if (targetPathIsUsed(client)) {
 | 
			
		||||
                return new RemoteOperationResult<>(ResultCode.INVALID_OVERWRITE);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
            final MoveMethod move = new MoveMethod(new URL(client.getNewFilesWebDavUri() +
 | 
			
		||||
                    WebdavUtils.encodePath(mOldRemotePath)),
 | 
			
		||||
                    client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mNewRemotePath), false);
 | 
			
		||||
 | 
			
		||||
            move.setReadTimeout(RENAME_READ_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            move.setConnectionTimeout(RENAME_READ_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
 | 
			
		||||
            final int status = client.executeHttpMethod(move);
 | 
			
		||||
            final RemoteOperationResult result =
 | 
			
		||||
                    (status == HttpConstants.HTTP_CREATED || status == HttpConstants.HTTP_NO_CONTENT)
 | 
			
		||||
                            ? new RemoteOperationResult<>(ResultCode.OK)
 | 
			
		||||
                            : new RemoteOperationResult<>(move);
 | 
			
		||||
 | 
			
		||||
            Log_OC.i(TAG, "Rename " + mOldRemotePath + " to " + mNewRemotePath + ": " +
 | 
			
		||||
                    result.getLogMessage()
 | 
			
		||||
            );
 | 
			
		||||
            client.exhaustResponse(move.getResponseBodyAsStream());
 | 
			
		||||
            return result;
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            final RemoteOperationResult result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Rename " + mOldRemotePath + " to " +
 | 
			
		||||
                    ((mNewRemotePath == null) ? mNewName : mNewRemotePath) + ": " +
 | 
			
		||||
                    result.getLogMessage(), e);
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -146,27 +142,4 @@ public class RenameRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
        RemoteOperationResult exists = existenceCheckRemoteOperation.run(client);
 | 
			
		||||
        return exists.isSuccess();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Move operation
 | 
			
		||||
     */
 | 
			
		||||
    private class LocalMoveMethod extends DavMethodBase {
 | 
			
		||||
 | 
			
		||||
        public LocalMoveMethod(String uri, String dest) {
 | 
			
		||||
            super(uri);
 | 
			
		||||
            addRequestHeader(new org.apache.commons.httpclient.Header("Destination", dest));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public String getName() {
 | 
			
		||||
            return "MOVE";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        protected boolean isSuccess(int status) {
 | 
			
		||||
            return status == 201 || status == 204;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,46 +24,39 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.files;
 | 
			
		||||
 | 
			
		||||
import java.io.ByteArrayInputStream;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.PutMethod;
 | 
			
		||||
import org.apache.commons.httpclient.methods.RequestEntity;
 | 
			
		||||
import org.apache.commons.httpclient.params.HttpMethodParams;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.network.FileRequestEntity;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
import com.owncloud.android.lib.common.http.methods.webdav.PutMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.network.FileRequestBody;
 | 
			
		||||
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
 | 
			
		||||
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
 | 
			
		||||
import com.owncloud.android.lib.common.network.WebdavUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.InvalidCharacterExceptionParser;
 | 
			
		||||
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 com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicBoolean;
 | 
			
		||||
 | 
			
		||||
import okhttp3.MediaType;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remote operation performing the upload of a remote file to the ownCloud server.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class UploadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = UploadRemoteFileOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    protected static final String OC_TOTAL_LENGTH_HEADER = "OC-Total-Length";
 | 
			
		||||
    protected static final String OC_X_OC_MTIME_HEADER = "X-OC-Mtime";
 | 
			
		||||
    protected static final String IF_MATCH_HEADER = "If-Match";
 | 
			
		||||
 | 
			
		||||
    protected String mLocalPath;
 | 
			
		||||
    protected String mRemotePath;
 | 
			
		||||
    protected String mMimeType;
 | 
			
		||||
@ -74,7 +67,7 @@ public class UploadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
    protected final AtomicBoolean mCancellationRequested = new AtomicBoolean(false);
 | 
			
		||||
    protected Set<OnDatatransferProgressListener> mDataTransferListeners = new HashSet<OnDatatransferProgressListener>();
 | 
			
		||||
 | 
			
		||||
    protected RequestEntity mEntity = null;
 | 
			
		||||
    protected FileRequestBody mFileRequestBody = null;
 | 
			
		||||
 | 
			
		||||
    public UploadRemoteFileOperation(String localPath, String remotePath, String mimeType,
 | 
			
		||||
                                     String fileLastModifTimestamp) {
 | 
			
		||||
@ -92,80 +85,69 @@ public class UploadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        DefaultHttpMethodRetryHandler oldRetryHandler =
 | 
			
		||||
            (DefaultHttpMethodRetryHandler) client.getParams().getParameter(HttpMethodParams.RETRY_HANDLER);
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // prevent that uploads are retried automatically by network library
 | 
			
		||||
            client.getParams().setParameter(
 | 
			
		||||
                HttpMethodParams.RETRY_HANDLER,
 | 
			
		||||
                new DefaultHttpMethodRetryHandler(0, false)
 | 
			
		||||
            );
 | 
			
		||||
            mPutMethod = new PutMethod(
 | 
			
		||||
                    new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mRemotePath)));
 | 
			
		||||
 | 
			
		||||
            mPutMethod = new PutMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath));
 | 
			
		||||
            mPutMethod.setRetryOnConnectionFailure(false);
 | 
			
		||||
 | 
			
		||||
            if (mCancellationRequested.get()) {
 | 
			
		||||
                // the operation was cancelled before getting it's turn to be executed in the queue of uploads
 | 
			
		||||
                result = new RemoteOperationResult(new OperationCancelledException());
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult<>(new OperationCancelledException());
 | 
			
		||||
            } else {
 | 
			
		||||
                // perform the upload
 | 
			
		||||
                result = uploadFile(client);
 | 
			
		||||
                Log_OC.i(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " +
 | 
			
		||||
                        result.getLogMessage());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
 | 
			
		||||
            if (mPutMethod != null && mPutMethod.isAborted()) {
 | 
			
		||||
                result = new RemoteOperationResult(new OperationCancelledException());
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult<>(new OperationCancelledException());
 | 
			
		||||
                Log_OC.e(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " +
 | 
			
		||||
                        result.getLogMessage(), new OperationCancelledException());
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(e);
 | 
			
		||||
                result = new RemoteOperationResult<>(e);
 | 
			
		||||
                Log_OC.e(TAG, "Upload of " + mLocalPath + " to " + mRemotePath + ": " +
 | 
			
		||||
                        result.getLogMessage(), e);
 | 
			
		||||
            }
 | 
			
		||||
        } finally {
 | 
			
		||||
            // reset previous retry handler
 | 
			
		||||
            client.getParams().setParameter(
 | 
			
		||||
                HttpMethodParams.RETRY_HANDLER,
 | 
			
		||||
                oldRetryHandler
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isSuccess(int status) {
 | 
			
		||||
        return ((status == HttpStatus.SC_OK || status == HttpStatus.SC_CREATED ||
 | 
			
		||||
                status == HttpStatus.SC_NO_CONTENT));
 | 
			
		||||
    }
 | 
			
		||||
    protected RemoteOperationResult<? extends Object> uploadFile(OwnCloudClient client) throws Exception {
 | 
			
		||||
 | 
			
		||||
    protected RemoteOperationResult uploadFile(OwnCloudClient client) throws IOException {
 | 
			
		||||
        int status;
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
        try {
 | 
			
		||||
            File f = new File(mLocalPath);
 | 
			
		||||
            mEntity  = new FileRequestEntity(f, mMimeType);
 | 
			
		||||
            synchronized (mDataTransferListeners) {
 | 
			
		||||
                ((ProgressiveDataTransferer)mEntity)
 | 
			
		||||
                        .addDatatransferProgressListeners(mDataTransferListeners);
 | 
			
		||||
            }
 | 
			
		||||
            if (mRequiredEtag != null && mRequiredEtag.length() > 0) {
 | 
			
		||||
                mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\"");
 | 
			
		||||
            }
 | 
			
		||||
            mPutMethod.addRequestHeader(OC_TOTAL_LENGTH_HEADER, String.valueOf(f.length()));
 | 
			
		||||
        File fileToUpload = new File(mLocalPath);
 | 
			
		||||
 | 
			
		||||
            mPutMethod.addRequestHeader(OC_X_OC_MTIME_HEADER, mFileLastModifTimestamp);
 | 
			
		||||
        MediaType mediaType = MediaType.parse(mMimeType);
 | 
			
		||||
 | 
			
		||||
            mPutMethod.setRequestEntity(mEntity);
 | 
			
		||||
            status = client.executeMethod(mPutMethod);
 | 
			
		||||
        mFileRequestBody = new FileRequestBody(fileToUpload, mediaType);
 | 
			
		||||
 | 
			
		||||
            result = new RemoteOperationResult(
 | 
			
		||||
                isSuccess(status),
 | 
			
		||||
                mPutMethod
 | 
			
		||||
            );
 | 
			
		||||
            client.exhaustResponse(mPutMethod.getResponseBodyAsStream());
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            mPutMethod.releaseConnection(); // let the connection available for other methods
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mFileRequestBody.addDatatransferProgressListeners(mDataTransferListeners);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mRequiredEtag != null && mRequiredEtag.length() > 0) {
 | 
			
		||||
            mPutMethod.addRequestHeader(HttpConstants.IF_MATCH_HEADER, mRequiredEtag);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        mPutMethod.addRequestHeader(HttpConstants.OC_TOTAL_LENGTH_HEADER, String.valueOf(fileToUpload.length()));
 | 
			
		||||
        mPutMethod.addRequestHeader(HttpConstants.OC_X_OC_MTIME_HEADER, mFileLastModifTimestamp);
 | 
			
		||||
 | 
			
		||||
        mPutMethod.setRequestBody(mFileRequestBody);
 | 
			
		||||
 | 
			
		||||
        int status = client.executeHttpMethod(mPutMethod);
 | 
			
		||||
 | 
			
		||||
        if (isSuccess(status)) {
 | 
			
		||||
            return new RemoteOperationResult<>(OK);
 | 
			
		||||
 | 
			
		||||
        } else { // synchronization failed
 | 
			
		||||
            return new RemoteOperationResult<>(mPutMethod);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Set<OnDatatransferProgressListener> getDataTransferListeners() {
 | 
			
		||||
@ -176,8 +158,8 @@ public class UploadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.add(listener);
 | 
			
		||||
        }
 | 
			
		||||
        if (mEntity != null) {
 | 
			
		||||
            ((ProgressiveDataTransferer)mEntity).addDatatransferProgressListener(listener);
 | 
			
		||||
        if (mFileRequestBody != null) {
 | 
			
		||||
            mFileRequestBody.addDatatransferProgressListener(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@ -185,8 +167,8 @@ public class UploadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mDataTransferListeners.remove(listener);
 | 
			
		||||
        }
 | 
			
		||||
        if (mEntity != null) {
 | 
			
		||||
            ((ProgressiveDataTransferer)mEntity).removeDatatransferProgressListener(listener);
 | 
			
		||||
        if (mFileRequestBody != null) {
 | 
			
		||||
            mFileRequestBody.removeDatatransferProgressListener(listener);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@ -198,4 +180,8 @@ public class UploadRemoteFileOperation extends RemoteOperation {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
    public boolean isSuccess(int status) {
 | 
			
		||||
        return ((status == HttpConstants.HTTP_OK || status == HttpConstants.HTTP_CREATED ||
 | 
			
		||||
                status == HttpConstants.HTTP_NO_CONTENT));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,138 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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.chunks;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.methods.webdav.PutMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.network.ChunkFromFileRequestBody;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.OperationCancelledException;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.FileUtils;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.RandomAccessFile;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.nio.channels.FileChannel;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
import okhttp3.MediaType;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.http.HttpConstants.IF_MATCH_HEADER;
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remote operation performing the chunked upload of a remote file to the ownCloud server.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class ChunkedUploadRemoteFileOperation extends UploadRemoteFileOperation {
 | 
			
		||||
 | 
			
		||||
    private static final int LAST_CHUNK_TIMEOUT = 900000; //15 mins.
 | 
			
		||||
    public static final long CHUNK_SIZE = 1024000;
 | 
			
		||||
    private static final String TAG = ChunkedUploadRemoteFileOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private String mTransferId;
 | 
			
		||||
 | 
			
		||||
    public ChunkedUploadRemoteFileOperation(String transferId, String localPath, String remotePath, String mimeType,
 | 
			
		||||
                                            String requiredEtag, String fileLastModifTimestamp) {
 | 
			
		||||
        super(localPath, remotePath, mimeType, requiredEtag, fileLastModifTimestamp);
 | 
			
		||||
        mTransferId = transferId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult uploadFile(OwnCloudClient client) throws Exception {
 | 
			
		||||
        int status;
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        FileChannel channel;
 | 
			
		||||
        RandomAccessFile raf;
 | 
			
		||||
 | 
			
		||||
        File fileToUpload = new File(mLocalPath);
 | 
			
		||||
        MediaType mediaType = MediaType.parse(mMimeType);
 | 
			
		||||
 | 
			
		||||
        raf = new RandomAccessFile(fileToUpload, "r");
 | 
			
		||||
        channel = raf.getChannel();
 | 
			
		||||
 | 
			
		||||
        mFileRequestBody = new ChunkFromFileRequestBody(fileToUpload, mediaType, channel, CHUNK_SIZE);
 | 
			
		||||
 | 
			
		||||
        synchronized (mDataTransferListeners) {
 | 
			
		||||
            mFileRequestBody.addDatatransferProgressListeners(mDataTransferListeners);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        long offset = 0;
 | 
			
		||||
        String uriPrefix = client.getNewUploadsWebDavUri() + FileUtils.PATH_SEPARATOR + String.valueOf(mTransferId);
 | 
			
		||||
        long totalLength = fileToUpload.length();
 | 
			
		||||
        long chunkCount = (long) Math.ceil((double) totalLength / CHUNK_SIZE);
 | 
			
		||||
 | 
			
		||||
        for (int chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++, offset += CHUNK_SIZE) {
 | 
			
		||||
            mPutMethod = new PutMethod(
 | 
			
		||||
                    new URL(uriPrefix + FileUtils.PATH_SEPARATOR + chunkIndex)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (mRequiredEtag != null && mRequiredEtag.length() > 0) {
 | 
			
		||||
                mPutMethod.addRequestHeader(IF_MATCH_HEADER, "\"" + mRequiredEtag + "\"");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ((ChunkFromFileRequestBody) mFileRequestBody).setOffset(offset);
 | 
			
		||||
 | 
			
		||||
            if (mCancellationRequested.get()) {
 | 
			
		||||
                result = new RemoteOperationResult<>(new OperationCancelledException());
 | 
			
		||||
                break;
 | 
			
		||||
            } else {
 | 
			
		||||
                if (chunkIndex == chunkCount - 1) {
 | 
			
		||||
                    // Added a high timeout to the last chunk due to when the last chunk
 | 
			
		||||
                    // arrives to the server with the last PUT, all chunks get assembled
 | 
			
		||||
                    // within that PHP request, so last one takes longer.
 | 
			
		||||
                    mPutMethod.setReadTimeout(LAST_CHUNK_TIMEOUT, TimeUnit.MILLISECONDS);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                mPutMethod.setRequestBody(mFileRequestBody);
 | 
			
		||||
 | 
			
		||||
                status = client.executeHttpMethod(mPutMethod);
 | 
			
		||||
 | 
			
		||||
                Log_OC.d(TAG, "Upload of " + mLocalPath + " to " + mRemotePath +
 | 
			
		||||
                        ", chunk index " + chunkIndex + ", count " + chunkCount +
 | 
			
		||||
                        ", HTTP result status " + status);
 | 
			
		||||
 | 
			
		||||
                if (isSuccess(status)) {
 | 
			
		||||
                    result = new RemoteOperationResult<>(OK);
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = new RemoteOperationResult<>(mPutMethod);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (channel != null)
 | 
			
		||||
            channel.close();
 | 
			
		||||
 | 
			
		||||
        if (raf != null)
 | 
			
		||||
            raf.close();
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,45 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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.chunks;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.resources.files.CreateRemoteFolderOperation;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remote operation performing the creation of a new folder to save chunks during an upload to the ownCloud server.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class CreateRemoteChunkFolderOperation extends CreateRemoteFolderOperation {
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
     * @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.
 | 
			
		||||
     */
 | 
			
		||||
    public CreateRemoteChunkFolderOperation(String remotePath, boolean createFullPath) {
 | 
			
		||||
        super(remotePath, createFullPath);
 | 
			
		||||
        createChunksFolder = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,50 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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.chunks;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.resources.files.MoveRemoteFileOperation;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remote operation to move the file built from chunks after uploading it
 | 
			
		||||
 *
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class MoveRemoteChunksFileOperation extends MoveRemoteFileOperation {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor.
 | 
			
		||||
     *
 | 
			
		||||
     * @param srcRemotePath    Remote path of the file/folder to move.
 | 
			
		||||
     * @param targetRemotePath Remove path desired for the file/folder after moving it.
 | 
			
		||||
     * @param overwrite
 | 
			
		||||
     */
 | 
			
		||||
    public MoveRemoteChunksFileOperation(String srcRemotePath, String targetRemotePath, boolean overwrite,
 | 
			
		||||
                                         String fileLastModifTimestamp, long fileLength) {
 | 
			
		||||
        super(srcRemotePath, targetRemotePath, overwrite);
 | 
			
		||||
        moveChunkedFile = true;
 | 
			
		||||
        mFileLastModifTimestamp = fileLastModifTimestamp;
 | 
			
		||||
        mFileLength = fileLength;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,41 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   Copyright (C) 2018 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.chunks;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.resources.files.RemoveRemoteFileOperation;
 | 
			
		||||
 | 
			
		||||
public class RemoveRemoteChunksFolderOperation extends RemoveRemoteFileOperation {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructor
 | 
			
		||||
     *
 | 
			
		||||
     * @param remotePath RemotePath of the remote file or folder to remove from the server
 | 
			
		||||
     */
 | 
			
		||||
    public RemoveRemoteChunksFolderOperation(String remotePath) {
 | 
			
		||||
        super(remotePath);
 | 
			
		||||
        removeChunksFolder = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,24 +1,25 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author masensio
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -26,21 +27,29 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.shares;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.PostMethod;
 | 
			
		||||
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.nonwebdav.PostMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
 | 
			
		||||
import okhttp3.FormBody;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a new share.  This allows sharing with a user or group or as a link.
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class CreateRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
@ -177,34 +186,22 @@ public class CreateRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
        mPublicUpload = publicUpload;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isGettingShareDetails() {
 | 
			
		||||
        return mGetShareDetails;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setGetShareDetails(boolean set) {
 | 
			
		||||
        mGetShareDetails = set;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status = -1;
 | 
			
		||||
 | 
			
		||||
        PostMethod post = null;
 | 
			
		||||
    protected RemoteOperationResult<ShareParserResult> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<ShareParserResult> result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // Post Method
 | 
			
		||||
            post = new PostMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
 | 
			
		||||
 | 
			
		||||
            post.setRequestHeader("Content-Type",
 | 
			
		||||
                    "application/x-www-form-urlencoded; charset=utf-8"); // necessary for special characters
 | 
			
		||||
 | 
			
		||||
            post.addParameter(PARAM_PATH, mRemoteFilePath);
 | 
			
		||||
            post.addParameter(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue()));
 | 
			
		||||
            post.addParameter(PARAM_SHARE_WITH, mShareWith);
 | 
			
		||||
            FormBody.Builder formBodyBuilder = new FormBody.Builder()
 | 
			
		||||
                    .add(PARAM_PATH, mRemoteFilePath)
 | 
			
		||||
                    .add(PARAM_SHARE_TYPE, Integer.toString(mShareType.getValue()))
 | 
			
		||||
                    .add(PARAM_SHARE_WITH, mShareWith);
 | 
			
		||||
 | 
			
		||||
            if (mName.length() > 0) {
 | 
			
		||||
                post.addParameter(PARAM_NAME, mName);
 | 
			
		||||
                formBodyBuilder.add(PARAM_NAME, mName);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (mExpirationDateInMillis > 0) {
 | 
			
		||||
@ -212,37 +209,47 @@ public class CreateRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
                Calendar expirationDate = Calendar.getInstance();
 | 
			
		||||
                expirationDate.setTimeInMillis(mExpirationDateInMillis);
 | 
			
		||||
                String formattedExpirationDate = dateFormat.format(expirationDate.getTime());
 | 
			
		||||
                post.addParameter(PARAM_EXPIRATION_DATE, formattedExpirationDate);
 | 
			
		||||
                formBodyBuilder.add(PARAM_EXPIRATION_DATE, formattedExpirationDate);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (mPublicUpload) {
 | 
			
		||||
                post.addParameter(PARAM_PUBLIC_UPLOAD, Boolean.toString(true));
 | 
			
		||||
                formBodyBuilder.add(PARAM_PUBLIC_UPLOAD, Boolean.toString(true));
 | 
			
		||||
            }
 | 
			
		||||
            if (mPassword != null && mPassword.length() > 0) {
 | 
			
		||||
                post.addParameter(PARAM_PASSWORD, mPassword);
 | 
			
		||||
                formBodyBuilder.add(PARAM_PASSWORD, mPassword);
 | 
			
		||||
            }
 | 
			
		||||
            if (OCShare.DEFAULT_PERMISSION != mPermissions) {
 | 
			
		||||
                post.addParameter(PARAM_PERMISSIONS, Integer.toString(mPermissions));
 | 
			
		||||
                formBodyBuilder.add(PARAM_PERMISSIONS, Integer.toString(mPermissions));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            post.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH);
 | 
			
		||||
 | 
			
		||||
            status = client.executeMethod(post);
 | 
			
		||||
            PostMethod postMethod = new PostMethod(new URL(uriBuilder.build().toString()));
 | 
			
		||||
 | 
			
		||||
            postMethod.setRequestBody(formBodyBuilder.build());
 | 
			
		||||
 | 
			
		||||
            postMethod.setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8);
 | 
			
		||||
            postMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(postMethod);
 | 
			
		||||
 | 
			
		||||
            ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
                    new ShareXMLParser()
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                String response = post.getResponseBodyAsString();
 | 
			
		||||
 | 
			
		||||
                ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
                        new ShareXMLParser()
 | 
			
		||||
                );
 | 
			
		||||
                parser.setOneOrMoreSharesRequired(true);
 | 
			
		||||
                parser.setOwnCloudVersion(client.getOwnCloudVersion());
 | 
			
		||||
                parser.setServerBaseUri(client.getBaseUri());
 | 
			
		||||
                result = parser.parse(response);
 | 
			
		||||
                result = parser.parse(postMethod.getResponseBodyAsString());
 | 
			
		||||
 | 
			
		||||
                if (result.isSuccess() && mGetShareDetails) {
 | 
			
		||||
 | 
			
		||||
                    // TODO Use executeHttpMethod
 | 
			
		||||
                    // retrieve more info - POST only returns the index of the new share
 | 
			
		||||
                    OCShare emptyShare = (OCShare) result.getData().get(0);
 | 
			
		||||
                    OCShare emptyShare = result.getData().getShares().get(0);
 | 
			
		||||
                    GetRemoteShareOperation getInfo = new GetRemoteShareOperation(
 | 
			
		||||
                            emptyShare.getRemoteId()
 | 
			
		||||
                    );
 | 
			
		||||
@ -250,23 +257,17 @@ public class CreateRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, post);
 | 
			
		||||
                result = parser.parse(postMethod.getResponseBodyAsString());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while Creating New Share", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (post != null) {
 | 
			
		||||
                post.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,23 +1,24 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -25,19 +26,25 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.shares;
 | 
			
		||||
 | 
			
		||||
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.nonwebdav.GetMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the data about a Share resource, known its remote ID.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class GetRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
public class GetRemoteShareOperation extends RemoteOperation<ShareParserResult> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteShareOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -48,53 +55,43 @@ public class GetRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
        mRemoteId = remoteId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status = -1;
 | 
			
		||||
        RemoteOperationResult<ShareParserResult> result;
 | 
			
		||||
 | 
			
		||||
        // Get Method
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
 | 
			
		||||
        // Get the response
 | 
			
		||||
        try {
 | 
			
		||||
            get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + "/" + Long.toString(mRemoteId));
 | 
			
		||||
            get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH);
 | 
			
		||||
            uriBuilder.appendEncodedPath(Long.toString(mRemoteId));
 | 
			
		||||
 | 
			
		||||
            status = client.executeMethod(get);
 | 
			
		||||
            GetMethod getMethod = new GetMethod(new URL(uriBuilder.build().toString()));
 | 
			
		||||
            getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(getMethod);
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
 | 
			
		||||
                // Parse xml response and obtain the list of shares
 | 
			
		||||
                ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
                    new ShareXMLParser()
 | 
			
		||||
                        new ShareXMLParser()
 | 
			
		||||
                );
 | 
			
		||||
                parser.setOneOrMoreSharesRequired(true);
 | 
			
		||||
                parser.setOwnCloudVersion(client.getOwnCloudVersion());
 | 
			
		||||
                parser.setServerBaseUri(client.getBaseUri());
 | 
			
		||||
                result = parser.parse(response);
 | 
			
		||||
                result = parser.parse(getMethod.getResponseBodyAsString());
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, get);
 | 
			
		||||
                result = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while getting remote shares ", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null) {
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -2,7 +2,8 @@
 | 
			
		||||
 *
 | 
			
		||||
 *   @author masensio
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -30,17 +31,20 @@ package com.owncloud.android.lib.resources.shares;
 | 
			
		||||
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.nonwebdav.GetMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
import org.json.JSONArray;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by masensio on 08/10/2015.
 | 
			
		||||
 *
 | 
			
		||||
@ -61,8 +65,12 @@ import java.util.ArrayList;
 | 
			
		||||
 *
 | 
			
		||||
 * Status codes:
 | 
			
		||||
 *    100 - successful
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class GetRemoteShareesOperation extends RemoteOperation{
 | 
			
		||||
public class GetRemoteShareesOperation extends RemoteOperation<ArrayList<JSONObject>> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteShareesOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -80,7 +88,6 @@ public class GetRemoteShareesOperation extends RemoteOperation{
 | 
			
		||||
    private static final String VALUE_FORMAT = "json";
 | 
			
		||||
    private static final String VALUE_ITEM_TYPE = "file";         //  to get the server search for users / groups
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // JSON Node names
 | 
			
		||||
    private static final String NODE_OCS = "ocs";
 | 
			
		||||
    private static final String NODE_DATA = "data";
 | 
			
		||||
@ -111,29 +118,27 @@ public class GetRemoteShareesOperation extends RemoteOperation{
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status;
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
    protected RemoteOperationResult<ArrayList<JSONObject>> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<ArrayList<JSONObject>> result;
 | 
			
		||||
 | 
			
		||||
        try{
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(OCS_ROUTE);
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT);
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_ITEM_TYPE, VALUE_ITEM_TYPE);
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_SEARCH, mSearchString);
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_PAGE, String.valueOf(mPage));
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_PER_PAGE, String.valueOf(mPerPage));
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon()
 | 
			
		||||
                    .appendEncodedPath(OCS_ROUTE)
 | 
			
		||||
                    .appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT)
 | 
			
		||||
                    .appendQueryParameter(PARAM_ITEM_TYPE, VALUE_ITEM_TYPE)
 | 
			
		||||
                    .appendQueryParameter(PARAM_SEARCH, mSearchString)
 | 
			
		||||
                    .appendQueryParameter(PARAM_PAGE, String.valueOf(mPage))
 | 
			
		||||
                    .appendQueryParameter(PARAM_PER_PAGE, String.valueOf(mPerPage));
 | 
			
		||||
 | 
			
		||||
            // Get Method
 | 
			
		||||
            get = new GetMethod(uriBuilder.build().toString());
 | 
			
		||||
            get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            GetMethod getMethod = new GetMethod(new URL(uriBuilder.build().toString()));
 | 
			
		||||
 | 
			
		||||
            status = client.executeMethod(get);
 | 
			
		||||
            getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(getMethod);
 | 
			
		||||
            String response = getMethod.getResponseBodyAsString();
 | 
			
		||||
 | 
			
		||||
            if(isSuccess(status)) {
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
                Log_OC.d(TAG, "Successful response: " + response);
 | 
			
		||||
 | 
			
		||||
                // Parse the response
 | 
			
		||||
@ -156,7 +161,7 @@ public class GetRemoteShareesOperation extends RemoteOperation{
 | 
			
		||||
                        respPartialRemotes
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                ArrayList<Object> data = new ArrayList<Object>(); // For result data
 | 
			
		||||
                ArrayList<JSONObject> data = new ArrayList<>(); // For result data
 | 
			
		||||
                for (int i=0; i<6; i++) {
 | 
			
		||||
                    for(int j=0; j< jsonResults[i].length(); j++){
 | 
			
		||||
                        JSONObject jsonResult = jsonResults[i].getJSONObject(j);
 | 
			
		||||
@ -165,15 +170,13 @@ public class GetRemoteShareesOperation extends RemoteOperation{
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Result
 | 
			
		||||
                result = new RemoteOperationResult(true, get);
 | 
			
		||||
                result = new RemoteOperationResult<>(OK);
 | 
			
		||||
                result.setData(data);
 | 
			
		||||
 | 
			
		||||
                Log_OC.d(TAG, "*** Get Users or groups completed " );
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, get);
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
                result = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
                Log_OC.e(TAG, "Failed response while getting users/groups from the server ");
 | 
			
		||||
                if (response != null) {
 | 
			
		||||
                    Log_OC.e(TAG, "*** status code: " + status + "; response message: " + response);
 | 
			
		||||
@ -181,20 +184,15 @@ public class GetRemoteShareesOperation extends RemoteOperation{
 | 
			
		||||
                    Log_OC.e(TAG, "*** status code: " + status);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while getting users/groups", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null) {
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,24 +1,25 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author masensio
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -26,21 +27,27 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.shares;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.NameValuePair;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
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.nonwebdav.GetMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provide a list shares for a specific file.
 | 
			
		||||
 * The input is the full path of the desired file.
 | 
			
		||||
 * The output is a list of everyone who has the file shared with them.
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class GetRemoteSharesForFileOperation extends RemoteOperation {
 | 
			
		||||
public class GetRemoteSharesForFileOperation extends RemoteOperation<ShareParserResult> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteSharesForFileOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -70,60 +77,48 @@ public class GetRemoteSharesForFileOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status = -1;
 | 
			
		||||
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
    protected RemoteOperationResult<ShareParserResult> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<ShareParserResult> result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // Get Method
 | 
			
		||||
            get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
 | 
			
		||||
 | 
			
		||||
            // Add Parameters to Get Method
 | 
			
		||||
            get.setQueryString(new NameValuePair[]{
 | 
			
		||||
                new NameValuePair(PARAM_PATH, mRemoteFilePath),
 | 
			
		||||
                new NameValuePair(PARAM_RESHARES, String.valueOf(mReshares)),
 | 
			
		||||
                new NameValuePair(PARAM_SUBFILES, String.valueOf(mSubfiles))
 | 
			
		||||
            });
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH);
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_PATH, mRemoteFilePath);
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_RESHARES, String.valueOf(mReshares));
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_SUBFILES, String.valueOf(mSubfiles));
 | 
			
		||||
 | 
			
		||||
            get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            GetMethod getMethod = new GetMethod(new URL(uriBuilder.build().toString()));
 | 
			
		||||
 | 
			
		||||
            status = client.executeMethod(get);
 | 
			
		||||
            getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(getMethod);
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
 | 
			
		||||
                // Parse xml response and obtain the list of shares
 | 
			
		||||
                ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
                    new ShareXMLParser()
 | 
			
		||||
                );
 | 
			
		||||
                parser.setOwnCloudVersion(client.getOwnCloudVersion());
 | 
			
		||||
                parser.setServerBaseUri(client.getBaseUri());
 | 
			
		||||
                result = parser.parse(response);
 | 
			
		||||
                result = parser.parse(getMethod.getResponseBodyAsString());
 | 
			
		||||
 | 
			
		||||
                if (result.isSuccess()) {
 | 
			
		||||
                    Log_OC.d(TAG, "Got " + result.getData().size() + " shares");
 | 
			
		||||
                    Log_OC.d(TAG, "Got " + result.getData().getShares().size() + " shares");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, get);
 | 
			
		||||
                result = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while getting shares", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null) {
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,24 +1,23 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author masensio
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -26,42 +25,47 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.shares;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
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.nonwebdav.GetMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the data from the server about ALL the known shares owned by the requester.
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class GetRemoteSharesOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteSharesOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public GetRemoteSharesOperation() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status = -1;
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
 | 
			
		||||
        // Get Method
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
 | 
			
		||||
        // Get the response
 | 
			
		||||
        try {
 | 
			
		||||
            get = new GetMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH);
 | 
			
		||||
            get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            status = client.executeMethod(get);
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH);
 | 
			
		||||
 | 
			
		||||
            GetMethod getMethod = new GetMethod(
 | 
			
		||||
                    new URL(client.getBaseUri() + ShareUtils.SHARING_API_PATH)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(getMethod);
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
 | 
			
		||||
                // Parse xml response and obtain the list of shares
 | 
			
		||||
                ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
@ -69,26 +73,19 @@ public class GetRemoteSharesOperation extends RemoteOperation {
 | 
			
		||||
                );
 | 
			
		||||
                parser.setOwnCloudVersion(client.getOwnCloudVersion());
 | 
			
		||||
                parser.setServerBaseUri(client.getBaseUri());
 | 
			
		||||
                result = parser.parse(response);
 | 
			
		||||
                result = parser.parse(getMethod.getResponseBodyAsString());
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, get);
 | 
			
		||||
                result = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while getting remote shares ", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null) {
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,24 +1,25 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author masensio
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -26,16 +27,23 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.shares;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.DeleteMethod;
 | 
			
		||||
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.nonwebdav.DeleteMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove a share
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class RemoveRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
@ -52,51 +60,49 @@ public class RemoveRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    public RemoveRemoteShareOperation(int remoteShareId) {
 | 
			
		||||
        mRemoteShareId = remoteShareId;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status = -1;
 | 
			
		||||
 | 
			
		||||
        DeleteMethod delete = null;
 | 
			
		||||
        RemoteOperationResult result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            String id = "/" + String.valueOf(mRemoteShareId);
 | 
			
		||||
            delete = new DeleteMethod(client.getBaseUri() + ShareUtils.SHARING_API_PATH + id);
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH);
 | 
			
		||||
            uriBuilder.appendEncodedPath(String.valueOf(mRemoteShareId));
 | 
			
		||||
 | 
			
		||||
            delete.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            DeleteMethod deleteMethod = new DeleteMethod(
 | 
			
		||||
                    new URL(uriBuilder.build().toString())
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            status = client.executeMethod(delete);
 | 
			
		||||
            deleteMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(deleteMethod);
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                String response = delete.getResponseBodyAsString();
 | 
			
		||||
 | 
			
		||||
                // Parse xml response and obtain the list of shares
 | 
			
		||||
                ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
                    new ShareXMLParser()
 | 
			
		||||
                        new ShareXMLParser()
 | 
			
		||||
                );
 | 
			
		||||
                result = parser.parse(response);
 | 
			
		||||
                result = parser.parse(deleteMethod.getResponseBodyAsString());
 | 
			
		||||
 | 
			
		||||
                Log_OC.d(TAG, "Unshare " + id + ": " + result.getLogMessage());
 | 
			
		||||
                Log_OC.d(TAG, "Unshare " + mRemoteShareId + ": " + result.getLogMessage());
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, delete);
 | 
			
		||||
                result = new RemoteOperationResult<>(deleteMethod);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            Log_OC.e(TAG, "Unshare Link Exception " + result.getLogMessage(), e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (delete != null)
 | 
			
		||||
                delete.releaseConnection();
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Unshare Link Exception " + result.getLogMessage(), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author Christian Schabesberger
 | 
			
		||||
 *   Copyright (C) 2018 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.shares;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
public class ShareParserResult {
 | 
			
		||||
    private ArrayList<OCShare> shares;
 | 
			
		||||
    private String parserMessage;
 | 
			
		||||
 | 
			
		||||
    public ShareParserResult(ArrayList<OCShare> shares, String parserMessage) {
 | 
			
		||||
        this.shares = shares;
 | 
			
		||||
        this.parserMessage = parserMessage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ArrayList<OCShare> getShares() {
 | 
			
		||||
        return shares;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getParserMessage() {
 | 
			
		||||
        return parserMessage;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,8 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   @author David González Verdugo
 | 
			
		||||
 *   @author Christian Schabesberger
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -65,13 +67,13 @@ public class ShareToRemoteOperationResultParser {
 | 
			
		||||
        mServerBaseUri = serverBaseURi;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public RemoteOperationResult parse(String serverResponse) {
 | 
			
		||||
    public RemoteOperationResult<ShareParserResult> parse(String serverResponse) {
 | 
			
		||||
        if (serverResponse == null || serverResponse.length() == 0) {
 | 
			
		||||
            return new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
            return new RemoteOperationResult<>(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        ArrayList<Object> resultData = new ArrayList<Object>();
 | 
			
		||||
        RemoteOperationResult<ShareParserResult> result;
 | 
			
		||||
        final ArrayList<OCShare> resultData = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // Parse xml response and obtain the list of shares
 | 
			
		||||
@ -84,17 +86,16 @@ public class ShareToRemoteOperationResultParser {
 | 
			
		||||
 | 
			
		||||
            if (mShareXmlParser.isSuccess()) {
 | 
			
		||||
                if ((shares != null && shares.size() > 0) || !mOneOrMoreSharesRequired) {
 | 
			
		||||
                    result = new RemoteOperationResult(RemoteOperationResult.ResultCode.OK);
 | 
			
		||||
                    result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.OK);
 | 
			
		||||
                    if (shares != null) {
 | 
			
		||||
                        for (OCShare share : shares) {
 | 
			
		||||
                            resultData.add(share);
 | 
			
		||||
                            // build the share link if not in the response
 | 
			
		||||
                            // (needed for OC servers < 9.0.0, see ShareXMLParser.java#line256)
 | 
			
		||||
                            if (share.getShareType() == ShareType.PUBLIC_LINK &&
 | 
			
		||||
                                    (share.getShareLink() == null ||
 | 
			
		||||
                                            share.getShareLink().length() <= 0) &&
 | 
			
		||||
                                    share.getToken().length() > 0
 | 
			
		||||
                                    ) {
 | 
			
		||||
                            if (share.getShareType() == ShareType.PUBLIC_LINK
 | 
			
		||||
                                    && (share.getShareLink() == null
 | 
			
		||||
                                        || share.getShareLink().length() <= 0)
 | 
			
		||||
                                    && share.getToken().length() > 0) {
 | 
			
		||||
                                if (mServerBaseUri != null) {
 | 
			
		||||
                                    String sharingLinkPath = ShareUtils.getSharingLinkPath(mOwnCloudVersion);
 | 
			
		||||
                                    share.setShareLink(mServerBaseUri + sharingLinkPath + share.getToken());
 | 
			
		||||
@ -104,43 +105,38 @@ public class ShareToRemoteOperationResultParser {
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    result.setData(resultData);
 | 
			
		||||
                    result.setData(new ShareParserResult(resultData, ""));
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
                    result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
                    Log_OC.e(TAG, "Successful status with no share in the response");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else if (mShareXmlParser.isWrongParameter()){
 | 
			
		||||
                result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER);
 | 
			
		||||
                resultData.add(mShareXmlParser.getMessage());
 | 
			
		||||
                result.setData(resultData);
 | 
			
		||||
                result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.SHARE_WRONG_PARAMETER);
 | 
			
		||||
                result.setData(new ShareParserResult(null, mShareXmlParser.getMessage()));
 | 
			
		||||
 | 
			
		||||
            } else if (mShareXmlParser.isNotFound()){
 | 
			
		||||
                result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND);
 | 
			
		||||
                resultData.add(mShareXmlParser.getMessage());
 | 
			
		||||
                result.setData(resultData);
 | 
			
		||||
                result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.SHARE_NOT_FOUND);
 | 
			
		||||
                result.setData(new ShareParserResult(null, mShareXmlParser.getMessage()));
 | 
			
		||||
 | 
			
		||||
            } else if (mShareXmlParser.isForbidden()) {
 | 
			
		||||
                result = new RemoteOperationResult(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN);
 | 
			
		||||
                resultData.add(mShareXmlParser.getMessage());
 | 
			
		||||
                result.setData(resultData);
 | 
			
		||||
                result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.SHARE_FORBIDDEN);
 | 
			
		||||
                result.setData(new ShareParserResult(null, mShareXmlParser.getMessage()));
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
 | 
			
		||||
                result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (XmlPullParserException e) {
 | 
			
		||||
            Log_OC.e(TAG, "Error parsing response from server ", e);
 | 
			
		||||
            result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
            result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            Log_OC.e(TAG, "Error reading response from server ", e);
 | 
			
		||||
            result = new RemoteOperationResult(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
            result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.WRONG_SERVER_RESPONSE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -30,13 +30,14 @@ import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 | 
			
		||||
 * Contains Constants for Share Operation
 | 
			
		||||
 * 
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ShareUtils {
 | 
			
		||||
 | 
			
		||||
	// OCS Route
 | 
			
		||||
	public static final String SHARING_API_PATH ="/ocs/v1.php/apps/files_sharing/api/v1/shares"; 
 | 
			
		||||
	public static final String SHARING_API_PATH ="ocs/v2.php/apps/files_sharing/api/v1/shares";
 | 
			
		||||
 | 
			
		||||
    // String to build the link with the token of a share:
 | 
			
		||||
    public static final String SHARING_LINK_PATH_BEFORE_VERSION_8 = "/public.php?service=files&t=";
 | 
			
		||||
@ -49,5 +50,4 @@ public class ShareUtils {
 | 
			
		||||
            return SHARING_LINK_PATH_BEFORE_VERSION_8;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -41,7 +41,7 @@ import com.owncloud.android.lib.resources.files.FileUtils;
 | 
			
		||||
/**
 | 
			
		||||
 * Parser for Share API Response
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 *
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class ShareXMLParser {
 | 
			
		||||
@ -82,7 +82,7 @@ public class ShareXMLParser {
 | 
			
		||||
 | 
			
		||||
	private static final String TYPE_FOLDER = "folder";
 | 
			
		||||
	
 | 
			
		||||
	private static final int SUCCESS = 100;
 | 
			
		||||
	private static final int SUCCESS = 200;
 | 
			
		||||
	private static final int ERROR_WRONG_PARAMETER = 400;
 | 
			
		||||
	private static final int ERROR_FORBIDDEN = 403;
 | 
			
		||||
	private static final int ERROR_NOT_FOUND = 404;
 | 
			
		||||
@ -172,7 +172,7 @@ public class ShareXMLParser {
 | 
			
		||||
	 */
 | 
			
		||||
	private ArrayList<OCShare> readOCS (XmlPullParser parser) throws XmlPullParserException,
 | 
			
		||||
			IOException {
 | 
			
		||||
		ArrayList<OCShare> shares = new ArrayList<OCShare>();
 | 
			
		||||
		ArrayList<OCShare> shares = new ArrayList<>();
 | 
			
		||||
		parser.require(XmlPullParser.START_TAG,  ns , NODE_OCS);
 | 
			
		||||
		while (parser.next() != XmlPullParser.END_TAG) {
 | 
			
		||||
			if (parser.getEventType() != XmlPullParser.START_TAG) {
 | 
			
		||||
@ -190,8 +190,6 @@ public class ShareXMLParser {
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		return shares;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@ -439,5 +437,4 @@ public class ShareXMLParser {
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -26,32 +26,32 @@
 | 
			
		||||
package com.owncloud.android.lib.resources.shares;
 | 
			
		||||
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
import android.util.Pair;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.http.HttpConstants;
 | 
			
		||||
import com.owncloud.android.lib.common.http.methods.nonwebdav.PutMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.PutMethod;
 | 
			
		||||
import org.apache.commons.httpclient.methods.StringRequestEntity;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.text.DateFormat;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Calendar;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
 | 
			
		||||
import okhttp3.FormBody;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Updates parameters of an existing Share resource, known its remote ID.
 | 
			
		||||
 * <p/>
 | 
			
		||||
 *
 | 
			
		||||
 * Allow updating several parameters, triggering a request to the server per parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class UpdateRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
public class UpdateRemoteShareOperation extends RemoteOperation<ShareParserResult> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteShareOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -163,104 +163,77 @@ public class UpdateRemoteShareOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status;
 | 
			
		||||
 | 
			
		||||
        /// prepare array of parameters to update
 | 
			
		||||
        List<Pair<String, String>> parametersToUpdate = new ArrayList<>();
 | 
			
		||||
        if (mName != null) {
 | 
			
		||||
            parametersToUpdate.add(new Pair<>(PARAM_NAME, mName));
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (mPassword != null) {
 | 
			
		||||
            parametersToUpdate.add(new Pair<>(PARAM_PASSWORD, mPassword));
 | 
			
		||||
        }
 | 
			
		||||
        if (mExpirationDateInMillis < 0) {
 | 
			
		||||
            // clear expiration date
 | 
			
		||||
            parametersToUpdate.add(new Pair<>(PARAM_EXPIRATION_DATE, ""));
 | 
			
		||||
 | 
			
		||||
        } else if (mExpirationDateInMillis > 0) {
 | 
			
		||||
            // set expiration date
 | 
			
		||||
            DateFormat dateFormat = new SimpleDateFormat(FORMAT_EXPIRATION_DATE, Locale.GERMAN);
 | 
			
		||||
            Calendar expirationDate = Calendar.getInstance();
 | 
			
		||||
            expirationDate.setTimeInMillis(mExpirationDateInMillis);
 | 
			
		||||
            String formattedExpirationDate = dateFormat.format(expirationDate.getTime());
 | 
			
		||||
            parametersToUpdate.add(new Pair<>(PARAM_EXPIRATION_DATE, formattedExpirationDate));
 | 
			
		||||
 | 
			
		||||
        } // else, ignore - no update
 | 
			
		||||
 | 
			
		||||
        if (mPublicUpload != null) {
 | 
			
		||||
            parametersToUpdate.add(new Pair<>(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // IMPORTANT: permissions parameter needs to be updated after mPublicUpload parameter,
 | 
			
		||||
        // otherwise they would be set always as 1 (READ) in the server when mPublicUpload was updated
 | 
			
		||||
        if (mPermissions > 0) {
 | 
			
		||||
            // set permissions
 | 
			
		||||
            parametersToUpdate.add(new Pair<>(PARAM_PERMISSIONS, Integer.toString(mPermissions)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// perform required PUT requests
 | 
			
		||||
        PutMethod put = null;
 | 
			
		||||
        String uriString;
 | 
			
		||||
    protected RemoteOperationResult<ShareParserResult> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<ShareParserResult> result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            FormBody.Builder formBodyBuilder = new FormBody.Builder();
 | 
			
		||||
 | 
			
		||||
            // Parameters to update
 | 
			
		||||
            if (mName != null) {
 | 
			
		||||
                formBodyBuilder.add(PARAM_NAME, mName);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (mExpirationDateInMillis < 0) {
 | 
			
		||||
                // clear expiration date
 | 
			
		||||
                formBodyBuilder.add(PARAM_EXPIRATION_DATE, "");
 | 
			
		||||
 | 
			
		||||
            } else if (mExpirationDateInMillis > 0) {
 | 
			
		||||
                // set expiration date
 | 
			
		||||
                DateFormat dateFormat = new SimpleDateFormat(FORMAT_EXPIRATION_DATE, Locale.GERMAN);
 | 
			
		||||
                Calendar expirationDate = Calendar.getInstance();
 | 
			
		||||
                expirationDate.setTimeInMillis(mExpirationDateInMillis);
 | 
			
		||||
                String formattedExpirationDate = dateFormat.format(expirationDate.getTime());
 | 
			
		||||
                formBodyBuilder.add(PARAM_EXPIRATION_DATE, formattedExpirationDate);
 | 
			
		||||
            } // else, ignore - no update
 | 
			
		||||
 | 
			
		||||
            if (mPublicUpload != null) {
 | 
			
		||||
                formBodyBuilder.add(PARAM_PUBLIC_UPLOAD, Boolean.toString(mPublicUpload));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // IMPORTANT: permissions parameter needs to be updated after mPublicUpload parameter,
 | 
			
		||||
            // otherwise they would be set always as 1 (READ) in the server when mPublicUpload was updated
 | 
			
		||||
            if (mPermissions > 0) {
 | 
			
		||||
                // set permissions
 | 
			
		||||
                formBodyBuilder.add(PARAM_PERMISSIONS, Integer.toString(mPermissions));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
            Uri.Builder uriBuilder = requestUri.buildUpon();
 | 
			
		||||
            uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH.substring(1));
 | 
			
		||||
            uriBuilder.appendEncodedPath(ShareUtils.SHARING_API_PATH);
 | 
			
		||||
            uriBuilder.appendEncodedPath(Long.toString(mRemoteId));
 | 
			
		||||
            uriString = uriBuilder.build().toString();
 | 
			
		||||
 | 
			
		||||
            for (Pair<String, String> parameter : parametersToUpdate) {
 | 
			
		||||
                if (put != null) {
 | 
			
		||||
                    put.releaseConnection();
 | 
			
		||||
                }
 | 
			
		||||
                put = new PutMethod(uriString);
 | 
			
		||||
                put.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
                put.setRequestEntity(new StringRequestEntity(
 | 
			
		||||
                        parameter.first + "=" + parameter.second,
 | 
			
		||||
                        ENTITY_CONTENT_TYPE,
 | 
			
		||||
                        ENTITY_CHARSET
 | 
			
		||||
                ));
 | 
			
		||||
            PutMethod putMethod = new PutMethod(new URL(uriBuilder.build().toString()));
 | 
			
		||||
 | 
			
		||||
                status = client.executeMethod(put);
 | 
			
		||||
            putMethod.setRequestBody(formBodyBuilder.build());
 | 
			
		||||
 | 
			
		||||
                if (status == HttpStatus.SC_OK) {
 | 
			
		||||
                    String response = put.getResponseBodyAsString();
 | 
			
		||||
            putMethod.setRequestHeader(HttpConstants.CONTENT_TYPE_HEADER, HttpConstants.CONTENT_TYPE_URLENCODED_UTF8);
 | 
			
		||||
            putMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
                    // Parse xml response
 | 
			
		||||
                    ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
                            new ShareXMLParser()
 | 
			
		||||
                    );
 | 
			
		||||
                    parser.setOwnCloudVersion(client.getOwnCloudVersion());
 | 
			
		||||
                    parser.setServerBaseUri(client.getBaseUri());
 | 
			
		||||
                    result = parser.parse(response);
 | 
			
		||||
            int status = client.executeHttpMethod(putMethod);
 | 
			
		||||
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = new RemoteOperationResult(false, put);
 | 
			
		||||
                }
 | 
			
		||||
                if (!result.isSuccess() &&
 | 
			
		||||
                    !PARAM_NAME.equals(parameter.first)
 | 
			
		||||
                        // fail in "name" parameter will be ignored; requires OCX, will fail
 | 
			
		||||
                        // fails in previous versions
 | 
			
		||||
                    ) {
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                // Parse xml response
 | 
			
		||||
                ShareToRemoteOperationResultParser parser = new ShareToRemoteOperationResultParser(
 | 
			
		||||
                        new ShareXMLParser()
 | 
			
		||||
                );
 | 
			
		||||
                parser.setOwnCloudVersion(client.getOwnCloudVersion());
 | 
			
		||||
                parser.setServerBaseUri(client.getBaseUri());
 | 
			
		||||
                result = parser.parse(putMethod.getResponseBodyAsString());
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult<>(putMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while updating remote share ", e);
 | 
			
		||||
            if (put != null) {
 | 
			
		||||
                put.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (put != null) {
 | 
			
		||||
                put.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while Creating New Share", e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -24,33 +24,37 @@
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.status;
 | 
			
		||||
 | 
			
		||||
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.nonwebdav.GetMethod;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get the Capabilities from the server
 | 
			
		||||
 *
 | 
			
		||||
 * Save in Result.getData in a OCCapability object
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class GetRemoteCapabilitiesOperation extends RemoteOperation {
 | 
			
		||||
public class GetRemoteCapabilitiesOperation extends RemoteOperation<OCCapability> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteCapabilitiesOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // OCS Routes
 | 
			
		||||
    private static final String OCS_ROUTE = "ocs/v1.php/cloud/capabilities";
 | 
			
		||||
    private static final String OCS_ROUTE = "ocs/v2.php/cloud/capabilities";
 | 
			
		||||
 | 
			
		||||
    // Arguments - names
 | 
			
		||||
    private static final String PARAM_FORMAT = "format";
 | 
			
		||||
@ -115,10 +119,8 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status;
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
    protected RemoteOperationResult<OCCapability> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<OCCapability> result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            Uri requestUri = client.getBaseUri();
 | 
			
		||||
@ -126,14 +128,14 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation {
 | 
			
		||||
            uriBuilder.appendEncodedPath(OCS_ROUTE);    // avoid starting "/" in this method
 | 
			
		||||
            uriBuilder.appendQueryParameter(PARAM_FORMAT, VALUE_FORMAT);
 | 
			
		||||
 | 
			
		||||
            // Get Method
 | 
			
		||||
            get = new GetMethod(uriBuilder.build().toString());
 | 
			
		||||
            get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            GetMethod getMethod = new GetMethod(new URL(uriBuilder.build().toString()));
 | 
			
		||||
 | 
			
		||||
            status = client.executeMethod(get);
 | 
			
		||||
            getMethod.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(getMethod);
 | 
			
		||||
 | 
			
		||||
            String response = getMethod.getResponseBodyAsString();
 | 
			
		||||
            if(isSuccess(status)) {
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
                Log_OC.d(TAG, "Successful response: " + response);
 | 
			
		||||
 | 
			
		||||
                // Parse the response
 | 
			
		||||
@ -148,7 +150,6 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation {
 | 
			
		||||
                String message = respMeta.getString(PROPERTY_MESSAGE);
 | 
			
		||||
 | 
			
		||||
                if (statusProp) {
 | 
			
		||||
                    ArrayList<Object> data = new ArrayList<Object>(); // For result data
 | 
			
		||||
                    OCCapability capability = new OCCapability();
 | 
			
		||||
                    // Add Version
 | 
			
		||||
                    if (respData.has(NODE_VERSION)) {
 | 
			
		||||
@ -254,20 +255,18 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation {
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    // Result
 | 
			
		||||
                    data.add(capability);
 | 
			
		||||
                    result = new RemoteOperationResult(true, get);
 | 
			
		||||
                    result.setData(data);
 | 
			
		||||
                    result = new RemoteOperationResult<>(OK);
 | 
			
		||||
                    result.setData(capability);
 | 
			
		||||
 | 
			
		||||
                    Log_OC.d(TAG, "*** Get Capabilities completed ");
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = new RemoteOperationResult(statusProp, statuscode, null, null);
 | 
			
		||||
                    result = new RemoteOperationResult<>(statuscode, message, null);
 | 
			
		||||
                    Log_OC.e(TAG, "Failed response while getting capabilities from the server ");
 | 
			
		||||
                    Log_OC.e(TAG, "*** status: " + statusProp + "; message: " + message);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, get);
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
                result = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
                Log_OC.e(TAG, "Failed response while getting capabilities from the server ");
 | 
			
		||||
                if (response != null) {
 | 
			
		||||
                    Log_OC.e(TAG, "*** status code: " + status + "; response message: " + response);
 | 
			
		||||
@ -277,18 +276,13 @@ public class GetRemoteCapabilitiesOperation extends RemoteOperation {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while getting capabilities", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null) {
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,40 +24,41 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.status;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
import org.apache.commons.httpclient.params.HttpMethodParams;
 | 
			
		||||
import org.apache.commons.httpclient.params.HttpParams;
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.net.ConnectivityManager;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
 | 
			
		||||
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.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.json.JSONException;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
import javax.net.ssl.SSLException;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks if the server is valid and if the server supports the Share API
 | 
			
		||||
 *
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class GetRemoteStatusOperation extends RemoteOperation {
 | 
			
		||||
public class GetRemoteStatusOperation extends RemoteOperation<OwnCloudVersion> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Maximum time to wait for a response from the server when the connection is being tested,
 | 
			
		||||
     * in MILLISECONDs.
 | 
			
		||||
     */
 | 
			
		||||
    public static final int TRY_CONNECTION_TIMEOUT = 5000;
 | 
			
		||||
    public static final long TRY_CONNECTION_TIMEOUT = 5000;
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteStatusOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
@ -66,7 +67,7 @@ public class GetRemoteStatusOperation extends RemoteOperation {
 | 
			
		||||
    private static final String HTTPS_PREFIX = "https://";
 | 
			
		||||
    private static final String HTTP_PREFIX = "http://";
 | 
			
		||||
 | 
			
		||||
    private RemoteOperationResult mLatestResult;
 | 
			
		||||
    private RemoteOperationResult<OwnCloudVersion> mLatestResult;
 | 
			
		||||
    private Context mContext;
 | 
			
		||||
 | 
			
		||||
    public GetRemoteStatusOperation(Context context) {
 | 
			
		||||
@ -75,20 +76,25 @@ public class GetRemoteStatusOperation extends RemoteOperation {
 | 
			
		||||
 | 
			
		||||
    private boolean tryConnection(OwnCloudClient client) {
 | 
			
		||||
        boolean retval = false;
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
        String baseUrlSt = client.getBaseUri().toString();
 | 
			
		||||
        try {
 | 
			
		||||
            get = new GetMethod(baseUrlSt + OwnCloudClient.STATUS_PATH);
 | 
			
		||||
            GetMethod getMethod = new GetMethod(new URL(baseUrlSt + OwnCloudClient.STATUS_PATH));
 | 
			
		||||
 | 
			
		||||
            HttpParams params = get.getParams().getDefaultParams();
 | 
			
		||||
            params.setParameter(HttpMethodParams.USER_AGENT,
 | 
			
		||||
                OwnCloudClientManagerFactory.getUserAgent());
 | 
			
		||||
            get.getParams().setDefaults(params);
 | 
			
		||||
            getMethod.setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
            getMethod.setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
 | 
			
		||||
            client.setFollowRedirects(false);
 | 
			
		||||
            boolean isRedirectToNonSecureConnection = false;
 | 
			
		||||
            int status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
 | 
			
		||||
            mLatestResult = new RemoteOperationResult((status == HttpStatus.SC_OK), get);
 | 
			
		||||
            int status;
 | 
			
		||||
            try {
 | 
			
		||||
                status = client.executeHttpMethod(getMethod);
 | 
			
		||||
                mLatestResult = isSuccess(status)
 | 
			
		||||
                        ? new RemoteOperationResult<>(OK)
 | 
			
		||||
                        : new RemoteOperationResult<>(getMethod);
 | 
			
		||||
            } catch (SSLException sslE) {
 | 
			
		||||
                mLatestResult = new RemoteOperationResult(sslE);
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            String redirectedLocation = mLatestResult.getRedirectedLocation();
 | 
			
		||||
            while (redirectedLocation != null && redirectedLocation.length() > 0
 | 
			
		||||
@ -98,61 +104,53 @@ public class GetRemoteStatusOperation extends RemoteOperation {
 | 
			
		||||
                    baseUrlSt.startsWith(HTTPS_PREFIX) &&
 | 
			
		||||
                        redirectedLocation.startsWith(HTTP_PREFIX)
 | 
			
		||||
                );
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
                get = new GetMethod(redirectedLocation);
 | 
			
		||||
                status = client.executeMethod(get, TRY_CONNECTION_TIMEOUT, TRY_CONNECTION_TIMEOUT);
 | 
			
		||||
                mLatestResult = new RemoteOperationResult(
 | 
			
		||||
                    (status == HttpStatus.SC_OK),
 | 
			
		||||
                    get
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                getMethod = new GetMethod(new URL(redirectedLocation));
 | 
			
		||||
                getMethod.setReadTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
                getMethod.setConnectionTimeout(TRY_CONNECTION_TIMEOUT, TimeUnit.SECONDS);
 | 
			
		||||
 | 
			
		||||
                status = client.executeHttpMethod(getMethod);
 | 
			
		||||
                mLatestResult = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
                redirectedLocation = mLatestResult.getRedirectedLocation();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            String response = get.getResponseBodyAsString();
 | 
			
		||||
            if (status == HttpStatus.SC_OK) {
 | 
			
		||||
                JSONObject json = new JSONObject(response);
 | 
			
		||||
                if (!json.getBoolean(NODE_INSTALLED)) {
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
 | 
			
		||||
                JSONObject respJSON = new JSONObject(getMethod.getResponseBodyAsString());
 | 
			
		||||
                if (!respJSON.getBoolean(NODE_INSTALLED)) {
 | 
			
		||||
                    mLatestResult = new RemoteOperationResult(
 | 
			
		||||
                        RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
 | 
			
		||||
                            RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
 | 
			
		||||
                } else {
 | 
			
		||||
                    String version = json.getString(NODE_VERSION);
 | 
			
		||||
                    String version = respJSON.getString(NODE_VERSION);
 | 
			
		||||
                    OwnCloudVersion ocVersion = new OwnCloudVersion(version);
 | 
			
		||||
                    /// the version object will be returned even if the version is invalid, no error code;
 | 
			
		||||
                    /// every app will decide how to act if (ocVersion.isVersionValid() == false)
 | 
			
		||||
 | 
			
		||||
                    if (isRedirectToNonSecureConnection) {
 | 
			
		||||
                        mLatestResult = new RemoteOperationResult(
 | 
			
		||||
                        mLatestResult = new RemoteOperationResult<>(
 | 
			
		||||
                            RemoteOperationResult.ResultCode.
 | 
			
		||||
                                OK_REDIRECT_TO_NON_SECURE_CONNECTION
 | 
			
		||||
                        );
 | 
			
		||||
                                OK_REDIRECT_TO_NON_SECURE_CONNECTION);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        mLatestResult = new RemoteOperationResult(
 | 
			
		||||
                        mLatestResult = new RemoteOperationResult<>(
 | 
			
		||||
                            baseUrlSt.startsWith(HTTPS_PREFIX) ?
 | 
			
		||||
                                RemoteOperationResult.ResultCode.OK_SSL :
 | 
			
		||||
                                RemoteOperationResult.ResultCode.OK_NO_SSL
 | 
			
		||||
                        );
 | 
			
		||||
                                RemoteOperationResult.ResultCode.OK_NO_SSL);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    ArrayList<Object> data = new ArrayList<Object>();
 | 
			
		||||
                    data.add(ocVersion);
 | 
			
		||||
                    mLatestResult.setData(data);
 | 
			
		||||
                    mLatestResult.setData(ocVersion);
 | 
			
		||||
                    retval = true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                mLatestResult = new RemoteOperationResult(false, get);
 | 
			
		||||
                mLatestResult = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (JSONException e) {
 | 
			
		||||
            mLatestResult = new RemoteOperationResult(
 | 
			
		||||
            mLatestResult = new RemoteOperationResult<>(
 | 
			
		||||
                RemoteOperationResult.ResultCode.INSTANCE_NOT_CONFIGURED);
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            mLatestResult = new RemoteOperationResult(e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null)
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            mLatestResult = new RemoteOperationResult<>(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mLatestResult.isSuccess()) {
 | 
			
		||||
@ -177,9 +175,9 @@ public class GetRemoteStatusOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
    protected RemoteOperationResult<OwnCloudVersion> run(OwnCloudClient client) {
 | 
			
		||||
        if (!isOnline()) {
 | 
			
		||||
            return new RemoteOperationResult(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
 | 
			
		||||
            return new RemoteOperationResult<>(RemoteOperationResult.ResultCode.NO_NETWORK_CONNECTION);
 | 
			
		||||
        }
 | 
			
		||||
        String baseUriStr = client.getBaseUri().toString();
 | 
			
		||||
        if (baseUriStr.startsWith(HTTP_PREFIX) || baseUriStr.startsWith(HTTPS_PREFIX)) {
 | 
			
		||||
@ -197,4 +195,7 @@ public class GetRemoteStatusOperation extends RemoteOperation {
 | 
			
		||||
        return mLatestResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,6 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *
 | 
			
		||||
 *   @author David A. Velasco
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -26,33 +25,32 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.users;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedInputStream;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.Header;
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
 | 
			
		||||
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.WebdavUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import java.io.BufferedInputStream;
 | 
			
		||||
import java.io.ByteArrayOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets avatar about the user logged in, if available
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class GetRemoteUserAvatarOperation extends RemoteOperation {
 | 
			
		||||
public class GetRemoteUserAvatarOperation extends RemoteOperation<GetRemoteUserAvatarOperation.ResultData> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteUserAvatarOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    private static final String NON_OFFICIAL_AVATAR_PATH = "/index.php/avatar/";
 | 
			
		||||
    private static final String IF_NONE_MATCH_HEADER = "If-None-Match";
 | 
			
		||||
 | 
			
		||||
    /** Desired size in pixels of the squared image */
 | 
			
		||||
    private int mDimension;
 | 
			
		||||
@ -63,67 +61,54 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation {
 | 
			
		||||
     */
 | 
			
		||||
    private String mCurrentEtag;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public GetRemoteUserAvatarOperation(int dimension, String currentEtag) {
 | 
			
		||||
        mDimension = dimension;
 | 
			
		||||
        mCurrentEtag = currentEtag;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
    protected RemoteOperationResult<ResultData> run(OwnCloudClient client) {
 | 
			
		||||
        GetMethod getMethod = null;
 | 
			
		||||
        RemoteOperationResult<ResultData> result;
 | 
			
		||||
        InputStream inputStream = null;
 | 
			
		||||
        BufferedInputStream bis = null;
 | 
			
		||||
        ByteArrayOutputStream bos = null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            String uri =
 | 
			
		||||
                client.getBaseUri() + NON_OFFICIAL_AVATAR_PATH +
 | 
			
		||||
                client.getCredentials().getUsername() + "/" + mDimension;
 | 
			
		||||
            ;
 | 
			
		||||
            Log_OC.d(TAG, "avatar URI: " + uri);
 | 
			
		||||
            get = new GetMethod(uri);
 | 
			
		||||
            /*  Conditioned call is corrupting the input stream of the connection.
 | 
			
		||||
                Seems that response with 304 is also including the avatar in the response body,
 | 
			
		||||
                though it's forbidden by HTTPS specification. Besides, HTTPClient library
 | 
			
		||||
                assumes there is nothing in the response body, but the bytes are read
 | 
			
		||||
                by the next request, resulting in an exception due to a corrupt status line
 | 
			
		||||
            final String url =
 | 
			
		||||
                    client.getBaseUri() + NON_OFFICIAL_AVATAR_PATH +
 | 
			
		||||
                    client.getCredentials().getUsername() + "/" + mDimension;
 | 
			
		||||
            Log_OC.d(TAG, "avatar URI: " + url);
 | 
			
		||||
 | 
			
		||||
                Maybe when we have a real API we can enable this again.
 | 
			
		||||
            getMethod = new GetMethod(new URL(url));
 | 
			
		||||
 | 
			
		||||
            if (mCurrentEtag != null && mCurrentEtag.length() > 0) {
 | 
			
		||||
                get.addRequestHeader(IF_NONE_MATCH_HEADER, "\"" + mCurrentEtag + "\"");
 | 
			
		||||
            }
 | 
			
		||||
            */
 | 
			
		||||
            int status = client.executeHttpMethod(getMethod);
 | 
			
		||||
 | 
			
		||||
            //get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            int status = client.executeMethod(get);
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
 | 
			
		||||
                // find out size of file to read
 | 
			
		||||
                int totalToTransfer = 0;
 | 
			
		||||
                Header contentLength = get.getResponseHeader("Content-Length");
 | 
			
		||||
                if (contentLength != null && contentLength.getValue().length() > 0) {
 | 
			
		||||
                    totalToTransfer = Integer.parseInt(contentLength.getValue());
 | 
			
		||||
                String contentLength = getMethod.getResponseHeader(HttpConstants.CONTENT_LENGTH_HEADER);
 | 
			
		||||
 | 
			
		||||
                if (contentLength != null && contentLength.length() > 0) {
 | 
			
		||||
                    totalToTransfer = Integer.parseInt(contentLength);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // find out MIME-type!
 | 
			
		||||
                String mimeType;
 | 
			
		||||
                Header contentType = get.getResponseHeader("Content-Type");
 | 
			
		||||
                if (contentType == null || !contentType.getValue().startsWith("image")) {
 | 
			
		||||
                String contentType = getMethod.getResponseHeader(HttpConstants.CONTENT_TYPE_HEADER);
 | 
			
		||||
 | 
			
		||||
                if (contentType == null || !contentType.startsWith("image")) {
 | 
			
		||||
                    Log_OC.e(
 | 
			
		||||
                        TAG, "Not an image, failing with no avatar"
 | 
			
		||||
                    );
 | 
			
		||||
                    result = new RemoteOperationResult(
 | 
			
		||||
                        RemoteOperationResult.ResultCode.FILE_NOT_FOUND
 | 
			
		||||
                    );
 | 
			
		||||
                    result = new RemoteOperationResult<>(RemoteOperationResult.ResultCode.FILE_NOT_FOUND);
 | 
			
		||||
                    return result;
 | 
			
		||||
                }
 | 
			
		||||
                mimeType = contentType.getValue();
 | 
			
		||||
 | 
			
		||||
                mimeType = contentType;
 | 
			
		||||
 | 
			
		||||
                /// download will be performed to a buffer
 | 
			
		||||
                inputStream = get.getResponseBodyAsStream();
 | 
			
		||||
                inputStream = getMethod.getResponseBodyAsStream();
 | 
			
		||||
                bis = new BufferedInputStream(inputStream);
 | 
			
		||||
                bos = new ByteArrayOutputStream(totalToTransfer);
 | 
			
		||||
 | 
			
		||||
@ -137,29 +122,26 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation {
 | 
			
		||||
                // TODO check total bytes transferred?
 | 
			
		||||
 | 
			
		||||
                // find out etag
 | 
			
		||||
                String etag = WebdavUtils.getEtagFromResponse(get);
 | 
			
		||||
                String etag = WebdavUtils.getEtagFromResponse(getMethod);
 | 
			
		||||
                if (etag.length() == 0) {
 | 
			
		||||
                    Log_OC.w(TAG, "Could not read Etag from avatar");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Result
 | 
			
		||||
                result = new RemoteOperationResult(true, get);
 | 
			
		||||
                ResultData resultData = new ResultData(bos.toByteArray(), mimeType, etag);
 | 
			
		||||
                ArrayList<Object> data = new ArrayList<Object>();
 | 
			
		||||
                data.add(resultData);
 | 
			
		||||
                result.setData(data);
 | 
			
		||||
                result = new RemoteOperationResult<>(OK);
 | 
			
		||||
                result.setData(new ResultData(bos.toByteArray(), mimeType, etag));
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, get);
 | 
			
		||||
                client.exhaustResponse(get.getResponseBodyAsStream());
 | 
			
		||||
                result = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
                client.exhaustResponse(getMethod.getResponseBodyAsStream());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while getting OC user avatar", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null) {
 | 
			
		||||
            if (getMethod != null) {
 | 
			
		||||
                try {
 | 
			
		||||
                    if (inputStream != null) {
 | 
			
		||||
                        client.exhaustResponse(inputStream);
 | 
			
		||||
@ -179,7 +161,6 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation {
 | 
			
		||||
                } catch (IOException o) {
 | 
			
		||||
                    Log_OC.e(TAG, "Unexpected exception closing output stream ", o);
 | 
			
		||||
                }
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -187,7 +168,7 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class ResultData {
 | 
			
		||||
@ -213,5 +194,4 @@ public class GetRemoteUserAvatarOperation extends RemoteOperation {
 | 
			
		||||
            return mAvatarData;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2016 ownCloud GmbH.
 | 
			
		||||
 *   Copyright (C) 2018 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
 | 
			
		||||
@ -24,31 +24,33 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.resources.users;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.methods.GetMethod;
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
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.utils.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.json.JSONObject;
 | 
			
		||||
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Gets information (id, display name, and e-mail address) about the user logged in.
 | 
			
		||||
 *
 | 
			
		||||
 * @author masensio
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class GetRemoteUserInfoOperation extends RemoteOperation {
 | 
			
		||||
public class GetRemoteUserInfoOperation extends RemoteOperation<GetRemoteUserInfoOperation.UserInfo> {
 | 
			
		||||
 | 
			
		||||
    private static final String TAG = GetRemoteUserInfoOperation.class.getSimpleName();
 | 
			
		||||
 | 
			
		||||
    // OCS Route
 | 
			
		||||
    private static final String OCS_ROUTE = "/ocs/v1.php/cloud/user?format=json";
 | 
			
		||||
    private static final String OCS_ROUTE = "/ocs/v2.php/cloud/user?format=json";
 | 
			
		||||
 | 
			
		||||
    // JSON Node names
 | 
			
		||||
    private static final String NODE_OCS = "ocs";
 | 
			
		||||
@ -61,22 +63,19 @@ public class GetRemoteUserInfoOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        int status = -1;
 | 
			
		||||
        GetMethod get = null;
 | 
			
		||||
    protected RemoteOperationResult<UserInfo> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<UserInfo> result;
 | 
			
		||||
 | 
			
		||||
        //Get the user
 | 
			
		||||
        try {
 | 
			
		||||
            get = new GetMethod(client.getBaseUri() + OCS_ROUTE);
 | 
			
		||||
            get.addRequestHeader(OCS_API_HEADER, OCS_API_HEADER_VALUE);
 | 
			
		||||
            status = client.executeMethod(get);
 | 
			
		||||
            GetMethod getMethod = new GetMethod(new URL(client.getBaseUri() + OCS_ROUTE));
 | 
			
		||||
 | 
			
		||||
            int status = client.executeHttpMethod(getMethod);
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
                Log_OC.d(TAG, "Successful response");
 | 
			
		||||
 | 
			
		||||
                // Parse the response
 | 
			
		||||
                JSONObject respJSON = new JSONObject(response);
 | 
			
		||||
                JSONObject respJSON = new JSONObject(getMethod.getResponseBodyAsString());
 | 
			
		||||
                JSONObject respOCS = respJSON.getJSONObject(NODE_OCS);
 | 
			
		||||
                JSONObject respData = respOCS.getJSONObject(NODE_DATA);
 | 
			
		||||
 | 
			
		||||
@ -85,45 +84,35 @@ public class GetRemoteUserInfoOperation extends RemoteOperation {
 | 
			
		||||
                userInfo.mDisplayName = respData.getString(NODE_DISPLAY_NAME);
 | 
			
		||||
                userInfo.mEmail = respData.getString(NODE_EMAIL);
 | 
			
		||||
 | 
			
		||||
                // Result
 | 
			
		||||
                result = new RemoteOperationResult(true, get);
 | 
			
		||||
                // Username in result.data
 | 
			
		||||
                ArrayList<Object> data = new ArrayList<Object>();
 | 
			
		||||
                data.add(userInfo);
 | 
			
		||||
                result.setData(data);
 | 
			
		||||
                result = new RemoteOperationResult<>(OK);
 | 
			
		||||
 | 
			
		||||
                result.setData(userInfo);
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                result = new RemoteOperationResult(false, get);
 | 
			
		||||
                String response = get.getResponseBodyAsString();
 | 
			
		||||
                result = new RemoteOperationResult<>(getMethod);
 | 
			
		||||
                String response = getMethod.getResponseBodyAsString();
 | 
			
		||||
                Log_OC.e(TAG, "Failed response while getting user information ");
 | 
			
		||||
                if (response != null) {
 | 
			
		||||
                if (getMethod != null) {
 | 
			
		||||
                    Log_OC.e(TAG, "*** status code: " + status + " ; response message: " + response);
 | 
			
		||||
                } else {
 | 
			
		||||
                    Log_OC.e(TAG, "*** status code: " + status);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
            Log_OC.e(TAG, "Exception while getting OC user information", e);
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (get != null) {
 | 
			
		||||
                get.releaseConnection();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return (status == HttpStatus.SC_OK);
 | 
			
		||||
        return (status == HttpConstants.HTTP_OK);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public static class UserInfo {
 | 
			
		||||
        public String mId = "";
 | 
			
		||||
        public String mDisplayName = "";
 | 
			
		||||
        public String mEmail = "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -28,42 +28,36 @@
 | 
			
		||||
package com.owncloud.android.lib.resources.users;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.network.WebdavEntry;
 | 
			
		||||
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.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.Log_OC;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.DavConstants;
 | 
			
		||||
import org.apache.jackrabbit.webdav.MultiStatus;
 | 
			
		||||
import org.apache.jackrabbit.webdav.client.methods.PropFindMethod;
 | 
			
		||||
import java.net.URL;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import java.math.BigDecimal;
 | 
			
		||||
import java.math.RoundingMode;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import at.bitfire.dav4android.Property;
 | 
			
		||||
import at.bitfire.dav4android.property.QuotaAvailableBytes;
 | 
			
		||||
import at.bitfire.dav4android.property.QuotaUsedBytes;
 | 
			
		||||
 | 
			
		||||
import static com.owncloud.android.lib.common.http.methods.webdav.DavConstants.DEPTH_0;
 | 
			
		||||
import static com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode.OK;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author marcello
 | 
			
		||||
 * @author David González Verdugo
 | 
			
		||||
 */
 | 
			
		||||
public class GetRemoteUserQuotaOperation extends RemoteOperation {
 | 
			
		||||
public class GetRemoteUserQuotaOperation extends RemoteOperation<GetRemoteUserQuotaOperation.RemoteQuota> {
 | 
			
		||||
 | 
			
		||||
    static public class Quota {
 | 
			
		||||
 | 
			
		||||
        // Not computed yet, e.g. external storage mounted but folder sizes need scanning
 | 
			
		||||
        public static final int PENDING_FREE_QUOTA = -1;
 | 
			
		||||
 | 
			
		||||
        // Storage not accessible, e.g. external storage with no API to ask for the free space
 | 
			
		||||
        public static final int UNKNOWN_FREE_QUOTA = -2;
 | 
			
		||||
 | 
			
		||||
        // Quota using all the storage
 | 
			
		||||
        public static final int UNLIMITED_FREE_QUOTA = -3;
 | 
			
		||||
    static public class RemoteQuota {
 | 
			
		||||
 | 
			
		||||
        long mFree, mUsed, mTotal;
 | 
			
		||||
        double mRelative;
 | 
			
		||||
 | 
			
		||||
        public Quota(long free, long used, long total, double relative) {
 | 
			
		||||
        public RemoteQuota(long free, long used, long total, double relative) {
 | 
			
		||||
            mFree = free;
 | 
			
		||||
            mUsed = used;
 | 
			
		||||
            mTotal = total;
 | 
			
		||||
@ -90,45 +84,36 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected RemoteOperationResult run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult result = null;
 | 
			
		||||
        PropFindMethod query = null;
 | 
			
		||||
    protected RemoteOperationResult<RemoteQuota> run(OwnCloudClient client) {
 | 
			
		||||
        RemoteOperationResult<RemoteQuota> result = null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            // remote request
 | 
			
		||||
            query = new PropFindMethod(client.getWebdavUri() + WebdavUtils.encodePath(mRemotePath),
 | 
			
		||||
                    WebdavUtils.getQuotaPropSet(),
 | 
			
		||||
                    DavConstants.DEPTH_0);
 | 
			
		||||
            PropfindMethod propfindMethod = new PropfindMethod(
 | 
			
		||||
                    new URL(client.getNewFilesWebDavUri() + WebdavUtils.encodePath(mRemotePath)),
 | 
			
		||||
                    DEPTH_0,
 | 
			
		||||
                    DavUtils.getQuotaPropSet());
 | 
			
		||||
 | 
			
		||||
            int status = client.executeMethod(query);
 | 
			
		||||
            int status = client.executeHttpMethod(propfindMethod);
 | 
			
		||||
 | 
			
		||||
            if (isSuccess(status)) {
 | 
			
		||||
                // get data from remote folder
 | 
			
		||||
                MultiStatus dataInServer = query.getResponseBodyAsMultiStatus();
 | 
			
		||||
                Quota quota = readData(dataInServer, client);
 | 
			
		||||
                RemoteQuota remoteQuota = readData(propfindMethod.getRoot().getProperties());
 | 
			
		||||
 | 
			
		||||
                // Result of the operation
 | 
			
		||||
                result = new RemoteOperationResult(true, query);
 | 
			
		||||
 | 
			
		||||
                ArrayList<Object> data = new ArrayList<>();
 | 
			
		||||
                data.add(quota);
 | 
			
		||||
                result = new RemoteOperationResult<>(OK);
 | 
			
		||||
 | 
			
		||||
                // Add data to the result
 | 
			
		||||
                if (result.isSuccess()) {
 | 
			
		||||
                    result.setData(data);
 | 
			
		||||
                    result.setData(remoteQuota);
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                // synchronization failed
 | 
			
		||||
                result = new RemoteOperationResult(false, query);
 | 
			
		||||
 | 
			
		||||
            } else { // synchronization failed
 | 
			
		||||
                result = new RemoteOperationResult<>(propfindMethod);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            result = new RemoteOperationResult(e);
 | 
			
		||||
            result = new RemoteOperationResult<>(e);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        } finally {
 | 
			
		||||
            if (query != null)
 | 
			
		||||
                query.releaseConnection();  // let the connection available for other methods
 | 
			
		||||
            if (result.isSuccess()) {
 | 
			
		||||
                Log_OC.i(TAG, "Get quota from " + mRemotePath + ": " + result.getLogMessage());
 | 
			
		||||
            } else {
 | 
			
		||||
@ -145,47 +130,48 @@ public class GetRemoteUserQuotaOperation extends RemoteOperation {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isSuccess(int status) {
 | 
			
		||||
        return status == HttpStatus.SC_MULTI_STATUS || status == HttpStatus.SC_OK;
 | 
			
		||||
        return status == HttpConstants.HTTP_MULTI_STATUS || status == HttpConstants.HTTP_OK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Read the data retrieved from the server about the quota
 | 
			
		||||
     *
 | 
			
		||||
     * @param remoteData Full response got from the server with the data of the quota
 | 
			
		||||
     * @param client     Client instance to the remote server where the data were retrieved
 | 
			
		||||
     * @return new Quota instance representing the data read from the server
 | 
			
		||||
     * @param properties WebDAV properties containing quota data
 | 
			
		||||
     * @return new {@link RemoteQuota} instance representing the data read from the server
 | 
			
		||||
     */
 | 
			
		||||
    private Quota readData(MultiStatus remoteData, OwnCloudClient client) {
 | 
			
		||||
    private RemoteQuota readData(List<Property> properties) {
 | 
			
		||||
        long quotaAvailable = 0;
 | 
			
		||||
        long quotaUsed = 0;
 | 
			
		||||
 | 
			
		||||
        // parse data from remote folder
 | 
			
		||||
        WebdavEntry we = new WebdavEntry(remoteData.getResponses()[0], client.getWebdavUri().getPath());
 | 
			
		||||
        for(Property property : properties) {
 | 
			
		||||
            if(property instanceof QuotaAvailableBytes)
 | 
			
		||||
                quotaAvailable = ((QuotaAvailableBytes) property).getQuotaAvailableBytes();
 | 
			
		||||
            if(property instanceof QuotaUsedBytes)
 | 
			
		||||
                quotaUsed = ((QuotaUsedBytes) property).getQuotaUsedBytes();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // If there's a special case, available bytes will contain a negative code
 | 
			
		||||
        // If there's a special case, quota available will contain a negative code
 | 
			
		||||
        // -1, PENDING: Not computed yet, e.g. external storage mounted but folder sizes need scanning
 | 
			
		||||
        // -2, UNKNOWN: Storage not accessible, e.g. external storage with no API to ask for the free space
 | 
			
		||||
        // -3, UNLIMITED: Quota using all the storage
 | 
			
		||||
        if (we.quotaAvailableBytes().compareTo(new BigDecimal(1)) == -1) {
 | 
			
		||||
            return new Quota(
 | 
			
		||||
                    we.quotaAvailableBytes().longValue(),
 | 
			
		||||
                    we.quotaUsedBytes().longValue(),
 | 
			
		||||
        if (quotaAvailable < 0) {
 | 
			
		||||
            return new RemoteQuota(
 | 
			
		||||
                    quotaAvailable,
 | 
			
		||||
                    quotaUsed,
 | 
			
		||||
                    0,
 | 
			
		||||
                    0
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            long totalQuota = quotaAvailable + quotaUsed;
 | 
			
		||||
            double relativeQuota = (double)(quotaUsed * 100)/totalQuota;
 | 
			
		||||
            double roundedRelativeQuota = Math.round(relativeQuota * 100)/100.0d;
 | 
			
		||||
 | 
			
		||||
            BigDecimal totalQuota = we.quotaAvailableBytes().add(we.quotaUsedBytes());
 | 
			
		||||
 | 
			
		||||
            BigDecimal relativeQuota = we.quotaUsedBytes()
 | 
			
		||||
                    .multiply(new BigDecimal(100))
 | 
			
		||||
                    .divide(totalQuota, 2, RoundingMode.HALF_UP);
 | 
			
		||||
 | 
			
		||||
            return new Quota(
 | 
			
		||||
                    we.quotaAvailableBytes().longValue(),
 | 
			
		||||
                    we.quotaUsedBytes().longValue(),
 | 
			
		||||
                    totalQuota.longValue(),
 | 
			
		||||
                    relativeQuota.doubleValue()
 | 
			
		||||
            return new RemoteQuota(
 | 
			
		||||
                    quotaAvailable,
 | 
			
		||||
                    quotaUsed,
 | 
			
		||||
                    totalQuota,
 | 
			
		||||
                    roundedRelativeQuota
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -43,4 +43,8 @@ android {
 | 
			
		||||
    packagingOptions {
 | 
			
		||||
        exclude 'META-INF/LICENSE.txt'
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
        sourceCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
        targetCompatibility JavaVersion.VERSION_1_8
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,193 +0,0 @@
 | 
			
		||||
/* 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.test_project;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.net.Socket;
 | 
			
		||||
import java.net.UnknownHostException;
 | 
			
		||||
import java.security.GeneralSecurityException;
 | 
			
		||||
import java.security.KeyStore;
 | 
			
		||||
import java.security.KeyStoreException;
 | 
			
		||||
import java.security.NoSuchAlgorithmException;
 | 
			
		||||
import java.security.cert.CertStoreException;
 | 
			
		||||
import java.security.cert.CertificateException;
 | 
			
		||||
import java.security.cert.X509Certificate;
 | 
			
		||||
 | 
			
		||||
import javax.net.ssl.SSLContext;
 | 
			
		||||
import javax.net.ssl.TrustManager;
 | 
			
		||||
import javax.net.ssl.TrustManagerFactory;
 | 
			
		||||
import javax.net.ssl.X509TrustManager;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.ConnectTimeoutException;
 | 
			
		||||
import org.apache.commons.httpclient.params.HttpConnectionParams;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.network.AdvancedSslSocketFactory;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SelfSignedConfidentSslSocketFactory allows to create SSL {@link Socket}s 
 | 
			
		||||
 * that accepts self-signed server certificates.
 | 
			
		||||
 * 
 | 
			
		||||
 * WARNING: this SHOULD NOT be used in productive environments.
 | 
			
		||||
 * 
 | 
			
		||||
 * @author David A. Velasco
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class SelfSignedConfidentSslSocketFactory implements SecureProtocolSocketFactory {
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	//private SSLContext mSslContext = null;
 | 
			
		||||
	private AdvancedSslSocketFactory mWrappedSslSocketFactory = null;
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor for SelfSignedConfidentSslSocketFactory.
 | 
			
		||||
	 * @throws GeneralSecurityException 
 | 
			
		||||
	 */
 | 
			
		||||
	public SelfSignedConfidentSslSocketFactory() throws GeneralSecurityException {
 | 
			
		||||
		SSLContext sslContext = SSLContext.getInstance("TLS");
 | 
			
		||||
		sslContext.init(
 | 
			
		||||
				null, 
 | 
			
		||||
				new TrustManager[] { new SelfSignedConfidentX509TrustManager() }, 
 | 
			
		||||
				null
 | 
			
		||||
		);
 | 
			
		||||
        mWrappedSslSocketFactory = new AdvancedSslSocketFactory(sslContext, null, null);		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int)
 | 
			
		||||
	 */
 | 
			
		||||
	@Override
 | 
			
		||||
	public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
 | 
			
		||||
		return mWrappedSslSocketFactory.createSocket(host, port);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
 | 
			
		||||
	 */
 | 
			
		||||
	@Override
 | 
			
		||||
	public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)
 | 
			
		||||
			throws IOException, UnknownHostException {
 | 
			
		||||
		return mWrappedSslSocketFactory.createSocket(host, port, clientHost, clientPort);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * Attempts to get a new socket connection to the given host within the given time limit.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @param host 			The host name/IP
 | 
			
		||||
	 * @param port 			The port on the host
 | 
			
		||||
	 * @param clientHost 	The local host name/IP to bind the socket to
 | 
			
		||||
	 * @param clientPort 	The port on the local machine
 | 
			
		||||
	 * @param params 		{@link HttpConnectionParams} HTTP connection parameters.
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @return Socket 		A new socket
 | 
			
		||||
	 * 
 | 
			
		||||
	 * @throws IOException if an I/O error occurs while creating the socket
 | 
			
		||||
	 * @throws UnknownHostException if the IP address of the host cannot be determined
 | 
			
		||||
	 */
 | 
			
		||||
	@Override
 | 
			
		||||
	public Socket createSocket(String host, int port, InetAddress localAddress, int localPort,
 | 
			
		||||
			HttpConnectionParams params) throws IOException, UnknownHostException,
 | 
			
		||||
			ConnectTimeoutException {
 | 
			
		||||
		
 | 
			
		||||
		return mWrappedSslSocketFactory.createSocket(host, port, localAddress, localPort, params);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	  * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
 | 
			
		||||
	  */
 | 
			
		||||
	@Override
 | 
			
		||||
	public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
 | 
			
		||||
			throws IOException, UnknownHostException {
 | 
			
		||||
		return mWrappedSslSocketFactory.createSocket(socket, host, port, autoClose);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
	public static class SelfSignedConfidentX509TrustManager implements X509TrustManager {
 | 
			
		||||
 | 
			
		||||
	    private X509TrustManager mStandardTrustManager = null;
 | 
			
		||||
 | 
			
		||||
		public SelfSignedConfidentX509TrustManager() 
 | 
			
		||||
				throws NoSuchAlgorithmException, KeyStoreException, CertStoreException {
 | 
			
		||||
			super();
 | 
			
		||||
			TrustManagerFactory factory = TrustManagerFactory
 | 
			
		||||
					.getInstance(TrustManagerFactory.getDefaultAlgorithm());
 | 
			
		||||
			factory.init((KeyStore)null);
 | 
			
		||||
			mStandardTrustManager = findX509TrustManager(factory);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
 | 
			
		||||
		 */
 | 
			
		||||
		@Override
 | 
			
		||||
		public void checkClientTrusted(X509Certificate[] chain, String authType)
 | 
			
		||||
				throws CertificateException {
 | 
			
		||||
			mStandardTrustManager.checkClientTrusted(chain, authType);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],
 | 
			
		||||
		 *      String authType)
 | 
			
		||||
		 */
 | 
			
		||||
		@Override
 | 
			
		||||
		public void checkServerTrusted(X509Certificate[] chain, String authType)
 | 
			
		||||
				throws CertificateException {
 | 
			
		||||
			if (chain != null && chain.length == 1) {
 | 
			
		||||
				chain[0].checkValidity();
 | 
			
		||||
			} else {
 | 
			
		||||
				mStandardTrustManager.checkServerTrusted(chain, authType);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
 | 
			
		||||
		 */
 | 
			
		||||
		public X509Certificate[] getAcceptedIssuers() {
 | 
			
		||||
			return mStandardTrustManager.getAcceptedIssuers();
 | 
			
		||||
		}
 | 
			
		||||
	
 | 
			
		||||
		/**
 | 
			
		||||
		 * 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.
 | 
			
		||||
		 * @throws CertStoreException   When no X509TrustManager instance was found in factory
 | 
			
		||||
		 */
 | 
			
		||||
		private X509TrustManager findX509TrustManager(TrustManagerFactory factory) 
 | 
			
		||||
				throws CertStoreException {
 | 
			
		||||
			TrustManager tms[] = factory.getTrustManagers();
 | 
			
		||||
			for (int i = 0; i < tms.length; i++) {
 | 
			
		||||
				if (tms[i] instanceof X509TrustManager) {
 | 
			
		||||
					return (X509TrustManager) tms[i];
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,22 +1,22 @@
 | 
			
		||||
/* ownCloud Android Library is available under MIT license
 | 
			
		||||
 *   Copyright (C) 2018 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, 
 | 
			
		||||
 *
 | 
			
		||||
 *   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 
 | 
			
		||||
 *   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.
 | 
			
		||||
 *
 | 
			
		||||
@ -24,15 +24,6 @@
 | 
			
		||||
 | 
			
		||||
package com.owncloud.android.lib.test_project;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.security.GeneralSecurityException;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.protocol.Protocol;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
 | 
			
		||||
 | 
			
		||||
import android.app.Activity;
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
@ -41,12 +32,8 @@ import android.util.Log;
 | 
			
		||||
import android.view.Menu;
 | 
			
		||||
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClient;
 | 
			
		||||
import com.owncloud.android.lib.common.OwnCloudClientFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
 | 
			
		||||
import com.owncloud.android.lib.common.network.NetworkUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperation;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.ChunkedUploadRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.CreateRemoteFolderOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.DownloadRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.ReadRemoteFolderOperation;
 | 
			
		||||
@ -54,12 +41,18 @@ import com.owncloud.android.lib.resources.files.RemoteFile;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.RemoveRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.RenameRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.chunks.ChunkedUploadRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.shares.CreateRemoteShareOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.shares.GetRemoteSharesOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.shares.RemoveRemoteShareOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.shares.ShareType;
 | 
			
		||||
import com.owncloud.android.lib.resources.users.GetRemoteUserQuotaOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.users.GetRemoteUserAvatarOperation;
 | 
			
		||||
import com.owncloud.android.lib.resources.users.GetRemoteUserQuotaOperation;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileOutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Activity to test OC framework
 | 
			
		||||
@ -69,59 +62,43 @@ import com.owncloud.android.lib.resources.users.GetRemoteUserAvatarOperation;
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class TestActivity extends Activity {
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	private static final String TAG = null;
 | 
			
		||||
	// This account must exists on the server side
 | 
			
		||||
	private String mServerUri;
 | 
			
		||||
	private String mUser;
 | 
			
		||||
	private String mPass;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	private static final int BUFFER_SIZE = 1024;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	public static final String ASSETS__TEXT_FILE_NAME = "textFile.txt";
 | 
			
		||||
	public static final String ASSETS__IMAGE_FILE_NAME = "imageFile.png";
 | 
			
		||||
	public static final String ASSETS__VIDEO_FILE_NAME = "videoFile.MP4";
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	//private Account mAccount = null;
 | 
			
		||||
	private OwnCloudClient mClient;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void onCreate(Bundle savedInstanceState) {
 | 
			
		||||
		super.onCreate(savedInstanceState);
 | 
			
		||||
		setContentView(R.layout.activity_test);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		mServerUri = getString(R.string.server_base_url);
 | 
			
		||||
		mUser = getString(R.string.username);
 | 
			
		||||
		mPass = getString(R.string.password);
 | 
			
		||||
    	
 | 
			
		||||
		Protocol pr = Protocol.getProtocol("https");
 | 
			
		||||
		if (pr == null || !(pr.getSocketFactory() instanceof SelfSignedConfidentSslSocketFactory)) {
 | 
			
		||||
			try {
 | 
			
		||||
				ProtocolSocketFactory psf = new SelfSignedConfidentSslSocketFactory();
 | 
			
		||||
				Protocol.registerProtocol(
 | 
			
		||||
						"https",
 | 
			
		||||
						new Protocol("https", psf, 443));
 | 
			
		||||
				
 | 
			
		||||
			} catch (GeneralSecurityException e) {
 | 
			
		||||
				Log.e(TAG, "Self-signed confident SSL context could not be loaded");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		mClient = new OwnCloudClient(Uri.parse(mServerUri), NetworkUtils.getMultiThreadedConnManager());
 | 
			
		||||
		mClient.setDefaultTimeouts(
 | 
			
		||||
				OwnCloudClientFactory.DEFAULT_DATA_TIMEOUT, 
 | 
			
		||||
				OwnCloudClientFactory.DEFAULT_CONNECTION_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
		mClient = new OwnCloudClient(Uri.parse(mServerUri));
 | 
			
		||||
		mClient.setFollowRedirects(true);
 | 
			
		||||
		mClient.setCredentials(
 | 
			
		||||
				OwnCloudCredentialsFactory.newBasicCredentials(
 | 
			
		||||
						mUser, 
 | 
			
		||||
						mUser,
 | 
			
		||||
						mPass
 | 
			
		||||
				)
 | 
			
		||||
		);
 | 
			
		||||
		mClient.setBaseUri(Uri.parse(mServerUri));
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		Log.v(TAG, "onCreate finished, ownCloud client ready");
 | 
			
		||||
    	
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
@ -134,57 +111,57 @@ public class TestActivity extends Activity {
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Create a Folder
 | 
			
		||||
	 * @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 if 
 | 
			
		||||
     * @param createFullPath        'True' means that all the ancestor folders should be created if
 | 
			
		||||
     * 								don't exist yet.
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	public RemoteOperationResult createFolder(String remotePath, boolean createFullPath) {
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		return TestActivity.createFolder(remotePath, createFullPath, mClient);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Create a Folder
 | 
			
		||||
	 * @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 if 
 | 
			
		||||
     * @param createFullPath    'True' means that all the ancestor folders should be created if
 | 
			
		||||
     * 							don't exist yet.
 | 
			
		||||
	 * @param client			Client instance configured to access the target OC server.
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return	Result of the operation
 | 
			
		||||
	 */
 | 
			
		||||
	public static RemoteOperationResult createFolder(
 | 
			
		||||
			String remotePath, boolean createFullPath, OwnCloudClient client
 | 
			
		||||
		) {
 | 
			
		||||
		
 | 
			
		||||
		CreateRemoteFolderOperation createOperation = 
 | 
			
		||||
 | 
			
		||||
		CreateRemoteFolderOperation createOperation =
 | 
			
		||||
				new CreateRemoteFolderOperation(remotePath, createFullPath);
 | 
			
		||||
		RemoteOperationResult result =  createOperation.execute(client);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Rename a File or Folder
 | 
			
		||||
	 * @param oldName			Old name of the file.
 | 
			
		||||
     * @param oldRemotePath		Old remote path of the file. For folders it starts and ends by "/"
 | 
			
		||||
     * @param newName			New name to set as the name of file.
 | 
			
		||||
     * @param isFolder			'true' for folder and 'false' for files
 | 
			
		||||
     * 
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
	public RemoteOperationResult renameFile(String oldName, String oldRemotePath, String newName, boolean isFolder) {
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		RenameRemoteFileOperation renameOperation = new RenameRemoteFileOperation(oldName, oldRemotePath, newName, isFolder);
 | 
			
		||||
		RemoteOperationResult result = renameOperation.execute(mClient);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Remove a File or Folder
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param remotePath	Remote path of the file or folder in the server.
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
@ -193,10 +170,10 @@ public class TestActivity extends Activity {
 | 
			
		||||
		RemoteOperationResult result = removeOperation.execute(mClient);
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** 
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Remove a File or Folder
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param remotePath	Remote path of the file or folder in the server.
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
@ -205,46 +182,46 @@ public class TestActivity extends Activity {
 | 
			
		||||
		RemoteOperationResult result = removeOperation.execute(client);
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Read a Folder (PROPFIND DEPTH 1)
 | 
			
		||||
	 * @param remotePath
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	public RemoteOperationResult readFile(String remotePath) {
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		ReadRemoteFolderOperation readOperation= new ReadRemoteFolderOperation(remotePath);
 | 
			
		||||
		RemoteOperationResult result = readOperation.execute(mClient);
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Download a File
 | 
			
		||||
	 * @param remotePath
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	public RemoteOperationResult downloadFile(RemoteFile remoteFile, String temporalFolder) {
 | 
			
		||||
		// Create folder 
 | 
			
		||||
		// Create folder
 | 
			
		||||
		String path =  "/owncloud/tmp/" + temporalFolder;
 | 
			
		||||
		File privateFolder = getFilesDir();
 | 
			
		||||
		File folder = new File(privateFolder.getAbsolutePath() + "/" + path);
 | 
			
		||||
		folder.mkdirs();
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		DownloadRemoteFileOperation downloadOperation = new DownloadRemoteFileOperation(remoteFile.getRemotePath(), folder.getAbsolutePath());
 | 
			
		||||
		RemoteOperationResult result = downloadOperation.execute(mClient);
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Access to the library method to Upload a File 
 | 
			
		||||
 | 
			
		||||
	/** Access to the library method to Upload a File
 | 
			
		||||
	 * @param storagePath
 | 
			
		||||
	 * @param remotePath
 | 
			
		||||
	 * @param mimeType
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	public RemoteOperationResult uploadFile(
 | 
			
		||||
@ -253,13 +230,13 @@ public class TestActivity extends Activity {
 | 
			
		||||
 | 
			
		||||
		return TestActivity.uploadFile(storagePath, remotePath, mimeType, mClient);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/** Access to the library method to Upload a File 
 | 
			
		||||
 | 
			
		||||
	/** Access to the library method to Upload a File
 | 
			
		||||
	 * @param storagePath
 | 
			
		||||
	 * @param remotePath
 | 
			
		||||
	 * @param mimeType
 | 
			
		||||
	 * @param client			Client instance configured to access the target OC server.
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	public static RemoteOperationResult uploadFile(
 | 
			
		||||
@ -271,31 +248,31 @@ public class TestActivity extends Activity {
 | 
			
		||||
        UploadRemoteFileOperation uploadOperation;
 | 
			
		||||
 | 
			
		||||
		if ((new File(storagePath)).length() > ChunkedUploadRemoteFileOperation.CHUNK_SIZE ) {
 | 
			
		||||
            uploadOperation = new ChunkedUploadRemoteFileOperation(
 | 
			
		||||
            		storagePath, remotePath, mimeType, fileLastModifTimestamp
 | 
			
		||||
            uploadOperation = new ChunkedUploadRemoteFileOperation("1",
 | 
			
		||||
            		storagePath, remotePath, mimeType, TAG, fileLastModifTimestamp
 | 
			
		||||
    		);
 | 
			
		||||
        } else {
 | 
			
		||||
            uploadOperation = new UploadRemoteFileOperation(
 | 
			
		||||
            		storagePath, remotePath, mimeType, fileLastModifTimestamp
 | 
			
		||||
    		);
 | 
			
		||||
        }
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		RemoteOperationResult result = uploadOperation.execute(client);
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/** Access to the library method to Get Shares 
 | 
			
		||||
	 * 
 | 
			
		||||
	/** Access to the library method to Get Shares
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	public RemoteOperationResult getShares(){
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		GetRemoteSharesOperation getOperation = new GetRemoteSharesOperation();
 | 
			
		||||
		RemoteOperationResult result = getOperation.execute(mClient);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/** Access to the library method to Create Share
 | 
			
		||||
	 * @param path			Full path of the file/folder being shared. Mandatory argument
 | 
			
		||||
	 * @param shareType		0 = user, 1 = group, 3 = Public link. Mandatory argument
 | 
			
		||||
@ -310,33 +287,33 @@ public class TestActivity extends Activity {
 | 
			
		||||
	 * 						16- Re-share
 | 
			
		||||
	 * 						31- All above Default for private shares
 | 
			
		||||
	 * 						For user or group shares.
 | 
			
		||||
	 * 						To obtain combinations, add the desired values together.  
 | 
			
		||||
	 * 						To obtain combinations, add the desired values together.
 | 
			
		||||
	 * 						For instance, for Re-Share, delete, read, update add 16+8+2+1 = 27.
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	public RemoteOperationResult createShare(String path, ShareType shareType, String shareWith, boolean publicUpload, 
 | 
			
		||||
	public RemoteOperationResult createShare(String path, ShareType shareType, String shareWith, boolean publicUpload,
 | 
			
		||||
			String password, int permissions){
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		CreateRemoteShareOperation createOperation = new CreateRemoteShareOperation(path, shareType, shareWith, publicUpload, password, permissions);
 | 
			
		||||
		RemoteOperationResult result = createOperation.execute(mClient);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access to the library method to Remove Share
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param idShare	Share ID
 | 
			
		||||
	 */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	public RemoteOperationResult removeShare(int idShare) {
 | 
			
		||||
		RemoveRemoteShareOperation removeOperation = new RemoveRemoteShareOperation(idShare);
 | 
			
		||||
		RemoteOperationResult result = removeOperation.execute(mClient);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		return result;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public RemoteOperationResult getQuota(String remotePath) {
 | 
			
		||||
@ -349,20 +326,20 @@ public class TestActivity extends Activity {
 | 
			
		||||
		GetRemoteUserAvatarOperation getUserAvatarOperation = new GetRemoteUserAvatarOperation(dimension, etag);
 | 
			
		||||
		return getUserAvatarOperation.execute(mClient);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Extracts file from AssetManager to cache folder.
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param	fileName	Name of the asset file to extract.
 | 
			
		||||
	 * @return				File instance of the extracted file.
 | 
			
		||||
	 */
 | 
			
		||||
	public File extractAsset(String fileName) throws IOException {
 | 
			
		||||
		return TestActivity.extractAsset(fileName, this);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Extracts file from AssetManager to cache folder.
 | 
			
		||||
	 * 
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param	fileName	Name of the asset file to extract.
 | 
			
		||||
	 * @param	context		Android context to access assets and file system.
 | 
			
		||||
	 * @return				File instance of the extracted file.
 | 
			
		||||
@ -391,4 +368,4 @@ public class TestActivity extends Activity {
 | 
			
		||||
        Long timeStampLong = file.lastModified()/1000;
 | 
			
		||||
        return timeStampLong.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -37,14 +37,13 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode;
 | 
			
		||||
import com.owncloud.android.lib.resources.files.CopyRemoteFileOperation;
 | 
			
		||||
import com.owncloud.android.lib.test_project.R;
 | 
			
		||||
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
 | 
			
		||||
import com.owncloud.android.lib.test_project.TestActivity;
 | 
			
		||||
 | 
			
		||||
import junit.framework.AssertionFailedError;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.HttpStatus;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.Protocol;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.security.GeneralSecurityException;
 | 
			
		||||
@ -373,7 +372,7 @@ public class CopyFileTest extends ActivityInstrumentationTestCase2<TestActivity>
 | 
			
		||||
                false
 | 
			
		||||
        );
 | 
			
		||||
        result = copyOperation.execute(mClient);
 | 
			
		||||
        assertTrue(result.getHttpCode() == HttpStatus.SC_CONFLICT);
 | 
			
		||||
        assertTrue(result.getHttpCode() == HttpConstants.HTTP_CONFLICT);
 | 
			
		||||
 | 
			
		||||
        // target location (renaming) has invalid characters
 | 
			
		||||
        copyOperation = new CopyRemoteFileOperation(
 | 
			
		||||
 | 
			
		||||
@ -29,8 +29,8 @@ import java.security.GeneralSecurityException;
 | 
			
		||||
 | 
			
		||||
import junit.framework.AssertionFailedError;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.httpclient.protocol.Protocol;
 | 
			
		||||
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import android.content.Context;
 | 
			
		||||
import android.net.Uri;
 | 
			
		||||
@ -43,7 +43,6 @@ import com.owncloud.android.lib.common.network.NetworkUtils;
 | 
			
		||||
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
 | 
			
		||||
import com.owncloud.android.lib.resources.status.GetRemoteCapabilitiesOperation;
 | 
			
		||||
import com.owncloud.android.lib.test_project.R;
 | 
			
		||||
import com.owncloud.android.lib.test_project.SelfSignedConfidentSslSocketFactory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Class to test GetRemoteCapabilitiesOperation
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user