Skip to content

Commit a66a972

Browse files
committed
[internal] use new jwt and users packages
1 parent 87d169c commit a66a972

File tree

34 files changed

+849
-296
lines changed

34 files changed

+849
-296
lines changed

cmd/sms-gateway/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ import (
1010
// @securitydefinitions.basic ApiAuth
1111
// @description User authentication
1212

13+
// @securitydefinitions.apikey JWTAuth
14+
// @in header
15+
// @name Authorization
16+
// @description JWT authentication
17+
1318
// @securitydefinitions.apikey UserCode
1419
// @in header
1520
// @name Authorization

configs/config.example.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,19 @@ cache: # cache config
3838
url: memory:// # cache url (memory:// or redis://) [CACHE__URL]
3939
pubsub: # pubsub config
4040
url: memory:// # pubsub url (memory:// or redis://) [PUBSUB__URL]
41+
jwt:
42+
secret: # jwt secret (leave empty to disable JWT functionality) [JWT__SECRET]
43+
ttl: 24h # jwt ttl [JWT__TTL]
44+
issuer: # jwt issuer [JWT__ISSUER]
4145

4246
## Worker Config ##
4347

4448
tasks: # tasks config
4549
messages_hashing:
46-
interval: 168h # task execution interval in hours [TASKS__MESSAGES_HASHING__INTERVAL]
50+
interval: 168h # task execution interval [TASKS__MESSAGES_HASHING__INTERVAL]
4751
messages_cleanup:
48-
interval: 24h # task execution interval in hours [TASKS__MESSAGES_CLEANUP__INTERVAL]
49-
max_age: 720h # messages max age in hours [TASKS__MESSAGES_CLEANUP__MAX_AGE]
52+
interval: 24h # task execution interval [TASKS__MESSAGES_CLEANUP__INTERVAL]
53+
max_age: 720h # messages max age [TASKS__MESSAGES_CLEANUP__MAX_AGE]
5054
devices_cleanup:
51-
interval: 24h # task execution interval in hours [TASKS__DEVICES_CLEANUP__INTERVAL]
52-
max_age: 8760h # inactive devices max age in hours [TASKS__DEVICES_CLEANUP__MAX_AGE]
55+
interval: 24h # task execution interval [TASKS__DEVICES_CLEANUP__INTERVAL]
56+
max_age: 8760h # inactive devices max age [TASKS__DEVICES_CLEANUP__MAX_AGE]

internal/config/config.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package config
22

3+
import "time"
4+
35
type GatewayMode string
46

57
const (
@@ -17,6 +19,7 @@ type Config struct {
1719
Messages Messages `yaml:"messages"` // messages config
1820
Cache Cache `yaml:"cache"` // cache (memory or redis) config
1921
PubSub PubSub `yaml:"pubsub"` // pubsub (memory or redis) config
22+
JWT JWT `yaml:"jwt"` // jwt config
2023
}
2124

2225
type Gateway struct {
@@ -85,6 +88,12 @@ type PubSub struct {
8588
URL string `yaml:"url" envconfig:"PUBSUB__URL"`
8689
}
8790

91+
type JWT struct {
92+
Secret string `yaml:"secret" envconfig:"JWT__SECRET"`
93+
TTL Duration `yaml:"ttl" envconfig:"JWT__TTL"`
94+
Issuer string `yaml:"issuer" envconfig:"JWT__ISSUER"`
95+
}
96+
8897
var defaultConfig = Config{
8998
Gateway: Gateway{Mode: GatewayModePublic},
9099
HTTP: HTTP{
@@ -119,4 +128,8 @@ var defaultConfig = Config{
119128
PubSub: PubSub{
120129
URL: "memory://",
121130
},
131+
JWT: JWT{
132+
TTL: Duration(time.Hour * 24),
133+
Issuer: "sms-gate.app",
134+
},
122135
}

internal/config/module.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/android-sms-gateway/server/internal/sms-gateway/cache"
88
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers"
9+
"github.com/android-sms-gateway/server/internal/sms-gateway/jwt"
910
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/auth"
1011
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/devices"
1112
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/messages"
@@ -124,4 +125,11 @@ var Module = fx.Module(
124125
BufferSize: 128,
125126
}
126127
}),
128+
fx.Provide(func(cfg Config) jwt.Config {
129+
return jwt.Config{
130+
Secret: cfg.JWT.Secret,
131+
TTL: time.Duration(cfg.JWT.TTL),
132+
Issuer: cfg.JWT.Issuer,
133+
}
134+
}),
127135
)

internal/config/types.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package config
2+
3+
import (
4+
"encoding"
5+
"fmt"
6+
"time"
7+
8+
"gopkg.in/yaml.v3"
9+
)
10+
11+
type Duration time.Duration
12+
13+
// Duration returns the underlying time.Duration value.
14+
func (d *Duration) Duration() time.Duration {
15+
if d == nil {
16+
return 0
17+
}
18+
return time.Duration(*d)
19+
}
20+
21+
// String returns the string representation of the duration.
22+
func (d *Duration) String() string {
23+
if d == nil {
24+
return ""
25+
}
26+
return time.Duration(*d).String()
27+
}
28+
29+
func (d *Duration) UnmarshalText(text []byte) error {
30+
t, err := time.ParseDuration(string(text))
31+
if err != nil {
32+
return fmt.Errorf("can't parse duration: %w", err)
33+
}
34+
*d = Duration(t)
35+
return nil
36+
}
37+
38+
func (d *Duration) UnmarshalYAML(value *yaml.Node) error {
39+
var s string
40+
if err := value.Decode(&s); err != nil {
41+
return fmt.Errorf("can't unmarshal duration: %w", err)
42+
}
43+
44+
return d.UnmarshalText([]byte(s))
45+
}
46+
47+
var _ yaml.Unmarshaler = (*Duration)(nil)
48+
var _ encoding.TextUnmarshaler = (*Duration)(nil)

internal/sms-gateway/app.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
appconfig "github.com/android-sms-gateway/server/internal/config"
88
"github.com/android-sms-gateway/server/internal/sms-gateway/cache"
99
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers"
10+
"github.com/android-sms-gateway/server/internal/sms-gateway/jwt"
1011
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/auth"
1112
appdb "github.com/android-sms-gateway/server/internal/sms-gateway/modules/db"
1213
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/devices"
@@ -20,6 +21,7 @@ import (
2021
"github.com/android-sms-gateway/server/internal/sms-gateway/online"
2122
"github.com/android-sms-gateway/server/internal/sms-gateway/openapi"
2223
"github.com/android-sms-gateway/server/internal/sms-gateway/pubsub"
24+
"github.com/android-sms-gateway/server/internal/sms-gateway/users"
2325
"github.com/android-sms-gateway/server/pkg/health"
2426
"github.com/capcom6/go-infra-fx/cli"
2527
"github.com/capcom6/go-infra-fx/db"
@@ -39,6 +41,7 @@ var Module = fx.Module(
3941
validator.Module,
4042
openapi.Module(),
4143
handlers.Module,
44+
users.Module(),
4245
auth.Module,
4346
push.Module(),
4447
db.Module,
@@ -53,6 +56,7 @@ var Module = fx.Module(
5356
metrics.Module,
5457
sse.Module,
5558
online.Module(),
59+
jwt.Module(),
5660
)
5761

5862
func Run() {

internal/sms-gateway/handlers/3rdparty.go

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,43 +5,65 @@ import (
55
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/devices"
66
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/logs"
77
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/messages"
8+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/jwtauth"
89
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/userauth"
910
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/settings"
11+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/thirdparty"
1012
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/webhooks"
11-
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/auth"
13+
"github.com/android-sms-gateway/server/internal/sms-gateway/jwt"
14+
"github.com/android-sms-gateway/server/internal/sms-gateway/users"
1215
"github.com/go-playground/validator/v10"
1316
"github.com/gofiber/fiber/v2"
14-
"go.uber.org/fx"
1517
"go.uber.org/zap"
1618
)
1719

18-
type ThirdPartyHandlerParams struct {
19-
fx.In
20-
21-
HealthHandler *HealthHandler
22-
MessagesHandler *messages.ThirdPartyController
23-
WebhooksHandler *webhooks.ThirdPartyController
24-
DevicesHandler *devices.ThirdPartyController
25-
SettingsHandler *settings.ThirdPartyController
26-
LogsHandler *logs.ThirdPartyController
27-
28-
AuthSvc *auth.Service
29-
30-
Logger *zap.Logger
31-
Validator *validator.Validate
32-
}
33-
3420
type thirdPartyHandler struct {
3521
base.Handler
3622

23+
usersSvc *users.Service
24+
jwtSvc jwt.Service
25+
3726
healthHandler *HealthHandler
3827
messagesHandler *messages.ThirdPartyController
3928
webhooksHandler *webhooks.ThirdPartyController
4029
devicesHandler *devices.ThirdPartyController
4130
settingsHandler *settings.ThirdPartyController
4231
logsHandler *logs.ThirdPartyController
32+
authHandler *thirdparty.AuthHandler
33+
}
4334

44-
authSvc *auth.Service
35+
func newThirdPartyHandler(
36+
usersSvc *users.Service,
37+
jwtService jwt.Service,
38+
39+
healthHandler *HealthHandler,
40+
messagesHandler *messages.ThirdPartyController,
41+
webhooksHandler *webhooks.ThirdPartyController,
42+
devicesHandler *devices.ThirdPartyController,
43+
settingsHandler *settings.ThirdPartyController,
44+
logsHandler *logs.ThirdPartyController,
45+
authHandler *thirdparty.AuthHandler,
46+
47+
logger *zap.Logger,
48+
validator *validator.Validate,
49+
) *thirdPartyHandler {
50+
return &thirdPartyHandler{
51+
Handler: base.Handler{
52+
Logger: logger,
53+
Validator: validator,
54+
},
55+
56+
usersSvc: usersSvc,
57+
jwtSvc: jwtService,
58+
59+
healthHandler: healthHandler,
60+
messagesHandler: messagesHandler,
61+
webhooksHandler: webhooksHandler,
62+
devicesHandler: devicesHandler,
63+
settingsHandler: settingsHandler,
64+
logsHandler: logsHandler,
65+
authHandler: authHandler,
66+
}
4567
}
4668

4769
func (h *thirdPartyHandler) Register(router fiber.Router) {
@@ -50,10 +72,13 @@ func (h *thirdPartyHandler) Register(router fiber.Router) {
5072
h.healthHandler.Register(router)
5173

5274
router.Use(
53-
userauth.NewBasic(h.authSvc),
75+
userauth.NewBasic(h.usersSvc),
76+
jwtauth.NewJWT(h.jwtSvc, h.usersSvc),
5477
userauth.UserRequired(),
5578
)
5679

80+
h.authHandler.Register(router.Group("/auth"))
81+
5782
h.messagesHandler.Register(router.Group("/message")) // TODO: remove after 2025-12-31
5883
h.messagesHandler.Register(router.Group("/messages"))
5984

@@ -66,16 +91,3 @@ func (h *thirdPartyHandler) Register(router fiber.Router) {
6691

6792
h.logsHandler.Register(router.Group("/logs"))
6893
}
69-
70-
func newThirdPartyHandler(params ThirdPartyHandlerParams) *thirdPartyHandler {
71-
return &thirdPartyHandler{
72-
Handler: base.Handler{Logger: params.Logger.Named("ThirdPartyHandler"), Validator: params.Validator},
73-
healthHandler: params.HealthHandler,
74-
messagesHandler: params.MessagesHandler,
75-
webhooksHandler: params.WebhooksHandler,
76-
devicesHandler: params.DevicesHandler,
77-
settingsHandler: params.SettingsHandler,
78-
logsHandler: params.LogsHandler,
79-
authSvc: params.AuthSvc,
80-
}
81-
}

internal/sms-gateway/handlers/devices/3rdparty.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import (
66

77
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/base"
88
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/converters"
9+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/permissions"
910
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/userauth"
10-
"github.com/android-sms-gateway/server/internal/sms-gateway/models"
1111
"github.com/android-sms-gateway/server/internal/sms-gateway/modules/devices"
12+
"github.com/android-sms-gateway/server/internal/sms-gateway/users"
1213
"github.com/capcom6/go-helpers/slices"
1314
"github.com/gofiber/fiber/v2"
1415
"go.uber.org/fx"
@@ -32,6 +33,7 @@ type ThirdPartyController struct {
3233
// @Summary List devices
3334
// @Description Returns list of registered devices
3435
// @Security ApiAuth
36+
// @Security JWTAuth
3537
// @Tags User, Devices
3638
// @Produce json
3739
// @Success 200 {object} []smsgateway.Device "Device list"
@@ -41,7 +43,7 @@ type ThirdPartyController struct {
4143
// @Router /3rdparty/v1/devices [get]
4244
//
4345
// List devices
44-
func (h *ThirdPartyController) get(user models.User, c *fiber.Ctx) error {
46+
func (h *ThirdPartyController) get(user users.User, c *fiber.Ctx) error {
4547
devices, err := h.devicesSvc.Select(user.ID)
4648
if err != nil {
4749
return fmt.Errorf("can't select devices: %w", err)
@@ -55,6 +57,7 @@ func (h *ThirdPartyController) get(user models.User, c *fiber.Ctx) error {
5557
// @Summary Remove device
5658
// @Description Removes device
5759
// @Security ApiAuth
60+
// @Security JWTAuth
5861
// @Tags User, Devices
5962
// @Produce json
6063
// @Param id path string true "Device ID"
@@ -66,7 +69,7 @@ func (h *ThirdPartyController) get(user models.User, c *fiber.Ctx) error {
6669
// @Router /3rdparty/v1/devices/{id} [delete]
6770
//
6871
// Remove device
69-
func (h *ThirdPartyController) remove(user models.User, c *fiber.Ctx) error {
72+
func (h *ThirdPartyController) remove(user users.User, c *fiber.Ctx) error {
7073
id := c.Params("id")
7174

7275
err := h.devicesSvc.Remove(user.ID, devices.WithID(id))
@@ -81,8 +84,8 @@ func (h *ThirdPartyController) remove(user models.User, c *fiber.Ctx) error {
8184
}
8285

8386
func (h *ThirdPartyController) Register(router fiber.Router) {
84-
router.Get("", userauth.WithUser(h.get))
85-
router.Delete(":id", userauth.WithUser(h.remove))
87+
router.Get("", permissions.RequireScope(ScopeList), userauth.WithUser(h.get))
88+
router.Delete(":id", permissions.RequireScope(ScopeDelete), userauth.WithUser(h.remove))
8689
}
8790

8891
func NewThirdPartyController(params thirdPartyControllerParams) *ThirdPartyController {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package devices
2+
3+
const (
4+
ScopeList = "devices:list"
5+
ScopeDelete = "devices:delete"
6+
)

internal/sms-gateway/handlers/logs/3rdparty.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package logs
22

33
import (
44
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/base"
5+
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/permissions"
56
"github.com/android-sms-gateway/server/internal/sms-gateway/handlers/middlewares/userauth"
6-
"github.com/android-sms-gateway/server/internal/sms-gateway/models"
7+
"github.com/android-sms-gateway/server/internal/sms-gateway/users"
78
"github.com/go-playground/validator/v10"
89
"github.com/gofiber/fiber/v2"
910
"go.uber.org/fx"
@@ -24,6 +25,7 @@ type ThirdPartyController struct {
2425
// @Summary Get logs
2526
// @Description Retrieve a list of log entries within a specified time range.
2627
// @Security ApiAuth
28+
// @Security JWTAuth
2729
// @Tags System, Logs
2830
// @Produce json
2931
// @Param from query string false "The start of the time range for the logs to retrieve. Logs created after this timestamp will be included." Format(date-time)
@@ -35,12 +37,12 @@ type ThirdPartyController struct {
3537
// @Router /3rdparty/v1/logs [get]
3638
//
3739
// List webhooks
38-
func (h *ThirdPartyController) get(user models.User, c *fiber.Ctx) error {
40+
func (h *ThirdPartyController) get(user users.User, c *fiber.Ctx) error {
3941
return fiber.NewError(fiber.StatusNotImplemented, "For privacy reasons, device's logs are not accessible through Cloud server")
4042
}
4143

4244
func (h *ThirdPartyController) Register(router fiber.Router) {
43-
router.Get("", userauth.WithUser(h.get))
45+
router.Get("", permissions.RequireScope(ScopeRead), userauth.WithUser(h.get))
4446
}
4547

4648
func NewThirdPartyController(params thirdPartyControllerParams) *ThirdPartyController {

0 commit comments

Comments
 (0)