Skip to content

Commit

Permalink
Sharing APIs (#1215)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ypkang committed Apr 23, 2024
1 parent a279ad4 commit c84e608
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 1 deletion.
2 changes: 1 addition & 1 deletion jaseci_core/jaseci/extens/api/master_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def master_list(self, detailed: bool = False):
def master_active_set(self, name: str):
"""
Sets the default master master should use
NOTE: Specail handler included in general_interface_to_api
NOTE: Special handler included in general_interface_to_api
"""
mas = self.sub_master_ids.get_obj_by_name(name)
if not mas:
Expand Down
64 changes: 64 additions & 0 deletions jaseci_core/jaseci/extens/api/share_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Object sharing APIs
"""
from jaseci.extens.api.interface import Interface
from jaseci.prim.element import Element


class ShareApi:
"""
Sharing APIs.
"""

def __init__(self):
self.incoming = {}

@Interface.private_api()
def share_object(
self, receiver: str, objs: list[Element] = [], read_only: bool = True
):
"""
Sharing an object with a user
obj: The list of elements to share
receiver: master of the receiving user
read_only: if set true, the object shared will be shared as read-only
"""
# Get the master object by id
receiver_mast = self._h.get_obj(
caller_id=self.jid, item_id=receiver, override=True
)

for obj in objs:
# Grant read-only permission to the new user
self.object_perms_grant(obj, receiver_mast, read_only=read_only)
obj.save()

# Add the objet id to the receiver's incoming list
receiver_mast.incoming[str(obj.id)] = {"jid": self.jid, "name": self.name}

receiver_mast.save()
self.save()

return {
"objects": [str(obj) for obj in objs],
"sharer": str(self),
"receiver": str(receiver_mast),
}

@Interface.private_api()
def share_incoming_pop(self, obj_id: str):
"""
Remove an item from the incoming list
"""
try:
self.incoming.pop(obj_id)
return True
except Exception:
return None

@Interface.private_api()
def share_incoming_list(self):
"""
Get the incoming objects
"""
return self.incoming
21 changes: 21 additions & 0 deletions jaseci_core/jaseci/extens/api/user_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,24 @@ def user_destroyer(self, name: str):
Permanently delete master with given id
"""
pass

@Interface.private_api()
def user_search(
self,
name: str,
detailed: bool = False,
create_if_not_exist: bool = False,
create_fields: dict = {},
):
"""
Search for user and returns its master jid.
Create new one if the user doesn't already exist, optionally.
create_fields will be forwarded to the user create endpoint, including
password
global_init
global_init_ctx
other_fields
send_email
See the user_create API for more details.
"""
pass
3 changes: 3 additions & 0 deletions jaseci_core/jaseci/prim/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from jaseci.extens.api.user_api import UserApi
from jaseci.extens.api.queue_api import QueueApi
from jaseci.extens.api.webhook_api import WebhookApi
from jaseci.extens.api.share_api import ShareApi
from jaseci.extens.api.health_api import HealthApi
from jaseci.jsorc.jsorc import JsOrc

Expand All @@ -36,6 +37,7 @@ class Master(
UserApi,
QueueApi,
WebhookApi,
ShareApi,
HealthApi,
):
"""Main class for master functions for user"""
Expand All @@ -51,6 +53,7 @@ def __init__(self, head_master=None, *args, **kwargs):
GraphApi.__init__(self)
WalkerApi.__init__(self)
SentinelApi.__init__(self)
ShareApi.__init__(self)
Interface.__init__(self)

def destroy(self):
Expand Down
43 changes: 43 additions & 0 deletions jaseci_serv/jaseci_serv/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
)
from django.db import models
from django.db.models import Q
from django.core.exceptions import ObjectDoesNotExist


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

@Interface.private_api()
def user_search(
self,
name: str,
detailed: bool = False,
create_if_not_exist: bool = False,
create_fields: dict = {},
):
"""
Search for user and returns its master jid.
Create new one if the user doesn't already exist, optionally.
create_fields will be forwarded to the user create endpoint, including
password
global_init
global_init_ctx
other_fields
send_email
See the user_create API for more details.
"""
try:
return (
get_user_model()
.objects.get(email=name)
.get_master()
.master_self(detailed=detailed)
)
except ObjectDoesNotExist:
if create_if_not_exist:
return self.user_create(
name=name,
password=create_fields.get("password", ""),
global_init=create_fields.get("global_init", ""),
global_init_ctx=create_fields.get("global_init_ctx", {}),
other_fields=create_fields.get("other_fields", {}),
send_email=create_fields.get("send_email", True),
)
else:
return f"User {name} not found."
except Exception as e:
return {"error": str(e)}


@JsOrc.context(name="super_master", priority=1)
class SuperMaster(Master, JsOrcApi, CoreSuper):
Expand Down
5 changes: 5 additions & 0 deletions jaseci_serv/jaseci_serv/hook/orm.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,5 +204,10 @@ def map_assignment_of_matching_fields(dest, source):
)
except Exception:
setattr(dest, i, IdList(parent_obj=dest))
elif i.endswith("_ids") and type(getattr(source, i)) == IdList:
try:
setattr(dest, i, json.dumps(getattr(source, i)))
except Exception:
setattr(dest, i, "[]")
elif not callable(getattr(dest, i)):
setattr(dest, i, getattr(source, i))

0 comments on commit c84e608

Please sign in to comment.