From cfd8fe21c801e96bd2513dddb55fd84e87d75d48 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 4 Apr 2022 09:39:58 -0700 Subject: [PATCH] add get[Profile|Conversation]Attribute api --- README.md | 9 ++++++++ go.mod | 2 +- go.sum | 4 ++-- lib.go | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 73 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8cbd741..42a6968 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,11 @@ Other version combinations untested and some definitely do not work. # Using +## General Environment Variables + +- `LOG_FILE` if defined will mean all go logging will go to a file instead of stdout +- `LOG_LEVEL` if set to `debug` will cause debug logging to be included in log output + ## Linux Desktop: - `LD_LIBRARY_PATH` set to point to `libCwtch.so` @@ -33,3 +38,7 @@ Other version combinations untested and some definitely do not work. ## Windows - copy libCwtch.dll into the directory of the `.exe` using it + +## MacOS + +- copy libCwtch.dylib into the directory you are executing from diff --git a/go.mod b/go.mod index 31f5439..14714d0 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.openprivacy.ca/cwtch.im/libcwtch-go go 1.15 require ( - cwtch.im/cwtch v0.16.3 + cwtch.im/cwtch v0.16.4 git.openprivacy.ca/cwtch.im/server v1.4.2 git.openprivacy.ca/openprivacy/connectivity v1.8.1 git.openprivacy.ca/openprivacy/log v1.0.3 diff --git a/go.sum b/go.sum index eceb7f7..ff831eb 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,8 @@ cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqCl cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cwtch.im/cwtch v0.14.9/go.mod h1:/fLuoYLY/7JHw6RojFojpd245CiOcU24QpWqzh9FRDI= -cwtch.im/cwtch v0.16.3 h1:8R1Cq8xeY3h+x0ZA4eqOgVfazfsJPwBNN/JP6lSAg60= -cwtch.im/cwtch v0.16.3/go.mod h1:lG9e5RUib+SbX2XsjWtHKJWz9geoIglSAq55LrCm8Io= +cwtch.im/cwtch v0.16.4 h1:ytzmQXPdllQdMf9qX5fEq38+eAL4MzsUTcmu6tPZt7c= +cwtch.im/cwtch v0.16.4/go.mod h1:lG9e5RUib+SbX2XsjWtHKJWz9geoIglSAq55LrCm8Io= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= diff --git a/lib.go b/lib.go index 518055f..e84f8ec 100644 --- a/lib.go +++ b/lib.go @@ -1018,7 +1018,7 @@ func SetProfileAttribute(profileOnion string, key string, value string) { if profile != nil { zone, key := attr.ParseZone(key) - // TODO We only allow public.profile.zone to be set for now. + // TODO We only allow public.profile.key to be set for now. // All other scopes and zones need to be added explicitly or handled by Cwtch. if zone == attr.ProfileZone && key == constants.Name { profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, value) @@ -1028,6 +1028,39 @@ func SetProfileAttribute(profileOnion string, key string, value string) { } } +// Attribute is a struct to return the dual values of an attempt at a Get*Attribute API call, meant to be json searlialized +type Attribute struct { + Exists bool + Value string +} + +//export c_GetProfileAttribute +func c_GetProfileAttribute(profile_ptr *C.char, profile_len C.int, key_ptr *C.char, key_len C.int) *C.char { + profileOnion := C.GoStringN(profile_ptr, profile_len) + key := C.GoStringN(key_ptr, key_len) + return C.CString(GetProfileAttribute(profileOnion, key)) +} + +// GetProfileAttribute provides a wrapper around profile.GetScopedZonedAttribute +// Key must have the format zone.key where Zone is defined in Cwtch. Unknown zones are not permitted. +// Currently forcing the Public Scope +// Returns json of Attribute +func GetProfileAttribute(profileOnion string, key string) string { + profile := application.GetPeer(profileOnion) + if profile != nil { + zone, key := attr.ParseZone(key) + + res, exists := profile.GetScopedZonedAttribute(attr.PublicScope, zone, key) + attr := Attribute{exists, res} + json, _ := json.Marshal(attr) + return string(json) + + } + empty := Attribute{false, ""} + json, _ := json.Marshal(empty) + return (string(json)) +} + //export c_SetConversationAttribute func c_SetConversationAttribute(profile_ptr *C.char, profile_len C.int, conversation_id C.int, key_ptr *C.char, key_len C.int, val_ptr *C.char, val_len C.int) { profileOnion := C.GoStringN(profile_ptr, profile_len) @@ -1037,12 +1070,39 @@ func c_SetConversationAttribute(profile_ptr *C.char, profile_len C.int, conversa } // SetConversationAttribute provides a wrapper around profile.SetProfileAttribute +// key is of format Zone.Key, and the API forces the Local Scope func SetConversationAttribute(profileOnion string, conversationID int, key string, value string) { profile := application.GetPeer(profileOnion) zone, key := attr.ParseZone(key) profile.SetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(zone.ConstructZonedPath(key)), value) } +//export c_GetConversationAttribute +func c_GetConversationAttribute(profile_ptr *C.char, profile_len C.int, conversation_id C.int, key_ptr *C.char, key_len C.int) *C.char { + profileOnion := C.GoStringN(profile_ptr, profile_len) + key := C.GoStringN(key_ptr, key_len) + return C.CString(GetConversationAttribute(profileOnion, int(conversation_id), key)) +} + +// GetGonversationAttribute provides a wrapper around profile.GetGonversationAttribute +// key is of format Scope.Zone.Key +// Returns json of an Attribute +func GetConversationAttribute(profileOnion string, conversationID int, key string) string { + profile := application.GetPeer(profileOnion) + if profile != nil { + scope, zonekey := attr.ParseScope(key) + zone, key := attr.ParseZone(zonekey) + + res, err := profile.GetConversationAttribute(conversationID, scope.ConstructScopedZonedPath(zone.ConstructZonedPath(key))) + attr := Attribute{err == nil, res} + json, _ := json.Marshal(attr) + return string(json) + } + empty := Attribute{false, ""} + json, _ := json.Marshal(empty) + return (string(json)) +} + //export c_SetMessageAttribute func c_SetMessageAttribute(profile_ptr *C.char, profile_len C.int, conversation_id C.int, channel_id C.int, message_id C.int, key_ptr *C.char, key_len C.int, val_ptr *C.char, val_len C.int) { profileOnion := C.GoStringN(profile_ptr, profile_len)