diff --git a/doc/api.oa3 b/doc/api.oa3 index 689e6670..ec508721 100644 --- a/doc/api.oa3 +++ b/doc/api.oa3 @@ -84,8 +84,13 @@ paths: - admin description: Get node configuration. Access granted to admin username and password. operationId: get-node-config - security: - - basicAuth: [] + parameters: + - name: token + in: query + description: token for admin access + required: true + schema: + type: string responses: '200': description: success @@ -102,8 +107,13 @@ paths: - admin description: Set node config. Access granted to admin username and password. operationId: set-node-config - security: - - basicAuth: [] + parameters: + - name: token + in: query + description: token for admin access + required: true + schema: + type: string responses: '200': description: success @@ -118,8 +128,13 @@ paths: - admin description: Get list of accounts hosted on node. Access granted to admin username and password. operationId: get-node-accounts - security: - - basicAuth: [] + parameters: + - name: token + in: query + description: token for admin access + required: true + schema: + type: string responses: '200': description: successful operation @@ -140,8 +155,13 @@ paths: - admin description: Gernerate a url for creating a new account. Access granted to admin username and password. operationId: add-node-account - security: - - basicAuth: [] + parameters: + - name: token + in: query + description: token for admin access + required: true + schema: + type: string responses: '201': description: success @@ -160,8 +180,6 @@ paths: - admin description: Get profile image of node account. operationId: get-node-account-image - security: - - basicAuth: [] parameters: - name: accountId in: path @@ -169,6 +187,12 @@ paths: required: true schema: type: string + - name: token + in: query + description: token for admin access + required: true + schema: + type: string responses: '200': description: successful operation @@ -199,6 +223,12 @@ paths: required: true schema: type: string + - name: token + in: query + description: token for admin access + required: true + schema: + type: string responses: '200': description: successful operation diff --git a/net/server/internal/api_addNodeAccount.go b/net/server/internal/api_addNodeAccount.go index d9f919e0..b9b942f4 100644 --- a/net/server/internal/api_addNodeAccount.go +++ b/net/server/internal/api_addNodeAccount.go @@ -10,8 +10,8 @@ import ( func AddNodeAccount(w http.ResponseWriter, r *http.Request) { - if err := AdminLogin(r); err != nil { - ErrResponse(w, http.StatusUnauthorized, err) + if code, err := ParamAdminToken(r); err != nil { + ErrResponse(w, code, err) return } diff --git a/net/server/internal/api_getNodeAccountImage.go b/net/server/internal/api_getNodeAccountImage.go index 2e954a7d..6696c542 100644 --- a/net/server/internal/api_getNodeAccountImage.go +++ b/net/server/internal/api_getNodeAccountImage.go @@ -22,8 +22,8 @@ func GetNodeAccountImage(w http.ResponseWriter, r *http.Request) { return } - if err := AdminLogin(r); err != nil { - ErrResponse(w, http.StatusUnauthorized, err) + if code, err := ParamAdminToken(r); err != nil { + ErrResponse(w, code, err) return } diff --git a/net/server/internal/api_getNodeAccounts.go b/net/server/internal/api_getNodeAccounts.go index c3962e2c..04cae725 100644 --- a/net/server/internal/api_getNodeAccounts.go +++ b/net/server/internal/api_getNodeAccounts.go @@ -7,8 +7,8 @@ import ( func GetNodeAccounts(w http.ResponseWriter, r *http.Request) { - if err := AdminLogin(r); err != nil { - ErrResponse(w, http.StatusUnauthorized, err) + if code, err := ParamAdminToken(r); err != nil { + ErrResponse(w, code, err) return } diff --git a/net/server/internal/api_getNodeConfig.go b/net/server/internal/api_getNodeConfig.go index 6463c069..c09b4d63 100644 --- a/net/server/internal/api_getNodeConfig.go +++ b/net/server/internal/api_getNodeConfig.go @@ -7,8 +7,8 @@ import ( func GetNodeConfig(w http.ResponseWriter, r *http.Request) { // validate login - if err := AdminLogin(r); err != nil { - ErrResponse(w, http.StatusUnauthorized, err) + if code, err := ParamAdminToken(r); err != nil { + ErrResponse(w, code, err) return } diff --git a/net/server/internal/api_removeNodeAccount.go b/net/server/internal/api_removeNodeAccount.go index caf0d6b2..2f024165 100644 --- a/net/server/internal/api_removeNodeAccount.go +++ b/net/server/internal/api_removeNodeAccount.go @@ -20,8 +20,8 @@ func RemoveNodeAccount(w http.ResponseWriter, r *http.Request) { return } - if err := AdminLogin(r); err != nil { - ErrResponse(w, http.StatusUnauthorized, err) + if code, err := ParamAdminToken(r); err != nil { + ErrResponse(w, code, err) return } diff --git a/net/server/internal/api_setNodeAccount.go b/net/server/internal/api_setNodeAccount.go index 866f75ba..75b9c414 100644 --- a/net/server/internal/api_setNodeAccount.go +++ b/net/server/internal/api_setNodeAccount.go @@ -20,8 +20,8 @@ func SetNodeAccount(w http.ResponseWriter, r *http.Request) { return } - if res = AdminLogin(r); res != nil { - ErrResponse(w, http.StatusUnauthorized, res) + if code, res := ParamAdminToken(r); res != nil { + ErrResponse(w, code, res) return } diff --git a/net/server/internal/api_setNodeConfig.go b/net/server/internal/api_setNodeConfig.go index 96bc8825..7e854aa1 100644 --- a/net/server/internal/api_setNodeConfig.go +++ b/net/server/internal/api_setNodeConfig.go @@ -10,8 +10,8 @@ import ( func SetNodeConfig(w http.ResponseWriter, r *http.Request) { // validate login - if err := AdminLogin(r); err != nil { - ErrResponse(w, http.StatusUnauthorized, err) + if code, err := ParamAdminToken(r); err != nil { + ErrResponse(w, code, err) return } diff --git a/net/server/internal/api_setNodeStatus.go b/net/server/internal/api_setNodeStatus.go index 2f01cf45..e99f8871 100644 --- a/net/server/internal/api_setNodeStatus.go +++ b/net/server/internal/api_setNodeStatus.go @@ -20,18 +20,14 @@ func SetNodeStatus(w http.ResponseWriter, r *http.Request) { return } - username, password, res := BasicCredentials(r); - if res != nil || username != "admin" { - LogMsg("invalid credenitals"); + token := r.FormValue("token") + if token == "" { w.WriteHeader(http.StatusBadRequest) return } err = store.DB.Transaction(func(tx *gorm.DB) error { - if res := tx.Create(&store.Config{ConfigId: CONFIG_USERNAME, StrValue: username}).Error; res != nil { - return res - } - if res := tx.Create(&store.Config{ConfigId: CONFIG_PASSWORD, BinValue: password}).Error; res != nil { + if res := tx.Create(&store.Config{ConfigId: CONFIG_TOKEN, StrValue: token}).Error; res != nil { return res } if res := tx.Create(&store.Config{ConfigId: CONFIG_CONFIGURED, BoolValue: true}).Error; res != nil { diff --git a/net/server/internal/authUtil.go b/net/server/internal/authUtil.go index f97fdc02..3b2a5d0d 100644 --- a/net/server/internal/authUtil.go +++ b/net/server/internal/authUtil.go @@ -11,33 +11,6 @@ import ( "databag/internal/store" ) -func AdminLogin(r *http.Request) error { - - // extract request auth - username, password, ok := r.BasicAuth() - if !ok || username == "" || password == "" { - return errors.New("invalid credentials") - } - - // nothing to do if not configured - if !getBoolConfigValue(CONFIG_CONFIGURED, false) { - return errors.New("node not configured") - } - - // compare username - if getStrConfigValue(CONFIG_USERNAME, "") != username { - return errors.New("admin username error") - } - - // compare password - p := getBinConfigValue(CONFIG_PASSWORD, nil); - if bcrypt.CompareHashAndPassword(p, []byte(password)) != nil { - return errors.New("admin password error") - } - - return nil -} - func AccountLogin(r *http.Request) (*store.Account, error) { // extract request auth @@ -77,6 +50,28 @@ func BearerAccountToken(r *http.Request) (*store.AccountToken, error) { return &accountToken, nil } +func ParamAdminToken(r *http.Request) (int, error) { + + // parse authentication token + token := r.FormValue("token") + if token == "" { + return http.StatusUnauthorized, errors.New("token not set"); + } + + // nothing to do if not configured + if !getBoolConfigValue(CONFIG_CONFIGURED, false) { + return http.StatusUnauthorized, errors.New("node not configured") + } + + // compare password + value := getStrConfigValue(CONFIG_TOKEN, ""); + if (value != token) { + return http.StatusUnauthorized, errors.New("invalid admin token") + } + + return http.StatusOK, nil; +} + func ParamAgentToken(r *http.Request, detail bool) (*store.Account, int, error) { // parse authentication token diff --git a/net/server/internal/configUtil.go b/net/server/internal/configUtil.go index 796fbcc5..6bb4dd8b 100644 --- a/net/server/internal/configUtil.go +++ b/net/server/internal/configUtil.go @@ -9,8 +9,7 @@ import ( const CONFIG_OPENACCESS = "open_access" const CONFIG_ACCOUNTLIMIT = "account_limit" const CONFIG_CONFIGURED = "configured" -const CONFIG_USERNAME = "username" -const CONFIG_PASSWORD = "password" +const CONFIG_TOKEN = "token" const CONFIG_DOMAIN = "domain" const CONFIG_STORAGE = "storage" const CONFIG_ASSETPATH = "asset_path" diff --git a/net/server/internal/main_test.go b/net/server/internal/main_test.go index 792a00d5..2fdf560a 100644 --- a/net/server/internal/main_test.go +++ b/net/server/internal/main_test.go @@ -34,8 +34,7 @@ func TestMain(m *testing.M) { } // claim server - r, w, _ = NewRequest("PUT", "/admin/status", nil) - SetCredentials(r, "admin:pass"); + r, w, _ = NewRequest("PUT", "/admin/status?token=pass", nil) SetNodeStatus(w, r) if ReadResponse(w, nil) != nil { panic("failed to claim server") @@ -55,16 +54,14 @@ func TestMain(m *testing.M) { // config server config := NodeConfig{Domain: "databag.coredb.org", AccountLimit: 1024, OpenAccess: true, AccountStorage: 4096} - r, w, _ = NewRequest("PUT", "/admin/config", &config) - SetBasicAuth(r, "admin:pass") + r, w, _ = NewRequest("PUT", "/admin/config?token=pass", &config) SetNodeConfig(w, r) if ReadResponse(w, nil) != nil { panic("failed to set config") } // check config - r, w, _ = NewRequest("GET", "/admin/config", nil) - SetBasicAuth(r, "admin:pass") + r, w, _ = NewRequest("GET", "/admin/config?token=pass", nil) GetNodeConfig(w, r) var check NodeConfig if ReadResponse(w, &check) != nil { diff --git a/net/server/internal/testUtil.go b/net/server/internal/testUtil.go index e6b04c25..2c746b78 100644 --- a/net/server/internal/testUtil.go +++ b/net/server/internal/testUtil.go @@ -620,10 +620,9 @@ func AddTestAccount(username string) (guid string, token string, err error) { var login = username + ":pass" // get account token - if r, w, err= NewRequest("POST", "/admin/accounts", nil); err != nil { + if r, w, err= NewRequest("POST", "/admin/accounts?token=pass", nil); err != nil { return } - SetBasicAuth(r, "admin:pass") AddNodeAccount(w, r) if err = ReadResponse(w, &access); err != nil { return diff --git a/net/web/src/Admin/Dashboard/AccountItem/AccountItem.jsx b/net/web/src/Admin/Dashboard/AccountItem/AccountItem.jsx new file mode 100644 index 00000000..84401c22 --- /dev/null +++ b/net/web/src/Admin/Dashboard/AccountItem/AccountItem.jsx @@ -0,0 +1,4 @@ +export function AccountItem() { + return