Skip to content

Commit c84e608

Browse files
authored
Sharing APIs (#1215)
* Start of the sharing APIs * Update the user_search API * Rename APi * Add shareapi.py * Temporary lower k8s version * Move user_search to normal master * Return list * Save the object after grant perms * Not saving the actual object to avoid infinite recursion * V1 sharing is done * Clean up * Update user_search API request format * Add sharing incoming source
1 parent a279ad4 commit c84e608

File tree

6 files changed

+137
-1
lines changed

6 files changed

+137
-1
lines changed

jaseci_core/jaseci/extens/api/master_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def master_list(self, detailed: bool = False):
7373
def master_active_set(self, name: str):
7474
"""
7575
Sets the default master master should use
76-
NOTE: Specail handler included in general_interface_to_api
76+
NOTE: Special handler included in general_interface_to_api
7777
"""
7878
mas = self.sub_master_ids.get_obj_by_name(name)
7979
if not mas:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
Object sharing APIs
3+
"""
4+
from jaseci.extens.api.interface import Interface
5+
from jaseci.prim.element import Element
6+
7+
8+
class ShareApi:
9+
"""
10+
Sharing APIs.
11+
"""
12+
13+
def __init__(self):
14+
self.incoming = {}
15+
16+
@Interface.private_api()
17+
def share_object(
18+
self, receiver: str, objs: list[Element] = [], read_only: bool = True
19+
):
20+
"""
21+
Sharing an object with a user
22+
obj: The list of elements to share
23+
receiver: master of the receiving user
24+
read_only: if set true, the object shared will be shared as read-only
25+
"""
26+
# Get the master object by id
27+
receiver_mast = self._h.get_obj(
28+
caller_id=self.jid, item_id=receiver, override=True
29+
)
30+
31+
for obj in objs:
32+
# Grant read-only permission to the new user
33+
self.object_perms_grant(obj, receiver_mast, read_only=read_only)
34+
obj.save()
35+
36+
# Add the objet id to the receiver's incoming list
37+
receiver_mast.incoming[str(obj.id)] = {"jid": self.jid, "name": self.name}
38+
39+
receiver_mast.save()
40+
self.save()
41+
42+
return {
43+
"objects": [str(obj) for obj in objs],
44+
"sharer": str(self),
45+
"receiver": str(receiver_mast),
46+
}
47+
48+
@Interface.private_api()
49+
def share_incoming_pop(self, obj_id: str):
50+
"""
51+
Remove an item from the incoming list
52+
"""
53+
try:
54+
self.incoming.pop(obj_id)
55+
return True
56+
except Exception:
57+
return None
58+
59+
@Interface.private_api()
60+
def share_incoming_list(self):
61+
"""
62+
Get the incoming objects
63+
"""
64+
return self.incoming

jaseci_core/jaseci/extens/api/user_api.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,24 @@ def user_destroyer(self, name: str):
143143
Permanently delete master with given id
144144
"""
145145
pass
146+
147+
@Interface.private_api()
148+
def user_search(
149+
self,
150+
name: str,
151+
detailed: bool = False,
152+
create_if_not_exist: bool = False,
153+
create_fields: dict = {},
154+
):
155+
"""
156+
Search for user and returns its master jid.
157+
Create new one if the user doesn't already exist, optionally.
158+
create_fields will be forwarded to the user create endpoint, including
159+
password
160+
global_init
161+
global_init_ctx
162+
other_fields
163+
send_email
164+
See the user_create API for more details.
165+
"""
166+
pass

jaseci_core/jaseci/prim/master.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from jaseci.extens.api.user_api import UserApi
1818
from jaseci.extens.api.queue_api import QueueApi
1919
from jaseci.extens.api.webhook_api import WebhookApi
20+
from jaseci.extens.api.share_api import ShareApi
2021
from jaseci.extens.api.health_api import HealthApi
2122
from jaseci.jsorc.jsorc import JsOrc
2223

@@ -36,6 +37,7 @@ class Master(
3637
UserApi,
3738
QueueApi,
3839
WebhookApi,
40+
ShareApi,
3941
HealthApi,
4042
):
4143
"""Main class for master functions for user"""
@@ -51,6 +53,7 @@ def __init__(self, head_master=None, *args, **kwargs):
5153
GraphApi.__init__(self)
5254
WalkerApi.__init__(self)
5355
SentinelApi.__init__(self)
56+
ShareApi.__init__(self)
5457
Interface.__init__(self)
5558

5659
def destroy(self):

jaseci_serv/jaseci_serv/base/models.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
)
1010
from django.db import models
1111
from django.db.models import Q
12+
from django.core.exceptions import ObjectDoesNotExist
13+
1214

1315
from jaseci.extens.api.interface import Interface
1416
from jaseci.prim.master import Master as CoreMaster
@@ -98,6 +100,47 @@ def master_self(self, detailed: bool = False):
98100
}
99101
return info
100102

103+
@Interface.private_api()
104+
def user_search(
105+
self,
106+
name: str,
107+
detailed: bool = False,
108+
create_if_not_exist: bool = False,
109+
create_fields: dict = {},
110+
):
111+
"""
112+
Search for user and returns its master jid.
113+
Create new one if the user doesn't already exist, optionally.
114+
create_fields will be forwarded to the user create endpoint, including
115+
password
116+
global_init
117+
global_init_ctx
118+
other_fields
119+
send_email
120+
See the user_create API for more details.
121+
"""
122+
try:
123+
return (
124+
get_user_model()
125+
.objects.get(email=name)
126+
.get_master()
127+
.master_self(detailed=detailed)
128+
)
129+
except ObjectDoesNotExist:
130+
if create_if_not_exist:
131+
return self.user_create(
132+
name=name,
133+
password=create_fields.get("password", ""),
134+
global_init=create_fields.get("global_init", ""),
135+
global_init_ctx=create_fields.get("global_init_ctx", {}),
136+
other_fields=create_fields.get("other_fields", {}),
137+
send_email=create_fields.get("send_email", True),
138+
)
139+
else:
140+
return f"User {name} not found."
141+
except Exception as e:
142+
return {"error": str(e)}
143+
101144

102145
@JsOrc.context(name="super_master", priority=1)
103146
class SuperMaster(Master, JsOrcApi, CoreSuper):

jaseci_serv/jaseci_serv/hook/orm.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,10 @@ def map_assignment_of_matching_fields(dest, source):
204204
)
205205
except Exception:
206206
setattr(dest, i, IdList(parent_obj=dest))
207+
elif i.endswith("_ids") and type(getattr(source, i)) == IdList:
208+
try:
209+
setattr(dest, i, json.dumps(getattr(source, i)))
210+
except Exception:
211+
setattr(dest, i, "[]")
207212
elif not callable(getattr(dest, i)):
208213
setattr(dest, i, getattr(source, i))

0 commit comments

Comments
 (0)