Skip to content

Commit c73476f

Browse files
authored
Merge pull request #12 from raghavyuva/feature/notifications-conf
notification configuration setup, any controller can now make use of …
2 parents cc4ed05 + 23a8795 commit c73476f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1374
-518
lines changed

api/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/jackc/pgx/v5 v5.7.2
1111
github.com/joho/godotenv v1.5.1
1212
github.com/sirupsen/logrus v1.9.3
13+
github.com/slack-go/slack v0.16.0
1314
github.com/swaggo/http-swagger/v2 v2.0.2
1415
github.com/swaggo/swag v1.16.4
1516
github.com/uptrace/bun v1.2.10

api/go.sum

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,18 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z
1313
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
1414
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
1515
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
16+
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
17+
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
1618
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
1719
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
20+
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
21+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
22+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1823
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
1924
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
2025
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
2126
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
27+
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
2228
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
2329
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
2430
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
@@ -53,7 +59,10 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN
5359
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
5460
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
5561
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
62+
github.com/slack-go/slack v0.16.0 h1:khp/WCFv+Hb/B/AJaAwvcxKun0hM6grN0bUZ8xG60P8=
63+
github.com/slack-go/slack v0.16.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
5664
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
65+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
5766
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
5867
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
5968
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
@@ -94,6 +103,7 @@ golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
94103
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
95104
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
96105
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
106+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
97107
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
98108
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
99109
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=

api/internal/features/auth/controller/init.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import (
66
"github.com/raghavyuva/nixopus-api/internal/features/auth/service"
77
"github.com/raghavyuva/nixopus-api/internal/features/auth/validation"
88
"github.com/raghavyuva/nixopus-api/internal/features/logger"
9+
"github.com/raghavyuva/nixopus-api/internal/features/notification"
910
shared_storage "github.com/raghavyuva/nixopus-api/internal/storage"
1011
)
1112

1213
type AuthController struct {
13-
store *shared_storage.Store
14-
validator *validation.Validator
15-
service *service.AuthService
16-
ctx context.Context
17-
logger logger.Logger
14+
store *shared_storage.Store
15+
validator *validation.Validator
16+
service *service.AuthService
17+
ctx context.Context
18+
logger logger.Logger
19+
notification *notification.NotificationManager
1820
}
1921

2022
// NewAuthController creates a new AuthController with the given App.
@@ -26,12 +28,14 @@ func NewAuthController(
2628
store *shared_storage.Store,
2729
ctx context.Context,
2830
l logger.Logger,
31+
notificationManager *notification.NotificationManager,
2932
) *AuthController {
3033
return &AuthController{
31-
store: store,
32-
validator: validation.NewValidator(),
33-
service: service.NewAuthService(store, ctx, l),
34-
ctx: ctx,
35-
logger: l,
34+
store: store,
35+
validator: validation.NewValidator(),
36+
service: service.NewAuthService(store, ctx, l),
37+
ctx: ctx,
38+
logger: l,
39+
notification: notificationManager,
3640
}
3741
}

api/internal/features/auth/controller/login.go

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

66
"github.com/raghavyuva/nixopus-api/internal/features/auth/types"
77
"github.com/raghavyuva/nixopus-api/internal/features/logger"
8+
"github.com/raghavyuva/nixopus-api/internal/features/notification"
89
"github.com/raghavyuva/nixopus-api/internal/utils"
910
)
1011

@@ -42,5 +43,19 @@ func (c *AuthController) Login(w http.ResponseWriter, r *http.Request) {
4243
return
4344
}
4445

46+
c.notification.SendNotification(notification.NewNotificationPayload(
47+
notification.NotificationPayloadTypeLogin,
48+
response.User.ID.String(),
49+
notification.NotificationAuthenticationData{
50+
Email: login_request.Email,
51+
NotificationBaseData: notification.NotificationBaseData{
52+
IP: r.RemoteAddr,
53+
Browser: r.UserAgent(),
54+
},
55+
UserName: response.User.Username,
56+
},
57+
notification.NotificationCategoryAuthentication,
58+
))
59+
4560
utils.SendJSONResponse(w, "success", "User logged in successfully", response)
4661
}

api/internal/features/auth/controller/logout.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ import (
55

66
"github.com/raghavyuva/nixopus-api/internal/features/auth/types"
77
"github.com/raghavyuva/nixopus-api/internal/features/logger"
8+
"github.com/raghavyuva/nixopus-api/internal/features/notification"
89
"github.com/raghavyuva/nixopus-api/internal/utils"
10+
11+
shared_types "github.com/raghavyuva/nixopus-api/internal/types"
912
)
1013

1114
// Logout godoc
@@ -36,10 +39,33 @@ func (c *AuthController) Logout(w http.ResponseWriter, r *http.Request) {
3639
return
3740
}
3841

