-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth.go
179 lines (141 loc) · 4.78 KB
/
auth.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package directadmin
import (
"errors"
"fmt"
"net/http"
"strings"
"time"
)
type (
credentials struct {
username string
passkey string
}
LoginHistory struct {
Attempts int `json:"attempts"`
Host string `json:"host"`
Timestamp time.Time `json:"timestamp"`
}
LoginKeyURL struct {
AllowNetworks []string `json:"allowNetworks"`
Created time.Time `json:"created"`
CreatedBy string `json:"createdBy"`
Expires time.Time `json:"expires"`
Id string `json:"id"`
RedirectURL string `json:"redirectURL"`
URL string `json:"url"`
}
)
func (c *UserContext) CreateLoginURL(loginKeyURL *LoginKeyURL) error {
if loginKeyURL == nil {
return errors.New("failed to create login key URL: loginKeyURL is nil")
}
if _, err := c.makeRequestNew(http.MethodPost, "login-keys/urls", loginKeyURL, loginKeyURL); err != nil {
return fmt.Errorf("failed to create login URL: %w", err)
}
return nil
}
func (c *UserContext) GetLoginURLs() ([]*LoginKeyURL, error) {
var loginKeyURLs []*LoginKeyURL
if _, err := c.makeRequestNew(http.MethodGet, "login-keys/urls", nil, &loginKeyURLs); err != nil {
return nil, fmt.Errorf("failed to get login URLs: %w", err)
}
return loginKeyURLs, nil
}
func (c *AdminContext) GetLoginHistory() ([]*LoginHistory, error) {
var loginHistory []*LoginHistory
if _, err := c.makeRequestNew(http.MethodGet, "login-history", nil, &loginHistory); err != nil {
return nil, fmt.Errorf("failed to get login history: %w", err)
}
if len(loginHistory) == 0 {
return nil, fmt.Errorf("no login history found")
}
return loginHistory, nil
}
// GetMyUsername returns the current user's username. This is particularly useful when logging in as another user, as it
// trims the admin/reseller username automatically
func (c *UserContext) GetMyUsername() string {
// if user is logged in via reseller, we need to remove the reseller username from the context's username
if strings.Contains(c.credentials.username, "|") {
return strings.Split(c.credentials.username, "|")[1]
}
return c.credentials.username
}
func (c *UserContext) Login() error {
var response apiGenericResponse
if _, err := c.makeRequestOld(http.MethodGet, "API_LOGIN_TEST", nil, &response); err != nil {
return err
}
if response.Success != "Login OK" {
return fmt.Errorf("login failed: %v", response)
}
return nil
}
// LoginAsAdmin verifies the provided credentials against the DA API, then returns an admin-level context.
// The passkey can either be the user's password, or a login key
func (a *API) LoginAsAdmin(username string, passkey string) (*AdminContext, error) {
userCtx, err := a.login(username, passkey)
if err != nil {
return nil, err
}
adminCtx := AdminContext{
ResellerContext{
UserContext: *userCtx,
},
}
if adminCtx.User.Config.UserType != AccountRoleAdmin {
return nil, fmt.Errorf("account is not an Admin, it is a %v", adminCtx.User.Config.UserType)
}
return &adminCtx, nil
}
// LoginAsReseller verifies the provided credentials against the DA API, then returns a reseller-level context.
// The passkey can either be the user's password, or a login key
func (a *API) LoginAsReseller(username string, passkey string) (*ResellerContext, error) {
userCtx, err := a.login(username, passkey)
if err != nil {
return nil, err
}
resellerCtx := ResellerContext{
UserContext: *userCtx,
}
if resellerCtx.User.Config.UserType != AccountRoleReseller {
return nil, fmt.Errorf("account is not an Reseller, it is a %v", resellerCtx.User.Config.UserType)
}
return &resellerCtx, nil
}
// LoginAsUser verifies the provided credentials against the DA API, then returns a user-level context.
// The passkey can either be the user's password, or a login key
func (a *API) LoginAsUser(username string, passkey string) (*UserContext, error) {
userCtx, err := a.login(username, passkey)
if err != nil {
return nil, err
}
if userCtx.User.Config.UserType != AccountRoleUser {
return nil, fmt.Errorf("account is not a User, it is a %v", userCtx.User.Config.UserType)
}
return userCtx, nil
}
func (c *AdminContext) LoginAsMyReseller(username string) (*ResellerContext, error) {
return c.api.LoginAsReseller(c.credentials.username+"|"+username, c.credentials.passkey)
}
func (c *ResellerContext) LoginAsMyUser(username string) (*UserContext, error) {
return c.api.LoginAsUser(c.credentials.username+"|"+username, c.credentials.passkey)
}
func (a *API) login(username string, passkey string) (*UserContext, error) {
userCtx := UserContext{
api: a,
credentials: credentials{
username: username,
passkey: passkey,
},
}
if err := userCtx.Login(); err != nil {
return nil, err
}
userConfig, err := userCtx.GetMyUserConfig()
if err != nil {
return nil, err
}
userCtx.User.Config = *userConfig
return &userCtx, nil
}