Skip to content

Commit

Permalink
Refactored all HTTP logic (cleaned up debug logic, log body if smalle…
Browse files Browse the repository at this point in the history
…r than 4096 bytes)

Implemented support for Softaculous (for WordPress)
Implemented support for PHP version retrieval and modification
Implemented support for downloading files
Implemented support for creating, retrieving, and restoring backups
Implemented support for retrieving messages
  • Loading branch information
wolveix committed Jun 2, 2024
1 parent 9223656 commit e32cb25
Show file tree
Hide file tree
Showing 26 changed files with 806 additions and 278 deletions.
20 changes: 10 additions & 10 deletions admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ type convertAccount struct {
}

func (c *AdminContext) ConvertResellerToUser(username string, reseller string) error {
if _, err := c.api.makeRequestN(http.MethodPost, "convert-reseller-to-user", c.credentials, convertAccount{Account: username, Creator: reseller}, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "convert-reseller-to-user", convertAccount{Account: username, Creator: reseller}, nil); err != nil {
return err
}

return nil
}

func (c *AdminContext) ConvertUserToReseller(username string) error {
if _, err := c.api.makeRequestN(http.MethodPost, "convert-user-to-reseller", c.credentials, convertAccount{Account: username}, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "convert-user-to-reseller", convertAccount{Account: username}, nil); err != nil {
return err
}

Expand All @@ -35,7 +35,7 @@ func (c *AdminContext) ConvertUserToReseller(username string) error {
func (c *AdminContext) DisableRedis() error {
var response apiGenericResponseN

if _, err := c.api.makeRequestN(http.MethodPost, "redis/disable", c.credentials, nil, &response); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "redis/disable", nil, &response); err != nil {
return err
}

Expand All @@ -45,7 +45,7 @@ func (c *AdminContext) DisableRedis() error {
func (c *AdminContext) EnableRedis() error {
var response apiGenericResponseN

if _, err := c.api.makeRequestN(http.MethodPost, "redis/enable", c.credentials, nil, &response); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "redis/enable", nil, &response); err != nil {
return err
}

Expand All @@ -56,7 +56,7 @@ func (c *AdminContext) EnableRedis() error {
func (c *AdminContext) GetAllUsers() ([]string, error) {
var users []string

if _, err := c.api.makeRequest(http.MethodGet, "API_SHOW_ALL_USERS", c.credentials, nil, &users); err != nil {
if _, err := c.makeRequestOld(http.MethodGet, "API_SHOW_ALL_USERS", nil, &users); err != nil {
return nil, err
}

Expand All @@ -67,7 +67,7 @@ func (c *AdminContext) GetAllUsers() ([]string, error) {
func (c *AdminContext) GetResellers() ([]string, error) {
var users []string

if _, err := c.api.makeRequest(http.MethodGet, "API_SHOW_RESELLERS", c.credentials, nil, &users); err != nil {
if _, err := c.makeRequestOld(http.MethodGet, "API_SHOW_RESELLERS", nil, &users); err != nil {
return nil, err
}

Expand All @@ -78,15 +78,15 @@ func (c *AdminContext) GetResellers() ([]string, error) {
func (c *AdminContext) GetResellersWithUsage() ([]string, error) {
var users []string

if _, err := c.api.makeRequest(http.MethodGet, "RESELLER_SHOW", c.credentials, nil, &users); err != nil {
if _, err := c.makeRequestOld(http.MethodGet, "RESELLER_SHOW", nil, &users); err != nil {
return nil, err
}

return users, nil
}

func (c *AdminContext) MoveUserToReseller(username string, reseller string) error {
if _, err := c.api.makeRequestN(http.MethodPost, "change-user-creator", c.credentials, convertAccount{Account: username, Creator: reseller}, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "change-user-creator", convertAccount{Account: username, Creator: reseller}, nil); err != nil {
return err
}

Expand All @@ -96,7 +96,7 @@ func (c *AdminContext) MoveUserToReseller(username string, reseller string) erro
func (c *AdminContext) RestartDirectAdmin() error {
var response apiGenericResponseN

if _, err := c.api.makeRequestN(http.MethodPost, "restart", c.credentials, nil, &response); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "restart", nil, &response); err != nil {
return err
}

Expand All @@ -106,7 +106,7 @@ func (c *AdminContext) RestartDirectAdmin() error {
func (c *AdminContext) UpdateDirectAdmin() error {
var response apiGenericResponseN

if _, err := c.api.makeRequestN(http.MethodPost, "version/update", c.credentials, nil, &response); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "version/update", nil, &response); err != nil {
return err
}

Expand Down
10 changes: 5 additions & 5 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (c *UserContext) CreateLoginURL(loginKeyURL *LoginKeyURL) error {
return errors.New("failed to create login key URL: loginKeyURL is nil")
}

if _, err := c.api.makeRequestN(http.MethodPost, "login-keys/urls", c.credentials, loginKeyURL, loginKeyURL); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "login-keys/urls", loginKeyURL, loginKeyURL); err != nil {
return fmt.Errorf("failed to create login URL: %w", err)
}

Expand All @@ -46,7 +46,7 @@ func (c *UserContext) CreateLoginURL(loginKeyURL *LoginKeyURL) error {
func (c *UserContext) GetLoginURLs() ([]*LoginKeyURL, error) {
var loginKeyURLs []*LoginKeyURL

if _, err := c.api.makeRequestN(http.MethodGet, "login-keys/urls", c.credentials, nil, &loginKeyURLs); err != nil {
if _, err := c.makeRequestNew(http.MethodGet, "login-keys/urls", nil, &loginKeyURLs); err != nil {
return nil, fmt.Errorf("failed to get login URLs: %w", err)
}

Expand All @@ -56,7 +56,7 @@ func (c *UserContext) GetLoginURLs() ([]*LoginKeyURL, error) {
func (c *AdminContext) GetLoginHistory() ([]*LoginHistory, error) {
var loginHistory []*LoginHistory

if _, err := c.api.makeRequestN(http.MethodGet, "login-history", c.credentials, nil, &loginHistory); err != nil {
if _, err := c.makeRequestNew(http.MethodGet, "login-history", nil, &loginHistory); err != nil {
return nil, fmt.Errorf("failed to get login history: %w", err)
}

Expand All @@ -81,12 +81,12 @@ func (c *UserContext) GetMyUsername() string {
func (c *UserContext) Login() error {
var response apiGenericResponse

if _, err := c.api.makeRequest(http.MethodGet, "API_LOGIN_TEST", c.credentials, nil, &response); err != nil {
if _, err := c.makeRequestOld(http.MethodGet, "API_LOGIN_TEST", nil, &response); err != nil {
return err
}

if response.Success != "Login OK" {
return errors.New("login failed")
return fmt.Errorf("login failed: %v", response)
}

return nil
Expand Down
110 changes: 110 additions & 0 deletions backup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package directadmin

import (
"fmt"
"net/http"
"net/url"
)

// CreateBackup (user) creates an account backup for the given domain, and the given items
func (c *UserContext) CreateBackup(domain string, backupItems ...string) error {
var response apiGenericResponse

body := url.Values{}
body.Set("action", "backup")
body.Set("domain", domain)
body.Set("form_version", "4")

for index, backupItem := range backupItems {
body.Set(fmt.Sprintf("select%d", index), backupItem)
}

if _, err := c.makeRequestOld(http.MethodPost, "SITE_BACKUP", body, &response); err != nil {
return err
}

if response.Success != "Backup creation added to queue" {
return fmt.Errorf("failed to create backup: %v", response.Result)
}

return nil
}

// CreateBackupAllItems (user) wraps around CreateBackup and provides all available backup items
func (c *UserContext) CreateBackupAllItems(domain string) error {
return c.CreateBackup(
domain,
"domain",
"subdomain",
"email",
"email_data",
"emailsettings",
"forwarder",
"autoresponder",
"vacation",
"list",
"ftp",
"ftpsettings",
"database",
"database_data",
"trash",
)
}

// GetBackups (user) returns an array of the session user's backups for the given domain
func (c *UserContext) GetBackups(domain string) ([]string, error) {
var backups []string

if _, err := c.makeRequestOld(http.MethodGet, "SITE_BACKUP?domain="+domain+"&ipp=50", nil, &backups); err != nil {
return nil, err
}

return backups, nil
}

// RestoreBackup (user) restores an account backup for the given domain, and the given items
func (c *UserContext) RestoreBackup(domain string, backupFilename string, backupItems ...string) error {
var response apiGenericResponse

body := url.Values{}
body.Set("action", "restore")
body.Set("domain", domain)
body.Set("file", backupFilename)
body.Set("form_version", "3")

for index, backupItem := range backupItems {
body.Set(fmt.Sprintf("select%d", index), backupItem)
}

if _, err := c.makeRequestOld(http.MethodPost, "SITE_BACKUP", body, &response); err != nil {
return err
}

if response.Success != "Restore will run in the background" {
return fmt.Errorf("failed to restore backup: %v", response.Result)
}

return nil
}

// RestoreBackupAllItems (user) wraps around RestoreBackup and provides all available backup items
func (c *UserContext) RestoreBackupAllItems(domain string, backupFilename string) error {
return c.RestoreBackup(
domain,
backupFilename,
"domain",
"subdomain",
"email",
"email_data",
"emailsettings",
"forwarder",
"autoresponder",
"vacation",
"list",
"ftp",
"ftpsettings",
"database",
"database_data",
"trash",
)
}
49 changes: 35 additions & 14 deletions database.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package directadmin

import (
"bytes"
"fmt"
"mime/multipart"
"net/http"
"os"
"strconv"
Expand Down Expand Up @@ -57,7 +59,7 @@ type (
func (c *UserContext) CreateDatabase(database *Database) error {
database.Name = c.addUsernamePrefix(database.Name)

if _, err := c.api.makeRequestN(http.MethodPost, "db-manage/create-db", c.credentials, database, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "db-manage/create-db", database, nil); err != nil {
return err
}

Expand All @@ -68,7 +70,7 @@ func (c *UserContext) CreateDatabaseWithUser(database *DatabaseWithUser) error {
database.Name = c.addUsernamePrefix(database.Name)
database.User = c.addUsernamePrefix(database.User)

if _, err := c.api.makeRequestN(http.MethodPost, "db-manage/create-db-with-user", c.credentials, database, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "db-manage/create-db-with-user", database, nil); err != nil {
return err
}

Expand All @@ -78,7 +80,7 @@ func (c *UserContext) CreateDatabaseWithUser(database *DatabaseWithUser) error {
func (c *UserContext) CreateDatabaseUser(databaseUser *DatabaseUser) error {
databaseUser.User = c.addUsernamePrefix(databaseUser.User)

if _, err := c.api.makeRequestN(http.MethodPost, "db-manage/create-user", c.credentials, databaseUser, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "db-manage/create-user", databaseUser, nil); err != nil {
return err
}

Expand All @@ -88,16 +90,14 @@ func (c *UserContext) CreateDatabaseUser(databaseUser *DatabaseUser) error {
func (c *UserContext) DeleteDatabase(databaseName string) error {
databaseName = c.addUsernamePrefix(databaseName)

if _, err := c.api.makeRequestN(http.MethodDelete, "db-manage/databases/"+databaseName, c.credentials, nil, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodDelete, "db-manage/databases/"+databaseName, nil, nil); err != nil {
return err
}

return nil
}

func (c *UserContext) DownloadDatabase(name string, format DatabaseFormat, filePath string) error {
var response apiGenericResponse

name = name + "." + string(format)

if !strings.Contains(name, c.GetMyUsername()+"_") {
Expand All @@ -119,18 +119,23 @@ func (c *UserContext) DownloadDatabase(name string, format DatabaseFormat, fileP
}
}

if _, err := c.api.makeRequest(http.MethodPost, "DB/"+name, c.credentials, nil, &response, file); err != nil {
resp, err := c.makeRequestOld(http.MethodPost, "DB/"+name, nil, nil)
if err != nil {
return fmt.Errorf("failed to download database: %v", err)
}

if _, err = file.Write(resp); err != nil {
return fmt.Errorf("error writing to file: %w", err)
}

return nil
}

// ExportDatabase (user) returns an export of the given database
func (c *UserContext) ExportDatabase(databaseName string, gzip bool) ([]byte, error) {
databaseName = c.addUsernamePrefix(databaseName)

export, err := c.api.makeRequestN(http.MethodGet, "db-manage/databases/"+databaseName+"/export?gzip="+strconv.FormatBool(gzip), c.credentials, nil, nil)
export, err := c.makeRequestNew(http.MethodGet, "db-manage/databases/"+databaseName+"/export?gzip="+strconv.FormatBool(gzip), nil, nil)
if err != nil {
return nil, err
}
Expand All @@ -144,7 +149,7 @@ func (c *UserContext) GetDatabase(databaseName string) (*Database, error) {

var database Database

if _, err := c.api.makeRequestN(http.MethodGet, "db-show/databases/"+databaseName, c.credentials, nil, &database); err != nil {
if _, err := c.makeRequestNew(http.MethodGet, "db-show/databases/"+databaseName, nil, &database); err != nil {
return nil, err
}

Expand All @@ -155,7 +160,7 @@ func (c *UserContext) GetDatabase(databaseName string) (*Database, error) {
func (c *UserContext) GetDatabases() ([]*Database, error) {
var databases []*Database

if _, err := c.api.makeRequestN(http.MethodGet, "db-show/databases", c.credentials, nil, &databases); err != nil {
if _, err := c.makeRequestNew(http.MethodGet, "db-show/databases", nil, &databases); err != nil {
return nil, err
}

Expand All @@ -166,7 +171,7 @@ func (c *UserContext) GetDatabases() ([]*Database, error) {
func (c *UserContext) GetDatabaseProcesses() ([]*DatabaseProcess, error) {
var databaseProcesses []*DatabaseProcess

if _, err := c.api.makeRequestN(http.MethodGet, "db-monitor/processes", c.credentials, nil, &databaseProcesses); err != nil {
if _, err := c.makeRequestNew(http.MethodGet, "db-monitor/processes", nil, &databaseProcesses); err != nil {
return nil, err
}

Expand All @@ -177,7 +182,23 @@ func (c *UserContext) GetDatabaseProcesses() ([]*DatabaseProcess, error) {
func (c *UserContext) ImportDatabase(databaseName string, emptyExistingDatabase bool, sql []byte) error {
databaseName = c.addUsernamePrefix(databaseName)

if _, err := c.api.makeRequestN(http.MethodPost, "db-manage/databases/"+databaseName+"/import?clean="+strconv.FormatBool(emptyExistingDatabase), c.credentials, sql, nil, true); err != nil {
var byteBuffer bytes.Buffer
multipartWriter := multipart.NewWriter(&byteBuffer)

formFile, err := multipartWriter.CreateFormFile("sqlfile", "filename")
if err != nil {
return fmt.Errorf("failed to create form file: %w", err)
}

if _, err = formFile.Write(sql); err != nil {
return fmt.Errorf("failed to write to form file: %w", err)
}

if err = multipartWriter.Close(); err != nil {
return fmt.Errorf("failed to close multipart writer: %w", err)
}

if _, err = c.uploadFile(http.MethodPost, "/api/db-manage/databases/"+databaseName+"/import?clean="+strconv.FormatBool(emptyExistingDatabase), byteBuffer.Bytes(), nil, multipartWriter.FormDataContentType()); err != nil {
return err
}

Expand All @@ -188,7 +209,7 @@ func (c *UserContext) ImportDatabase(databaseName string, emptyExistingDatabase
func (c *UserContext) UpdateDatabaseUserHosts(username string, hosts []string) error {
username = c.addUsernamePrefix(username)

if _, err := c.api.makeRequestN(http.MethodPost, "db-manage/users/"+username+"/change-hosts", c.credentials, hosts, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "db-manage/users/"+username+"/change-hosts", hosts, nil); err != nil {
return err
}

Expand All @@ -205,7 +226,7 @@ func (c *UserContext) UpdateDatabaseUserPassword(username string, password strin
password,
}

if _, err := c.api.makeRequestN(http.MethodPost, "db-manage/users/"+username+"/change-password", c.credentials, newPassword, nil); err != nil {
if _, err := c.makeRequestNew(http.MethodPost, "db-manage/users/"+username+"/change-password", newPassword, nil); err != nil {
return err
}

Expand Down
Loading

0 comments on commit e32cb25

Please sign in to comment.