Skip to content

Commit e32cb25

Browse files
committed
Refactored all HTTP logic (cleaned up debug logic, log body if smaller 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
1 parent 9223656 commit e32cb25

26 files changed

+806
-278
lines changed

Diff for: admin.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ type convertAccount struct {
1717
}
1818

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

2424
return nil
2525
}
2626

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

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

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

@@ -45,7 +45,7 @@ func (c *AdminContext) DisableRedis() error {
4545
func (c *AdminContext) EnableRedis() error {
4646
var response apiGenericResponseN
4747

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

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

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

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

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

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

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

8585
return users, nil
8686
}
8787

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

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

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

@@ -106,7 +106,7 @@ func (c *AdminContext) RestartDirectAdmin() error {
106106
func (c *AdminContext) UpdateDirectAdmin() error {
107107
var response apiGenericResponseN
108108

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

Diff for: auth.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func (c *UserContext) CreateLoginURL(loginKeyURL *LoginKeyURL) error {
3636
return errors.New("failed to create login key URL: loginKeyURL is nil")
3737
}
3838

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

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

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

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

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

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

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

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

9292
return nil

Diff for: backup.go

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package directadmin
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"net/url"
7+
)
8+
9+
// CreateBackup (user) creates an account backup for the given domain, and the given items
10+
func (c *UserContext) CreateBackup(domain string, backupItems ...string) error {
11+
var response apiGenericResponse
12+
13+
body := url.Values{}
14+
body.Set("action", "backup")
15+
body.Set("domain", domain)
16+
body.Set("form_version", "4")
17+
18+
for index, backupItem := range backupItems {
19+
body.Set(fmt.Sprintf("select%d", index), backupItem)
20+
}
21+
22+
if _, err := c.makeRequestOld(http.MethodPost, "SITE_BACKUP", body, &response); err != nil {
23+
return err
24+
}
25+
26+
if response.Success != "Backup creation added to queue" {
27+
return fmt.Errorf("failed to create backup: %v", response.Result)
28+
}
29+
30+
return nil
31+
}
32+
33+
// CreateBackupAllItems (user) wraps around CreateBackup and provides all available backup items
34+
func (c *UserContext) CreateBackupAllItems(domain string) error {
35+
return c.CreateBackup(
36+
domain,
37+
"domain",
38+
"subdomain",
39+
"email",
40+
"email_data",
41+
"emailsettings",
42+
"forwarder",
43+
"autoresponder",
44+
"vacation",
45+
"list",
46+
"ftp",
47+
"ftpsettings",
48+
"database",
49+
"database_data",
50+
"trash",
51+
)
52+
}
53+
54+
// GetBackups (user) returns an array of the session user's backups for the given domain
55+
func (c *UserContext) GetBackups(domain string) ([]string, error) {
56+
var backups []string
57+
58+
if _, err := c.makeRequestOld(http.MethodGet, "SITE_BACKUP?domain="+domain+"&ipp=50", nil, &backups); err != nil {
59+
return nil, err
60+
}
61+
62+
return backups, nil
63+
}
64+
65+
// RestoreBackup (user) restores an account backup for the given domain, and the given items
66+
func (c *UserContext) RestoreBackup(domain string, backupFilename string, backupItems ...string) error {
67+
var response apiGenericResponse
68+
69+
body := url.Values{}
70+
body.Set("action", "restore")
71+
body.Set("domain", domain)
72+
body.Set("file", backupFilename)
73+
body.Set("form_version", "3")
74+
75+
for index, backupItem := range backupItems {
76+
body.Set(fmt.Sprintf("select%d", index), backupItem)
77+
}
78+
79+
if _, err := c.makeRequestOld(http.MethodPost, "SITE_BACKUP", body, &response); err != nil {
80+
return err
81+
}
82+
83+
if response.Success != "Restore will run in the background" {
84+
return fmt.Errorf("failed to restore backup: %v", response.Result)
85+
}
86+
87+
return nil
88+
}
89+
90+
// RestoreBackupAllItems (user) wraps around RestoreBackup and provides all available backup items
91+
func (c *UserContext) RestoreBackupAllItems(domain string, backupFilename string) error {
92+
return c.RestoreBackup(
93+
domain,
94+
backupFilename,
95+
"domain",
96+
"subdomain",
97+
"email",
98+
"email_data",
99+
"emailsettings",
100+
"forwarder",
101+
"autoresponder",
102+
"vacation",
103+
"list",
104+
"ftp",
105+
"ftpsettings",
106+
"database",
107+
"database_data",
108+
"trash",
109+
)
110+
}

Diff for: database.go

+35-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package directadmin
22

33
import (
4+
"bytes"
45
"fmt"
6+
"mime/multipart"
57
"net/http"
68
"os"
79
"strconv"
@@ -57,7 +59,7 @@ type (
5759
func (c *UserContext) CreateDatabase(database *Database) error {
5860
database.Name = c.addUsernamePrefix(database.Name)
5961

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

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

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

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

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

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

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

9597
return nil
9698
}
9799

98100
func (c *UserContext) DownloadDatabase(name string, format DatabaseFormat, filePath string) error {
99-
var response apiGenericResponse
100-
101101
name = name + "." + string(format)
102102

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

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

127+
if _, err = file.Write(resp); err != nil {
128+
return fmt.Errorf("error writing to file: %w", err)
129+
}
130+
126131
return nil
127132
}
128133

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

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

145150
var database Database
146151

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

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

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

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

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

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

180-
if _, err := c.api.makeRequestN(http.MethodPost, "db-manage/databases/"+databaseName+"/import?clean="+strconv.FormatBool(emptyExistingDatabase), c.credentials, sql, nil, true); err != nil {
185+
var byteBuffer bytes.Buffer
186+
multipartWriter := multipart.NewWriter(&byteBuffer)
187+
188+
formFile, err := multipartWriter.CreateFormFile("sqlfile", "filename")
189+
if err != nil {
190+
return fmt.Errorf("failed to create form file: %w", err)
191+
}
192+
193+
if _, err = formFile.Write(sql); err != nil {
194+
return fmt.Errorf("failed to write to form file: %w", err)
195+
}
196+
197+
if err = multipartWriter.Close(); err != nil {
198+
return fmt.Errorf("failed to close multipart writer: %w", err)
199+
}
200+
201+
if _, err = c.uploadFile(http.MethodPost, "/api/db-manage/databases/"+databaseName+"/import?clean="+strconv.FormatBool(emptyExistingDatabase), byteBuffer.Bytes(), nil, multipartWriter.FormDataContentType()); err != nil {
181202
return err
182203
}
183204

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

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

@@ -205,7 +226,7 @@ func (c *UserContext) UpdateDatabaseUserPassword(username string, password strin
205226
password,
206227
}
207228

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

0 commit comments

Comments
 (0)