From 3a0409c00247b4bae10647ff677be51cb88b55d9 Mon Sep 17 00:00:00 2001 From: Roland Osborne Date: Wed, 9 Mar 2022 21:19:05 -0800 Subject: [PATCH] adding admin listing of accounts --- doc/api.oa3 | 48 +++++++++++++++-- net/server/internal/api_admin.go | 10 ---- .../internal/api_getNodeAccountImage.go | 54 +++++++++++++++++++ net/server/internal/api_getNodeAccounts.go | 37 +++++++++++++ net/server/internal/models.go | 18 ++++--- 5 files changed, 147 insertions(+), 20 deletions(-) create mode 100644 net/server/internal/api_getNodeAccountImage.go create mode 100644 net/server/internal/api_getNodeAccounts.go diff --git a/doc/api.oa3 b/doc/api.oa3 index 650a8911..d3672468 100644 --- a/doc/api.oa3 +++ b/doc/api.oa3 @@ -130,7 +130,7 @@ paths: schema: type: array items: - $ref: '#/components/schemas/Account' + $ref: '#/components/schemas/AccountProfile' '401': description: invalid password '404': @@ -156,6 +156,36 @@ paths: '500': description: internal server error + /admin/accounts/{accountId}/image: + get: + tags: + - admin + description: Get profile image of node account. + operationId: get-node-account-image + security: + - basicAuth: [] + parameters: + - name: accountId + in: path + description: id of account to delete + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/octet-stream: # content specific + schema: + type: string + format: binary + '401': + description: invalid authentication + '404': + description: account not found + '500': + description: internal server error + /admin/accounts/{accountId}/reset: put: tags: @@ -3006,13 +3036,23 @@ components: type: object required: - accountId - - profile - disabled properties: accountId: + type: integer + format: uint32 + guid: type: string - profile: - $ref: '#/components/schemas/Profile' + handle: + type: string + name: + type: string + description: + type: string + location: + type: string + imageSet: + type: boolean disabled: type: boolean diff --git a/net/server/internal/api_admin.go b/net/server/internal/api_admin.go index abf9f5b9..72ac8684 100644 --- a/net/server/internal/api_admin.go +++ b/net/server/internal/api_admin.go @@ -13,16 +13,6 @@ import ( "net/http" ) -func GetNodeAccountImage(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - -func GetNodeAccounts(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json; charset=UTF-8") - w.WriteHeader(http.StatusOK) -} - func ImportAccount(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusOK) diff --git a/net/server/internal/api_getNodeAccountImage.go b/net/server/internal/api_getNodeAccountImage.go new file mode 100644 index 00000000..2e954a7d --- /dev/null +++ b/net/server/internal/api_getNodeAccountImage.go @@ -0,0 +1,54 @@ +package databag + +import ( + "time" + "strconv" + "gorm.io/gorm" + "bytes" + "errors" + "encoding/base64" + "net/http" + "databag/internal/store" + "github.com/gorilla/mux" +) + +func GetNodeAccountImage(w http.ResponseWriter, r *http.Request) { + + // get referenced account id + params := mux.Vars(r) + accountId, res := strconv.ParseUint(params["accountId"], 10, 32) + if res != nil { + ErrResponse(w, http.StatusBadRequest, res) + return + } + + if err := AdminLogin(r); err != nil { + ErrResponse(w, http.StatusUnauthorized, err) + return + } + + var account store.Account + if err := store.DB.Preload("AccountDetail").First(&account, uint(accountId)).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + ErrResponse(w, http.StatusNotFound, err) + } else { + ErrResponse(w, http.StatusInternalServerError, err) + } + return + } + + if account.AccountDetail.Image == "" { + ErrResponse(w, http.StatusNotFound, errors.New("iamge not set")) + return + } + + data, err := base64.StdEncoding.DecodeString(account.AccountDetail.Image) + if err != nil { + ErrResponse(w, http.StatusNotFound, errors.New("image not valid")) + return + } + + // response with content + http.ServeContent(w, r, "image", time.Unix(account.Updated, 0), bytes.NewReader(data)) +} + diff --git a/net/server/internal/api_getNodeAccounts.go b/net/server/internal/api_getNodeAccounts.go new file mode 100644 index 00000000..c3962e2c --- /dev/null +++ b/net/server/internal/api_getNodeAccounts.go @@ -0,0 +1,37 @@ +package databag + +import ( + "net/http" + "databag/internal/store" +) + +func GetNodeAccounts(w http.ResponseWriter, r *http.Request) { + + if err := AdminLogin(r); err != nil { + ErrResponse(w, http.StatusUnauthorized, err) + return + } + + var accounts []store.Account + if err := store.DB.Preload("AccountDetail").Find(&accounts).Error; err != nil { + ErrResponse(w, http.StatusInternalServerError, err) + return + } + + profiles := []AccountProfile{} + for _, account := range accounts { + profiles = append(profiles, AccountProfile{ + AccountId: uint32(account.ID), + Guid: account.Guid, + Handle: account.Username, + Name: account.AccountDetail.Name, + Description: account.AccountDetail.Description, + Location: account.AccountDetail.Location, + ImageSet: account.AccountDetail.Image != "", + Disabled: account.Disabled, + }) + } + + WriteResponse(w, &profiles); +} + diff --git a/net/server/internal/models.go b/net/server/internal/models.go index 7d9de346..8387b640 100644 --- a/net/server/internal/models.go +++ b/net/server/internal/models.go @@ -1,14 +1,20 @@ package databag -import ( - //"os" -) +type AccountProfile struct { -type Account struct { + AccountId uint32 `json:"accountId"` - AccountId string `json:"accountId"` + Guid string `json:"guid"` - Profile *Profile `json:"profile"` + Handle string `json:"handle,omitempty"` + + Name string `json:"name,omitempty"` + + Description string `json:"description,omitempty"` + + Location string `json:"location,omitempty"` + + ImageSet bool `json:"imageSet,omitempty"` Disabled bool `json:"disabled"` }