Skip to content

Commit a68cbcf

Browse files
committed
Add permissions and expiration date for public share
1 parent 9aa89e5 commit a68cbcf

File tree

2 files changed

+69
-18
lines changed

2 files changed

+69
-18
lines changed

owncloud/owncloud.py

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,17 @@ def __init__(self, res):
4343
class PublicShare():
4444
"""Public share information"""
4545

46-
def __init__(self, share_id, target_file, link, token):
46+
def __init__(self, share_id, target_file, link, token, **kwargs):
4747
self.share_id = share_id
4848
self.target_file = target_file
4949
self.link = link
5050
self.token = token
51+
self.permissions = kwargs.get('permissions', None)
52+
self.expiration = kwargs.get('expiration', None)
5153

5254
def __str__(self):
53-
return 'PublicShare(id=%i,path=%s,link=%s,token=%s)' % \
54-
(self.share_id, self.target_file, self.link, self.token)
55+
return 'PublicShare(id=%i,path=%s,link=%s,token=%s,permissions=%s,expiration=%s)' % \
56+
(self.share_id, self.target_file, self.link, self.token, self.permissions, self.expiration)
5557

5658

5759
class UserShare():
@@ -602,16 +604,18 @@ def update_share(self, share_id, **kwargs):
602604
:param perms: (int) update permissions (see share_file_with_user() below)
603605
:param password: (string) updated password for public link Share
604606
:param public_upload: (boolean) enable/disable public upload for public shares
607+
:param expiration: (optional) expiration date object, or string in format 'YYYY-MM-DD'
605608
:returns: True if the operation succeeded, False otherwise
606609
:raises: HTTPResponseError in case an HTTP error status was returned
607610
"""
608611

609612
perms = kwargs.get('perms', None)
610613
password = kwargs.get('password', None)
611614
public_upload = kwargs.get('public_upload', None)
615+
expiration = kwargs.get('expiration', None)
612616
if (isinstance(perms, int)) and (perms > self.OCS_PERMISSION_ALL):
613617
perms = None
614-
if not (perms or password or (public_upload is not None)):
618+
if not (perms or password or (public_upload is not None) or (expiration is not None)):
615619
return False
616620
if not isinstance(share_id, int):
617621
return False
@@ -623,6 +627,8 @@ def update_share(self, share_id, **kwargs):
623627
data['password'] = password
624628
if (public_upload is not None) and (isinstance(public_upload, bool)):
625629
data['publicUpload'] = str(public_upload).lower()
630+
if expiration is not None:
631+
data['expireDate'] = self.__parse_expiration_date(expiration)
626632

627633
res = self.__make_ocs_request(
628634
'PUT',
@@ -666,15 +672,16 @@ def share_file_with_link(self, path, **kwargs):
666672
defaults to read only (1)
667673
:param public_upload (optional): allows users to upload files or folders
668674
:param password (optional): sets a password
675+
:param expiration: (optional) expiration date object, or string in format 'YYYY-MM-DD'
669676
http://doc.owncloud.org/server/6.0/admin_manual/sharing_api/index.html
670677
:returns: instance of :class:`PublicShare` with the share info
671678
or False if the operation failed
672679
:raises: HTTPResponseError in case an HTTP error status was returned
673680
"""
674681
perms = kwargs.get('perms', None)
675682
public_upload = kwargs.get('public_upload', 'false')
676-
password = kwargs.get('password', None)
677-
683+
password = kwargs.get('password', None)
684+
expiration = kwargs.get('expiration', None)
678685

