Skip to content

Commit 63aed10

Browse files
PVince81Vincent Petry
authored andcommitted
Add permissions and expiration date for public share
1 parent 0c90c4d commit 63aed10

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

owncloud/owncloud.py

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,17 @@ def __init__(self, res):
5555
class PublicShare():
5656
"""Public share information"""
5757

58-
def __init__(self, share_id, target_file, link, token):
58+
def __init__(self, share_id, target_file, link, token, **kwargs):
5959
self.share_id = share_id
6060
self.target_file = target_file
6161
self.link = link
6262
self.token = token
63+
self.permissions = kwargs.get('permissions', None)
64+
self.expiration = kwargs.get('expiration', None)
6365

6466
def __str__(self):
65-
return 'PublicShare(id=%i,path=%s,link=%s,token=%s)' % \
66-
(self.share_id, self.target_file, self.link, self.token)
67+
return 'PublicShare(id=%i,path=%s,link=%s,token=%s,permissions=%s,expiration=%s)' % \
68+
(self.share_id, self.target_file, self.link, self.token, self.permissions, self.expiration)
6769

6870

6971
class UserShare():
@@ -613,16 +615,18 @@ def update_share(self, share_id, **kwargs):
613615
:param perms: (int) update permissions (see share_file_with_user() below)
614616
:param password: (string) updated password for public link Share
615617
:param public_upload: (boolean) enable/disable public upload for public shares
618+
:param expiration: (optional) expiration date object, or string in format 'YYYY-MM-DD'
616619
:returns: True if the operation succeeded, False otherwise
617620
:raises: HTTPResponseError in case an HTTP error status was returned
618621
"""
619622

620623
perms = kwargs.get('perms', None)
621624
password = kwargs.get('password', None)
622625
public_upload = kwargs.get('public_upload', None)
626+
expiration = kwargs.get('expiration', None)
623627
if (isinstance(perms, int)) and (perms > self.OCS_PERMISSION_ALL):
624628
perms = None
625-
if not (perms or password or (public_upload is not None)):
629+
if not (perms or password or (public_upload is not None) or (expiration is not None)):
626630
return False
627631
if not isinstance(share_id, int):
628632
return False
@@ -634,6 +638,8 @@ def update_share(self, share_id, **kwargs):
634638
data['password'] = password
635639
if (public_upload is not None) and (isinstance(public_upload, bool)):
636640
data['publicUpload'] = str(public_upload).lower()
641+
if expiration is not None:
642+
data['expireDate'] = self.__parse_expiration_date(expiration)
637643

638644
res = self.__make_ocs_request(
639645
'PUT',
@@ -677,15 +683,16 @@ def share_file_with_link(self, path, **kwargs):
677683
defaults to read only (1)
678684
:param public_upload (optional): allows users to upload files or folders
679685
:param password (optional): sets a password
686+
:param expiration: (optional) expiration date object, or string in format 'YYYY-MM-DD'
680687
http://doc.owncloud.org/server/6.0/admin_manual/sharing_api/index.html
681688
:returns: instance of :class:`PublicShare` with the share info
682689
or False if the operation failed
683690
:raises: HTTPResponseError in case an HTTP error status was returned
684691
"""
685692
perms = kwargs.get('perms', None)
686693
public_upload = kwargs.get('public_upload', 'false')
687-
password = kwargs.get('password', None)
688-
694+
password = kwargs.get('password', None)
695+
expiration = kwargs.get('expiration', None)
689696