42+
userAny := r.Context().Value(shared_types.UserContextKey)
43+
user, ok := userAny.(*shared_types.User)
44+
45+
if !ok {
46+
c.logger.Log(logger.Error, types.ErrFailedToGetUserFromContext.Error(), types.ErrFailedToGetUserFromContext.Error())
47+
utils.SendErrorResponse(w, types.ErrFailedToGetUserFromContext.Error(), http.StatusInternalServerError)
48+
return
49+
}
50+
3951
if err := c.service.Logout(logoutRequest.RefreshToken); err != nil {
4052
utils.SendErrorResponse(w, err.Error(), http.StatusInternalServerError)
4153
return
4254
}
4355

56+
c.notification.SendNotification(notification.NewNotificationPayload(
57+
notification.NotificationPayloadTypeLogout,
58+
user.ID.String(),
59+
notification.NotificationAuthenticationData{
60+
Email: user.Email,
61+
NotificationBaseData: notification.NotificationBaseData{
62+
IP: r.RemoteAddr,
63+
Browser: r.UserAgent(),
64+
},
65+
UserName: user.Username,
66+
},
67+
notification.NotificationCategoryAuthentication,
68+
))
69+
4470
utils.SendJSONResponse(w, "success", "Logged out successfully", nil)
4571
}

api/internal/features/auth/controller/reset_password.go

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

77
"github.com/raghavyuva/nixopus-api/internal/features/auth/types"
88
"github.com/raghavyuva/nixopus-api/internal/features/logger"
9+
"github.com/raghavyuva/nixopus-api/internal/features/notification"
910
shared_types "github.com/raghavyuva/nixopus-api/internal/types"
1011
"github.com/raghavyuva/nixopus-api/internal/utils"
1112
)
@@ -54,6 +55,20 @@ func (c *AuthController) ResetPassword(w http.ResponseWriter, r *http.Request) {
5455
return
5556
}
5657