679686
path = self.__normalize_path(path)
680687
post_data = {
@@ -687,6 +694,8 @@ def share_file_with_link(self, path, **kwargs):
687694
post_data['password'] = password
688695
if perms:
689696
post_data['permissions'] = perms
697+
if expiration is not None:
698+
post_data['expireDate'] = self.__parse_expiration_date(expiration)
690699

691700
res = self.__make_ocs_request(
692701
'POST',
@@ -698,11 +707,24 @@ def share_file_with_link(self, path, **kwargs):
698707
tree = ET.fromstring(res.content)
699708
self.__check_ocs_status(tree)
700709
data_el = tree.find('data')
710+
711+
expiration = None
712+
exp_el = data_el.find('expiration')
713+
if exp_el is not None and exp_el.text is not None and len(exp_el.text) > 0:
714+
expiration = exp_el.text
715+
716+
permissions = None
717+
perms_el = data_el.find('permissions')
718+
if perms_el is not None and perms_el.text is not None and len(perms_el.text) > 0:
719+
permissions = int(perms_el.text)
720+
701721
return PublicShare(
702722
int(data_el.find('id').text),
703723
path,
704724
data_el.find('url').text,
705-
data_el.find('token').text
725+
data_el.find('token').text,
726+
permissions=permissions,
727+
expiration=expiration
706728
)
707729
raise HTTPResponseError(res)
708730

@@ -824,24 +846,24 @@ def user_exists(self, user_name):
824846
"""Checks a user via provisioning API.
825847
If you get back an error 999, then the provisioning API is not enabled.
826848
827-
:param user_name: name of user to be checked
828-
:returns: True if user found
829-
849+
:param user_name: name of user to be checked
850+
:returns: True if user found
851+
830852
"""
831853
users=self.search_users(user_name)
832-
854+
833855
if len(users) > 0:
834856
for user in users:
835857
if user.text == user_name:
836858
return True
837-
859+
838860
return False
839861

840862
def search_users(self, user_name):
841863
"""Searches for users via provisioning API.
842864
If you get back an error 999, then the provisioning API is not enabled.
843865
844-
:param user_name: name of user to be searched for
866+
:param user_name: name of user to be searched for
845867
:returns: list of users
846868
:raises: HTTPResponseError in case an HTTP error status was returned
847869
@@ -856,7 +878,7 @@ def search_users(self, user_name):
856878
tree = ET.fromstring(res.text)
857879
users = tree.find('data/users')
858880

859-
return users
881+
return users
860882

861883
raise HTTPResponseError(res)
862884

@@ -1377,6 +1399,22 @@ def __encode_string(s):
13771399
return s.encode('utf-8')
13781400
return s
13791401

1402+
@staticmethod
1403+
def __parse_expiration_date(date):
1404+
"""Converts the given datetime object into the format required
1405+
by the share API
1406+
1407+
:param date: datetime object
1408+
:returns: string encoded to use as expireDate parameter in the share API
1409+
"""
1410+
if date is None:
1411+
return None
1412+
1413+
if isinstance(date, datetime.datetime):
1414+
return date.strftime('YYYY-MM-DD')
1415+
1416+
return date
1417+
13801418
@staticmethod
13811419
def __check_ocs_status(tree, accepted_codes=[100]):
13821420
"""Checks the status code of an OCS request
@@ -1497,7 +1535,7 @@ def __strip_dav_path(self, path):
14971535
if path.startswith(self.__davpath):
14981536
return path[len(self.__davpath):]
14991537
return path
1500-
1538+
15011539
def __webdav_move_copy(self,remote_path_source,remote_path_target,operation):
15021540
"""Copies or moves a remote file or directory
15031541

owncloud/test/test.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,16 +562,16 @@ def test_share_with_link(self, file_name):
562562
path = self.test_root + file_name
563563
self.assertTrue(self.client.put_file_contents(path, 'hello world!'))
564564

565-
share_info = self.client.share_file_with_link(path, public_upload=True, password='1234')
565+
share_info = self.client.share_file_with_link(path, public_upload=True, password='1234', expiration='2150-02-04')
566566

567567
self.assertTrue(self.client.is_shared(path))
568568
self.assertTrue(isinstance(share_info, owncloud.PublicShare))
569569
self.assertTrue(type(share_info.share_id) is int)
570570
self.assertEquals(share_info.target_file, path)
571571
self.assertTrue(type(share_info.link) is str)
572572
self.assertTrue(type(share_info.token) is str)
573-
574-
573+
self.assertEquals(share_info.permissions, 7)
574+
self.assertEquals(share_info.expiration, '2150-02-04 00:00:00')
575575

576576
def test_share_with_link_non_existing_file(self):
577577
"""Test sharing a file with link"""
@@ -731,6 +731,19 @@ def test_update_share_password(self):
731731
self.assertIsNotNone(share_info['share_with_displayname'])
732732
self.assertTrue(self.client.delete_share(share_id))
733733

734+
def test_update_share_expiration(self):
735+
"""Test updating a share parameters - expiration date"""
736+
path = self.test_root + 'update_share_expiration'
737+
self.client.mkdir(path)
738+
739+
share_info = self.client.share_file_with_link(path)
740+
share_id = share_info.share_id
741+
self.assertTrue(self.client.update_share(share_id, expiration='2150-02-04'))
742+
share_info = self.client.get_shares(path)[0]
743+
self.assertTrue('expiration' in share_info)
744+
self.assertEquals(share_info['expiration'], '2150-02-04 00:00:00')
745+
self.assertTrue(self.client.delete_share(share_id))
746+
734747

735748
class TestPrivateDataAccess(unittest.TestCase):
736749
attrs = lambda: (

0 commit comments

Comments
 (0)