Extract AppAPI auth and OCS preferences from CheckDNS.
Publish gonexapp v1 with Credentials, OCSClient, and parameterized AppAPIPreferences so ExApps share Nextcloud ExApp plumbing per ADR 0013. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package gonexapp
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AppAPIPreferences reads and writes one string ExApp preference for the requesting user.
|
||||
type AppAPIPreferences struct {
|
||||
Cred Credentials
|
||||
AppID string
|
||||
Key string
|
||||
Client *http.Client
|
||||
OCS OCSClient
|
||||
}
|
||||
|
||||
// NewAppAPIPreferences returns a preference store for appID and key using cred for auth.
|
||||
func NewAppAPIPreferences(cred Credentials, appID, key string) AppAPIPreferences {
|
||||
return AppAPIPreferences{
|
||||
Cred: cred,
|
||||
AppID: appID,
|
||||
Key: key,
|
||||
OCS: OCSClient{Cred: cred},
|
||||
}
|
||||
}
|
||||
|
||||
func (p AppAPIPreferences) ocsClient() OCSClient {
|
||||
c := p.OCS
|
||||
if c.Cred.BaseURL == "" {
|
||||
c.Cred = p.Cred
|
||||
}
|
||||
if c.Client == nil {
|
||||
c.Client = p.Client
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// Get loads the configured preference key for the requesting user.
|
||||
func (p AppAPIPreferences) Get() (string, error) {
|
||||
ocs := p.ocsClient()
|
||||
body, _ := json.Marshal(map[string]any{"configKeys": []string{p.Key}})
|
||||
raw, err := ocs.Call(http.MethodPost, "apps/app_api/api/v1/ex-app/preference/get-values", body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return decodePreferenceValue(raw, p.Key)
|
||||
}
|
||||
|
||||
// Set stores value for the configured preference key.
|
||||
func (p AppAPIPreferences) Set(value string) error {
|
||||
ocs := p.ocsClient()
|
||||
body, _ := json.Marshal(map[string]any{
|
||||
"configKey": p.Key,
|
||||
"configValue": value,
|
||||
"sensitive": 0,
|
||||
})
|
||||
_, err := ocs.Call(http.MethodPost, "apps/app_api/api/v1/ex-app/preference", body)
|
||||
return err
|
||||
}
|
||||
|
||||
func decodePreferenceValue(raw []byte, key string) (string, error) {
|
||||
var parsed struct {
|
||||
OCS struct {
|
||||
Data []struct {
|
||||
ConfigKey string `json:"configkey"`
|
||||
ConfigValue string `json:"configvalue"`
|
||||
} `json:"data"`
|
||||
} `json:"ocs"`
|
||||
}
|
||||
if err := json.Unmarshal(raw, &parsed); err != nil {
|
||||
var items []struct {
|
||||
ConfigKey string `json:"configkey"`
|
||||
ConfigValue string `json:"configvalue"`
|
||||
}
|
||||
if err2 := json.Unmarshal(raw, &items); err2 != nil {
|
||||
return "", fmt.Errorf("preferences decode: %w", err)
|
||||
}
|
||||
for _, it := range items {
|
||||
if it.ConfigKey == key {
|
||||
return strings.TrimSpace(it.ConfigValue), nil
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
for _, it := range parsed.OCS.Data {
|
||||
if it.ConfigKey == key {
|
||||
return strings.TrimSpace(it.ConfigValue), nil
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
Reference in New Issue
Block a user