690697
path = self.__normalize_path(path)
691698
post_data = {
@@ -698,6 +705,8 @@ def share_file_with_link(self, path, **kwargs):
698705
post_data['password'] = password
699706
if perms:
700707
post_data['permissions'] = perms
708+
if expiration is not None:
709+
post_data['expireDate'] = self.__parse_expiration_date(expiration)
701710

702711
res = self.__make_ocs_request(
703712
'POST',
@@ -709,11 +718,24 @@ def share_file_with_link(self, path, **kwargs):
709718
tree = ET.fromstring(res.content)
710719
self.__check_ocs_status(tree)
711720
data_el = tree.find('data')
721+
722+
expiration = None
723+
exp_el = data_el.find('expiration')
724+
if exp_el is not None and exp_el.text is not None and len(exp_el.text) > 0:
725+
expiration = exp_el.text
726+
727+
permissions = None
728+
perms_el = data_el.find('permissions')
729+
if perms_el is not None and perms_el.text is not None and len(perms_el.text) > 0:
730+
permissions = int(perms_el.text)
731+
712732
return PublicShare(
713733
int(data_el.find('id').text),
714734
path,
715735
data_el.find('url').text,
716-
data_el.find('token').text
736+
data_el.find('token').text,
737+
permissions=permissions,
738+
expiration=expiration
717739
)
718740
raise HTTPResponseError(res)
719741

@@ -834,9 +856,9 @@ def user_exists(self, user_name):
834856
"""Checks a user via provisioning API.
835857
If you get back an error 999, then the provisioning API is not enabled.
836858
837-
:param user_name: name of user to be checked
838-
:returns: True if user found
839-
859+
:param user_name: name of user to be checked
860+
:returns: True if user found
861+
840862
"""
841863
users=self.search_users(user_name)
842864

@@ -861,7 +883,7 @@ def search_users(self, user_name):
861883
tree = ET.fromstring(res.text)
862884
users = [x.text for x in tree.findall('data/users/element')]
863885

864-
return users
886+
return users
865887

866888
raise HTTPResponseError(res)
867889

@@ -1407,6 +1429,22 @@ def __encode_string(s):
14071429
return s.encode('utf-8')
14081430
return s
14091431

1432+
@staticmethod
1433+
def __parse_expiration_date(date):
1434+
"""Converts the given datetime object into the format required
1435+
by the share API
1436+
1437+
:param date: datetime object
1438+
:returns: string encoded to use as expireDate parameter in the share API
1439+
"""
1440+
if date is None:
1441+
return None
1442+
1443+
if isinstance(date, datetime.datetime):
1444+
return date.strftime('YYYY-MM-DD')
1445+
1446+
return date
1447+
14101448
@staticmethod
14111449
def __check_ocs_status(tree, accepted_codes=[100]):
14121450
"""Checks the status code of an OCS request
@@ -1547,7 +1585,7 @@ def __strip_dav_path(self, path):
15471585
if path.startswith(self.__davpath):
15481586
return path[len(self.__davpath):]
15491587
return path
1550-
1588+
15511589
def __webdav_move_copy(self,remote_path_source,remote_path_target,operation):
15521590
"""Copies or moves a remote file or directory
15531591

owncloud/test/test.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,14 +573,16 @@ def test_share_with_link(self, file_name):
573573
path = self.test_root + file_name
574574
self.assertTrue(self.client.put_file_contents(path, 'hello world!'))
575575

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

578578
self.assertTrue(self.client.is_shared(path))
579579
self.assertTrue(isinstance(share_info, owncloud.PublicShare))
580580
self.assertTrue(type(share_info.share_id) is int)
581581
self.assertEquals(share_info.target_file, path)
582582
self.assertTrue(type(share_info.link) is str)
583583
self.assertTrue(type(share_info.token) is str)
584+
self.assertEquals(share_info.permissions, 7)
585+
self.assertEquals(share_info.expiration, '2150-02-04 00:00:00')
584586

585587
def test_share_with_link_non_existing_file(self):
586588
"""Test sharing a file with link"""
@@ -769,6 +771,19 @@ def test_update_share_password(self):
769771
self.assertIsNotNone(share_info['share_with_displayname'])
770772
self.assertTrue(self.client.delete_share(share_id))
771773

774+
def test_update_share_expiration(self):
775+
"""Test updating a share parameters - expiration date"""
776+
path = self.test_root + 'update_share_expiration'
777+
self.client.mkdir(path)
778+
779+
share_info = self.client.share_file_with_link(path)
780+
share_id = share_info.share_id
781+
self.assertTrue(self.client.update_share(share_id, expiration='2150-02-04'))
782+
share_info = self.client.get_shares(path)[0]
783+
self.assertTrue('expiration' in share_info)
784+
self.assertEquals(share_info['expiration'], '2150-02-04 00:00:00')
785+
self.assertTrue(self.client.delete_share(share_id))
786+
772787

773788
class TestPrivateDataAccess(unittest.TestCase):
774789

0 commit comments

Comments
 (0)