udata 10.0.5.dev32897__py2.py3-none-any.whl → 10.0.5.dev32923__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of udata might be problematic. Click here for more details.

Files changed (28) hide show
  1. udata/core/organization/api_fields.py +13 -1
  2. udata/features/transfer/actions.py +1 -0
  3. udata/features/transfer/api.py +49 -2
  4. udata/features/transfer/models.py +1 -0
  5. udata/static/chunks/{10.471164b2a9fe15614797.js → 10.8ca60413647062717b1e.js} +3 -3
  6. udata/static/chunks/{10.471164b2a9fe15614797.js.map → 10.8ca60413647062717b1e.js.map} +1 -1
  7. udata/static/chunks/{11.83535504cd650ea08f65.js → 11.b6f741fcc366abfad9c4.js} +3 -3
  8. udata/static/chunks/{11.83535504cd650ea08f65.js.map → 11.b6f741fcc366abfad9c4.js.map} +1 -1
  9. udata/static/chunks/{13.d9c1735d14038b94c17e.js → 13.2d06442dd9a05d9777b5.js} +2 -2
  10. udata/static/chunks/{13.d9c1735d14038b94c17e.js.map → 13.2d06442dd9a05d9777b5.js.map} +1 -1
  11. udata/static/chunks/{17.81c57c0dedf812e43013.js → 17.e8e4caaad5cb0cc0bacc.js} +2 -2
  12. udata/static/chunks/{17.81c57c0dedf812e43013.js.map → 17.e8e4caaad5cb0cc0bacc.js.map} +1 -1
  13. udata/static/chunks/{19.df16abde17a42033a7f8.js → 19.f03a102365af4315f9db.js} +3 -3
  14. udata/static/chunks/{19.df16abde17a42033a7f8.js.map → 19.f03a102365af4315f9db.js.map} +1 -1
  15. udata/static/chunks/{8.462bb3029de008497675.js → 8.778091d55cd8ea39af6b.js} +2 -2
  16. udata/static/chunks/{8.462bb3029de008497675.js.map → 8.778091d55cd8ea39af6b.js.map} +1 -1
  17. udata/static/chunks/{9.07515e5187f475bce828.js → 9.033d7e190ca9e226a5d0.js} +3 -3
  18. udata/static/chunks/{9.07515e5187f475bce828.js.map → 9.033d7e190ca9e226a5d0.js.map} +1 -1
  19. udata/static/common.js +1 -1
  20. udata/static/common.js.map +1 -1
  21. udata/tests/api/test_organizations_api.py +22 -8
  22. udata/tests/api/test_transfer_api.py +117 -11
  23. {udata-10.0.5.dev32897.dist-info → udata-10.0.5.dev32923.dist-info}/METADATA +3 -1
  24. {udata-10.0.5.dev32897.dist-info → udata-10.0.5.dev32923.dist-info}/RECORD +28 -28
  25. {udata-10.0.5.dev32897.dist-info → udata-10.0.5.dev32923.dist-info}/LICENSE +0 -0
  26. {udata-10.0.5.dev32897.dist-info → udata-10.0.5.dev32923.dist-info}/WHEEL +0 -0
  27. {udata-10.0.5.dev32897.dist-info → udata-10.0.5.dev32923.dist-info}/entry_points.txt +0 -0
  28. {udata-10.0.5.dev32897.dist-info → udata-10.0.5.dev32923.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  from flask import request
2
2
 
3
3
  from udata.api import api, base_reference, fields
4
+ from udata.auth.helpers import current_user_is_admin_or_self
4
5
  from udata.core.badges.fields import badge_fields
5
6
  from udata.core.organization.permissions import OrganizationPrivatePermission
6
7
 
@@ -60,12 +61,23 @@ def check_can_access_user_private_info():
60
61
  return OrganizationPrivatePermission(org).can()
61
62
 
62
63
 
64
+ def member_email_with_visibility_check(email):
65
+ if current_user_is_admin_or_self():
66
+ return email
67
+ if check_can_access_user_private_info():
68
+ # Obfuscate email partially for other members
69
+ name, domain = email.split("@")
70
+ name = name[:2] + "*" * (len(name) - 2)
71
+ return f"{name}@{domain}"
72
+ return None
73
+
74
+
63
75
  member_user_with_email_fields = api.inherit(
64
76
  "MemberUserWithEmail",
65
77
  user_ref_fields,
66
78
  {
67
79
  "email": fields.Raw(
68
- attribute=lambda o: o.email if check_can_access_user_private_info() else None,
80
+ attribute=lambda o: member_email_with_visibility_check(o.email),
69
81
  description="The user email (only present on show organization endpoint if the current user is member of the organization: admin or editor)",
70
82
  readonly=True,
71
83
  ),
@@ -17,6 +17,7 @@ def request_transfer(subject, recipient, comment):
17
17
  if recipient == (subject.organization or subject.owner):
18
18
  raise ValueError("Recipient should be different than the current owner")
19
19
  transfer = Transfer.objects.create(
20
+ user=current_user._get_current_object(),
20
21
  owner=subject.organization or subject.owner,
21
22
  recipient=recipient,
22
23
  subject=subject,
@@ -4,6 +4,10 @@ from udata.api import API, api, base_reference, fields
4
4
  from udata.core.dataset.api_fields import dataset_ref_fields
5
5
  from udata.core.organization.api_fields import org_ref_fields
6
6
  from udata.core.user.api_fields import user_ref_fields
7
+ from udata.features.transfer.permissions import (
8
+ TransferPermission,
9
+ TransferResponsePermission,
10
+ )
7
11
  from udata.models import Dataset, Organization, Reuse, User, db
8
12
  from udata.utils import id_or_404
9
13
 
@@ -53,6 +57,12 @@ transfer_fields = api.model(
53
57
  "Transfer",
54
58
  {
55
59
  "id": fields.String(readonly=True, description="The transfer unique identifier"),
60
+ "user": fields.Nested(
61
+ user_ref_fields,
62
+ description="The user who requested the transfer",
63
+ readonly=True,
64
+ allow_null=True,
65
+ ),
56
66
  "owner": fields.Polymorph(
57
67
  person_mapping,
58
68
  readonly=True,
@@ -81,14 +91,51 @@ transfer_fields = api.model(
81
91
 
82
92
  ns = api.namespace("transfer")
83
93
 
94
+ requests_parser = api.parser()
95
+ requests_parser.add_argument(
96
+ "subject", type=str, help="ID of dataset, dataservice, reuse…", location="args"
97
+ )
98
+ requests_parser.add_argument(
99
+ "subject_type", choices=["Dataset", "Reuse", "Dataservice"], type=str, help="", location="args"
100
+ )
101
+ requests_parser.add_argument(
102
+ "recipient", type=str, help="ID of user or organization", location="args"
103
+ )
104
+ requests_parser.add_argument(
105
+ "status",
106
+ type=str,
107
+ choices=TRANSFER_STATUS.keys(),
108
+ help="ID of user or organization",
109
+ location="args",
110
+ )
111
+
84
112
 
85
113
  @ns.route("/", endpoint="transfers")
86
114
  class TransferRequestsAPI(API):
87
115
  @api.doc("list_transfers")
88
116
  @api.marshal_list_with(transfer_fields)
89
117
  def get(self):
90
- """List all transfer requests"""
91
- pass
118
+ args = requests_parser.parse_args()
119
+
120
+ transfers = Transfer.objects
121
+ if args["subject"]:
122
+ transfers = transfers.generic_in(subject=args["subject"])
123
+ if args["subject_type"]:
124
+ transfers = transfers.filter(__raw__={"subject._cls": args["subject_type"]})
125
+ if args["recipient"]:
126
+ transfers = transfers.generic_in(recipient=args["recipient"])
127
+ if args["status"]:
128
+ transfers = transfers.filter(status=args["status"])
129
+
130
+ if not (args["subject"] or args["recipient"]):
131
+ api.abort(400, "Please provide at least a `subject` or a `recipient`")
132
+
133
+ return [
134
+ transfer
135
+ for transfer in transfers
136
+ if TransferPermission(transfer.subject).can()
137
+ or TransferResponsePermission(transfer).can()
138
+ ]
92
139
 
93
140
  @api.doc("request_transfer")
94
141
  @api.expect(transfer_request_fields)
@@ -17,6 +17,7 @@ TRANSFER_STATUS = {
17
17
 
18
18
 
19
19
  class Transfer(db.Document):
20
+ user = db.ReferenceField("User")
20
21
  owner = db.GenericReferenceField(required=True)
21
22
  recipient = db.GenericReferenceField(required=True)
22
23
  subject = db.GenericReferenceField(required=True)