Revision a74ba506
b/snf-pithos-app/README | ||
---|---|---|
47 | 47 |
|
48 | 48 |
pithos-dispatcher --exchange=pithos --key=pithos.object --callback=pithos.api.dispatch.update_md5 |
49 | 49 |
|
50 |
To send sharing notifications:: |
|
51 |
|
|
52 |
pithos-dispatcher --exchange=pithos --key=pithos.sharing --callback=pithos.api.dispatch.send_sharing_notification |
|
53 |
|
|
50 | 54 |
Administrator functions |
51 | 55 |
----------------------- |
52 | 56 |
|
b/snf-pithos-app/pithos/api/dispatch.py | ||
---|---|---|
5 | 5 |
from pithos.backends import connect_backend |
6 | 6 |
from pithos.api.util import hashmap_md5 |
7 | 7 |
|
8 |
from django.core.mail import send_mail |
|
9 |
from django.utils.translation import ugettext as _ |
|
10 |
|
|
11 |
from astakos.im.settings import DEFAULT_FROM_EMAIL |
|
12 |
|
|
8 | 13 |
def update_md5(m): |
9 | 14 |
if m['resource'] != 'object' or m['details']['action'] != 'object update': |
10 | 15 |
return |
... | ... | |
33 | 38 |
print 'WARNING: Can not update checksum for path "%s" (%s)' % (path, e) |
34 | 39 |
|
35 | 40 |
backend.close() |
41 |
|
|
42 |
def send_sharing_notification(m): |
|
43 |
if m['resource'] != 'sharing': |
|
44 |
return |
|
45 |
|
|
46 |
members = m['details']['members'] |
|
47 |
user = m['details']['user'] |
|
48 |
path = m['value'] |
|
49 |
account, container, name = path.split('/', 2) |
|
50 |
|
|
51 |
subject = 'Invitation to a Pithos+ shared object' |
|
52 |
from_email = DEFAULT_FROM_EMAIL |
|
53 |
recipient_list = members |
|
54 |
message = 'User %s has invited you to a Pithos+ shared object. You can view it under "Shared to me" at "%s".' %(user, path) |
|
55 |
try: |
|
56 |
send_mail(subject, message, from_email, recipient_list) |
|
57 |
print 'INFO: Sharing notification sent for path "%s" to %s' % (path, ','.join(recipient_list)) |
|
58 |
except (SMTPException, socket.error) as e: |
|
59 |
print 'WARNING: Can not update send email for sharing "%s" (%s)' % (path, e) |
b/snf-pithos-backend/pithos/backends/lib/sqlalchemy/permissions.py | ||
---|---|---|
92 | 92 |
del(permissions[WRITE]) |
93 | 93 |
return permissions |
94 | 94 |
|
95 |
def access_members(self, path): |
|
96 |
feature = self.xfeature_get(path) |
|
97 |
if not feature: |
|
98 |
return [] |
|
99 |
permissions = self.feature_dict(feature) |
|
100 |
members = set() |
|
101 |
members.update(permissions.get(READ, [])) |
|
102 |
members.update(permissions.get(WRITE, [])) |
|
103 |
for m in set(members): |
|
104 |
parts = m.split(':', 1) |
|
105 |
if len(parts) != 2: |
|
106 |
continue |
|
107 |
user, group = parts |
|
108 |
members.remove(m) |
|
109 |
members.update(self.group_members(user, group)) |
|
110 |
return list(members) |
|
111 |
|
|
95 | 112 |
def access_clear(self, path): |
96 | 113 |
"""Revoke access to path (both permissions and public).""" |
97 | 114 |
|
b/snf-pithos-backend/pithos/backends/lib/sqlite/permissions.py | ||
---|---|---|
89 | 89 |
del(permissions[WRITE]) |
90 | 90 |
return permissions |
91 | 91 |
|
92 |
def access_members(self, path): |
|
93 |
feature = self.xfeature_get(path) |
|
94 |
if not feature: |
|
95 |
return [] |
|
96 |
permissions = self.feature_dict(feature) |
|
97 |
members = set() |
|
98 |
members.update(permissions.get(READ, [])) |
|
99 |
members.update(permissions.get(WRITE, [])) |
|
100 |
for m in set(members): |
|
101 |
parts = m.split(':', 1) |
|
102 |
if len(parts) != 2: |
|
103 |
continue |
|
104 |
user, group = parts |
|
105 |
members.remove(m) |
|
106 |
members.update(self.group_members(user, group)) |
|
107 |
return members |
|
108 |
|
|
92 | 109 |
def access_clear(self, path): |
93 | 110 |
"""Revoke access to path (both permissions and public).""" |
94 | 111 |
|
b/snf-pithos-backend/pithos/backends/modular.py | ||
---|---|---|
104 | 104 |
try: |
105 | 105 |
self.messages = [] |
106 | 106 |
ret = func(self, *args, **kw) |
107 |
self.wrapper.commit() |
|
108 | 107 |
for m in self.messages: |
109 | 108 |
self.queue.send(*m) |
109 |
self.wrapper.commit() |
|
110 | 110 |
return ret |
111 | 111 |
except: |
112 | 112 |
self.wrapper.rollback() |
... | ... | |
603 | 603 |
path = self._lookup_object(account, container, name)[0] |
604 | 604 |
self._check_permissions(path, permissions) |
605 | 605 |
self.permissions.access_set(path, permissions) |
606 |
self._report_sharing_change(user, account, path, {'members':self.permissions.access_members(path)}) |
|
606 | 607 |
|
607 | 608 |
@backend_method |
608 | 609 |
def get_object_public(self, user, account, container, name): |
... | ... | |
671 | 672 |
|
672 | 673 |
if permissions is not None: |
673 | 674 |
self.permissions.access_set(path, permissions) |
675 |
self._report_sharing_change(user, account, path, {'members':self.permissions.access_members(path)}) |
|
674 | 676 |
|
675 | 677 |
self._report_object_change(user, account, path, details={'version': dest_version_id, 'action': 'object update'}) |
676 | 678 |
return dest_version_id |
... | ... | |
1018 | 1020 |
details.update({'user': user}) |
1019 | 1021 |
self.messages.append((QUEUE_MESSAGE_KEY_PREFIX % ('object',), account, QUEUE_INSTANCE_ID, 'object', path, details)) |
1020 | 1022 |
|
1023 |
def _report_sharing_change(self, user, account, path, details={}): |
|
1024 |
logger.debug("_report_permissions_change: %s %s %s %s", user, account, path, details) |
|
1025 |
details.update({'user': user}) |
|
1026 |
self.messages.append((QUEUE_MESSAGE_KEY_PREFIX % ('sharing',), account, QUEUE_INSTANCE_ID, 'sharing', path, details)) |
|
1027 |
|
|
1021 | 1028 |
# Policy functions. |
1022 | 1029 |
|
1023 | 1030 |
def _check_policy(self, policy): |
Also available in: Unified diff