58+
c.notification.SendNotification(notification.NewNotificationPayload(
59+
notification.NotificationPayloadTypePasswordReset,
60+
user.ID.String(),
61+
notification.NotificationAuthenticationData{
62+
Email: user.Email,
63+
NotificationBaseData: notification.NotificationBaseData{
64+
IP: r.RemoteAddr,
65+
Browser: r.UserAgent(),
66+
},
67+
UserName: user.Username,
68+
},
69+
notification.NotificationCategoryAuthentication,
70+
))
71+
5772
utils.SendJSONResponse(w, "success", "Password reset successfully", nil)
5873
}
5974

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package controller
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/raghavyuva/nixopus-api/internal/features/logger"
7+
"github.com/raghavyuva/nixopus-api/internal/features/notification"
8+
shared_types "github.com/raghavyuva/nixopus-api/internal/types"
9+
"github.com/raghavyuva/nixopus-api/internal/utils"
10+
)
11+
12+
// @Summary Add SMTP configuration
13+
// @Description Add SMTP configuration
14+
// @Tags notification
15+
// @Accept json
16+
// @Produce json
17+
// @Param SMTPConfigs body notification.CreateSMTPConfigRequest true "SMTP configuration"
18+
// @Success 200 {object} types.Response "SMTP added successfully"
19+
// @Failure 400 {object} types.Response "Bad request"
20+
// @Failure 500 {object} types.Response "Internal server error"
21+
// @Router /notification/add-smtp [post]
22+
func (c *NotificationController) AddSmtp(w http.ResponseWriter, r *http.Request) {
23+
var SMTPConfigs notification.CreateSMTPConfigRequest
24+
if err := c.validator.ParseRequestBody(r, r.Body, &SMTPConfigs); err != nil {
25+
c.logger.Log(logger.Error, shared_types.ErrFailedToDecodeRequest.Error(), err.Error())
26+
utils.SendErrorResponse(w, shared_types.ErrFailedToDecodeRequest.Error(), http.StatusBadRequest)
27+
return
28+
}
29+
30+
if err := c.validator.ValidateRequest(SMTPConfigs); err != nil {
31+
c.logger.Log(logger.Error, err.Error(), "")
32+
utils.SendErrorResponse(w, err.Error(), http.StatusBadRequest)
33+
return
34+
}
35+
36+
userAny := r.Context().Value(shared_types.UserContextKey)
37+
user, ok := userAny.(*shared_types.User)
38+
39+
if !ok {
40+
c.logger.Log(logger.Error, shared_types.ErrFailedToGetUserFromContext.Error(), shared_types.ErrFailedToGetUserFromContext.Error())
41+
utils.SendErrorResponse(w, shared_types.ErrFailedToGetUserFromContext.Error(), http.StatusInternalServerError)
42+
return
43+
}
44+
45+
err := c.service.AddSmtp(SMTPConfigs,user.ID)
46+
if err != nil {
47+
c.logger.Log(logger.Error, err.Error(), "")
48+
utils.SendErrorResponse(w, err.Error(), http.StatusInternalServerError)
49+
return
50+
}
51+
52+
utils.SendJSONResponse(w, "success", "SMTP added successfully", nil)
53+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package controller
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/raghavyuva/nixopus-api/internal/features/logger"
7+
"github.com/raghavyuva/nixopus-api/internal/features/notification"
8+
"github.com/raghavyuva/nixopus-api/internal/utils"
9+
10+
shared_types "github.com/raghavyuva/nixopus-api/internal/types"
11+
)
12+
13+
// @Summary Delete SMTP configuration
14+
// @Description Delete SMTP configuration
15+
// @Tags notification
16+
// @Accept json
17+
// @Produce json
18+
// @Param SMTPConfigs body notification.DeleteSMTPConfigRequest true "SMTP configuration"
19+
// @Success 200 {object} types.Response "SMTP deleted successfully"
20+
// @Failure 400 {object} types.Response "Bad request"
21+
// @Failure 500 {object} types.Response "Internal server error"
22+
// @Router /notification/delete-smtp [post]
23+
func (c *NotificationController) DeleteSmtp(w http.ResponseWriter, r *http.Request) {
24+
var SMTPConfigs notification.DeleteSMTPConfigRequest
25+
if err := c.validator.ParseRequestBody(r, r.Body, &SMTPConfigs); err != nil {
26+
c.logger.Log(logger.Error, shared_types.ErrFailedToDecodeRequest.Error(), err.Error())
27+
utils.SendErrorResponse(w, shared_types.ErrFailedToDecodeRequest.Error(), http.StatusBadRequest)
28+
return
29+
}
30+
31+
if err := c.validator.ValidateRequest(SMTPConfigs); err != nil {
32+
c.logger.Log(logger.Error, err.Error(), "")
33+
utils.SendErrorResponse(w, err.Error(), http.StatusBadRequest)
34+
return
35+
}
36+
37+
err := c.service.DeleteSmtp(SMTPConfigs.ID.String())
38+
if err != nil {
39+
c.logger.Log(logger.Error, err.Error(), "")
40+
utils.SendErrorResponse(w, err.Error(), http.StatusInternalServerError)
41+
return
42+
}
43+
44+
utils.SendJSONResponse(w, "success", "SMTP deleted successfully", nil)
45+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package controller
2+
3+
import (
4+
"github.com/raghavyuva/nixopus-api/internal/features/logger"
5+
"github.com/raghavyuva/nixopus-api/internal/utils"
6+
"net/http"
7+
8+
shared_types "github.com/raghavyuva/nixopus-api/internal/types"
9+
)
10+
11+
// @Summary Get SMTP configuration
12+
// @Description Get SMTP configuration
13+
// @Tags notification
14+
// @Accept json
15+
// @Produce json
16+
// @Success 200 {object} types.Response "SMTP configuration"
17+
// @Failure 400 {object} types.Response "Bad request"
18+
// @Failure 500 {object} types.Response "Internal server error"
19+
// @Router /notification/get-smtp [get]
20+
func (c *NotificationController) GetSmtp(w http.ResponseWriter, r *http.Request) {
21+
userAny := r.Context().Value(shared_types.UserContextKey)
22+
user, ok := userAny.(*shared_types.User)
23+
24+
if !ok {
25+
c.logger.Log(logger.Error, shared_types.ErrFailedToGetUserFromContext.Error(), shared_types.ErrFailedToGetUserFromContext.Error())
26+
utils.SendErrorResponse(w, shared_types.ErrFailedToGetUserFromContext.Error(), http.StatusInternalServerError)
27+
return
28+
}
29+
SMTPConfigs, err := c.service.GetSmtp(user.ID.String())
30+
if err != nil {
31+
c.logger.Log(logger.Error, err.Error(), "")
32+
utils.SendErrorResponse(w, err.Error(), http.StatusInternalServerError)
33+
return
34+
}
35+
36+
utils.SendJSONResponse(w, "success", "SMTP configuration", SMTPConfigs)
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package controller
2+
3+
import (
4+
"context"
5+
6+
"github.com/raghavyuva/nixopus-api/internal/features/logger"
7+
"github.com/raghavyuva/nixopus-api/internal/features/notification"
8+
"github.com/raghavyuva/nixopus-api/internal/features/notification/service"
9+
"github.com/raghavyuva/nixopus-api/internal/features/notification/validation"
10+
shared_storage "github.com/raghavyuva/nixopus-api/internal/storage"
11+
)
12+
13+
type NotificationController struct {
14+
store *shared_storage.Store
15+
validator *validation.Validator
16+
service *service.NotificationService
17+
ctx context.Context
18+
logger logger.Logger
19+
notification *notification.NotificationManager
20+
}
21+
22+
// NewNotificationController creates a new NotificationController with the given App.
23+
//
24+
// This function creates a new NotificationController with the given App and returns a pointer to it.
25+
//
26+
// The App passed to this function should be a valid App that has been created with storage.NewApp.
27+
func NewNotificationController(
28+
store *shared_storage.Store,
29+
ctx context.Context,
30+
l logger.Logger,
31+
notificationManager *notification.NotificationManager,
32+
) *NotificationController {
33+
return &NotificationController{
34+
store: store,
35+
validator: validation.NewValidator(),
36+
service: service.NewNotificationService(store, ctx, l),
37+
ctx: ctx,
38+
logger: l,
39+
notification: notificationManager,
40+
}
41+
}

0 commit comments

Comments
 (0)