From ddf149dd04597391bc5ee678bd146d106383f376 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 16 Mar 2024 12:42:35 +0100 Subject: [PATCH] Implement the account API --- README.md | 2 +- account/account.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 account/account.go diff --git a/README.md b/README.md index 7f18e8c..e8c899b 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ func main() { The lsit below contains all of the portal APIs available as of 2024-03-14. Checked boxes are partially or completely implemented within this project. -- [ ] Account +- [x] Account - [ ] Background - [ ] Camera - [ ] Clipboard diff --git a/account/account.go b/account/account.go new file mode 100644 index 0000000..a5d975d --- /dev/null +++ b/account/account.go @@ -0,0 +1,78 @@ +// Package account lets sandboxed applications query basic information about the user, like their name and avatar photo. +package account + +import ( + "github.com/godbus/dbus/v5" + "github.com/rymdport/portal" + "github.com/rymdport/portal/internal/apis" + "github.com/rymdport/portal/internal/convert" +) + +const ( + accountBaseName = apis.CallBaseName + ".Account" + getUserInfoCallName = accountBaseName + ".GetUserInformation" +) + +// UserInfoOptions holds optional settings for getting user information. +type UserInfoOptions struct { + HandleToken string // A string that will be used as the last element of the handle. Must be a valid object path element. + Reason string // A string that can be shown in the dialog to explain why the information is needed. +} + +// UserInfoResult holds the results that are returned when getting user information. +type UserInfoResult struct { + Id string + Name string + Image string +} + +// GetUserInformation gets information about the current user. +// Both return values will be nil if the user cancelled the request. +func GetUserInformation(parentWindow string, options *UserInfoOptions) (*UserInfoResult, error) { + conn, err := dbus.SessionBus() // Shared connection, don't close. + if err != nil { + return nil, err + } + + data := map[string]dbus.Variant{} + + if options != nil { + if options.HandleToken != "" { + data["handle_token"] = convert.FromString(options.HandleToken) + } + + if options.Reason != "" { + data["reason"] = convert.FromString(options.Reason) + } + } + + obj := conn.Object(apis.ObjectName, apis.ObjectPath) + call := obj.Call(getUserInfoCallName, 0, parentWindow, data) + if call.Err != nil { + return nil, err + } + + result, err := apis.ReadResponse(conn, call) + if err != nil { + return nil, err + } else if result == nil { + return nil, nil // Cancelled by user. + } + + id, ok := result["id"].Value().(string) + if !ok { + return nil, portal.ErrUnexpectedResponse + } + + name, ok := result["name"].Value().(string) + if !ok { + return nil, portal.ErrUnexpectedResponse + } + + image, ok := result["image"].Value().(string) + if !ok { + return nil, portal.ErrUnexpectedResponse + } + + return &UserInfoResult{Id: id, Name: name, Image: image}, nil +}