Skip to content

Commit 2d04f70

Browse files
committed
feat(api): add support for multiple user authentication methods
- Added a list to represent the authentication methods available for each user. - Introduced an `authentication` attribute to manage authentication method settings, such as enabling or disabling specific methods. - Updated the `/info` endpoint to include authentication details in its response.
1 parent faafd30 commit 2d04f70

File tree

19 files changed

+1108
-150
lines changed

19 files changed

+1108
-150
lines changed

api/pkg/responses/system.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package responses
2+
3+
type SystemInfo struct {
4+
Version string `json:"version"`
5+
Endpoints *SystemEndpointsInfo `json:"endpoints"`
6+
Setup bool `json:"setup"`
7+
Authentication *SystemAuthenticationInfo `json:"authentication"`
8+
}
9+
10+
type SystemAuthenticationInfo struct {
11+
Local bool `json:"local"`
12+
}
13+
14+
type SystemEndpointsInfo struct {
15+
API string `json:"api"`
16+
SSH string `json:"ssh"`
17+
}

api/routes/stats.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,16 @@ func (h *Handler) GetStats(c gateway.Context) error {
2323
}
2424

2525
func (h *Handler) GetSystemInfo(c gateway.Context) error {
26-
var req requests.SystemGetInfo
27-
28-
if err := c.Bind(&req); err != nil {
26+
req := new(requests.GetSystemInfo)
27+
if err := c.Bind(req); err != nil {
2928
return err
3029
}
3130

3231
if req.Host == "" {
3332
req.Host = c.Request().Host
3433
}
3534

36-
info, err := h.service.SystemGetInfo(c.Ctx(), req)
35+
info, err := h.service.GetSystemInfo(c.Ctx(), req)
3736
if err != nil {
3837
return err
3938
}

api/routes/stats_test.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88
"testing"
99

10+
"github.com/shellhub-io/shellhub/api/pkg/responses"
1011
"github.com/shellhub-io/shellhub/api/services/mocks"
1112
"github.com/shellhub-io/shellhub/pkg/api/authorizer"
1213
"github.com/shellhub-io/shellhub/pkg/api/requests"
@@ -20,22 +21,25 @@ func TestGetSystemInfo(t *testing.T) {
2021

2122
cases := []struct {
2223
title string
23-
request requests.SystemGetInfo
24-
requiredMocks func(updatePayloadMock requests.SystemGetInfo)
24+
request requests.GetSystemInfo
25+
requiredMocks func(updatePayloadMock requests.GetSystemInfo)
2526
expectedStatus int
2627
}{
2728
{
2829
title: "success when try to get infos of a existing system",
29-
request: requests.SystemGetInfo{
30+
request: requests.GetSystemInfo{
3031
Host: "example.com",
3132
Port: 0,
3233
},
33-
requiredMocks: func(updatePayloadMock requests.SystemGetInfo) {
34-
mock.On("SystemGetInfo", gomock.Anything, requests.SystemGetInfo{
35-
Host: "example.com",
36-
Port: 0,
37-
},
38-
).Return(&models.SystemInfo{}, nil)
34+
requiredMocks: func(updatePayloadMock requests.GetSystemInfo) {
35+
mock.
36+
On(
37+
"GetSystemInfo",
38+
gomock.Anything,
39+
&requests.GetSystemInfo{Host: "example.com", Port: 0},
40+
).
41+
Return(&responses.SystemInfo{}, nil).
42+
Once()
3943
},
4044
expectedStatus: http.StatusOK,
4145
},

api/services/auth.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"encoding/hex"
1212
"encoding/pem"
1313
"net"
14+
"slices"
1415
"strings"
1516
"time"
1617

@@ -171,6 +172,10 @@ func (s *service) AuthDevice(ctx context.Context, req requests.DeviceAuth, remot
171172
}
172173

173174
func (s *service) AuthLocalUser(ctx context.Context, req *requests.AuthLocalUser, sourceIP string) (*models.UserAuthResponse, int64, string, error) {
175+
if s, err := s.store.SystemGet(ctx); err != nil || !s.Authentication.Local.Enabled {
176+
return nil, 0, "", NewErrAuthMethodNotAllowed()
177+
}
178+
174179
var err error
175180
var user *models.User
176181

@@ -184,7 +189,7 @@ func (s *service) AuthLocalUser(ctx context.Context, req *requests.AuthLocalUser
184189
return nil, 0, "", NewErrAuthUnathorized(nil)
185190
}
186191

187-
if user.Origin != models.UserOriginLocal {
192+
if !slices.Contains(user.Preferences.AuthMethods, models.UserAuthMethodLocal) {
188193
return nil, 0, "", NewErrAuthUnathorized(nil)
189194
}
190195

@@ -289,7 +294,8 @@ func (s *service) AuthLocalUser(ctx context.Context, req *requests.AuthLocalUser
289294

290295
res := &models.UserAuthResponse{
291296
ID: user.ID,
292-
Origin: user.Origin.String(),
297+
Origin: user.Origin,
298+
AuthMethods: user.Preferences.AuthMethods,
293299
User: user.Username,
294300
Name: user.Name,
295301
Email: user.Email,
@@ -372,7 +378,8 @@ func (s *service) CreateUserToken(ctx context.Context, req *requests.CreateUserT
372378

373379
return &models.UserAuthResponse{
374380
ID: user.ID,
375-
Origin: user.Origin.String(),
381+
Origin: user.Origin,
382+
AuthMethods: user.Preferences.AuthMethods,
376383
User: user.Username,
377384
Name: user.Name,
378385
Email: user.Email,

0 commit comments

Comments
 (0)