Skip to content

Commit

Permalink
Merge branch 'master' into codearchitecture
Browse files Browse the repository at this point in the history
  • Loading branch information
punithnayak authored Aug 26, 2023
2 parents f0fc8b4 + 963ee8c commit 4bb22c7
Show file tree
Hide file tree
Showing 272 changed files with 34,432 additions and 7,738 deletions.
9 changes: 6 additions & 3 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
*.go linguist-language=Go
*.sh linguist-language=Shell
*.js linguist-language=JavaScript
*.go linguist-detectable=true
*.css linguist-detectable=false
*.js linguist-detectable=false
*.ts linguist-detectable=false
*.html linguist-detectable=false
*.tsx linguist-detectable=false
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
id: getcommit
run: |
prsha=$(echo $response | jq '.[-1].sha' | tr -d '"')
echo "::set-output name=sha::$prsha"
echo "sha=$prsha" >> $GITHUB_OUTPUT
env:
response: ${{ steps.get_PR_commits.outputs.data }}

Expand Down
8 changes: 8 additions & 0 deletions chaoscenter/Readme.md → chaoscenter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ metrics:
enabled: false
prometheusRule:
enabled: false

# bitnami/mongodb is not yet supported on ARM.
# Using unofficial tools to build bitnami/mongodb (arm64 support)
# more info: https://github.com/ZCube/bitnami-compat
#image:
# registry: ghcr.io/zcube
# repository: bitnami-compat/mongodb
# tag: 6.0.5
```

```shell
Expand Down
3 changes: 1 addition & 2 deletions chaoscenter/authentication/api/handlers/grpc/grpc_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"strconv"

"github.com/litmuschaos/litmus/chaoscenter/authentication/api/middleware"
"github.com/litmuschaos/litmus/chaoscenter/authentication/api/presenter/protos"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/entities"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/validations"
Expand All @@ -16,7 +15,7 @@ import (

func (s *ServerGrpc) ValidateRequest(ctx context.Context,
inputRequest *protos.ValidationRequest) (*protos.ValidationResponse, error) {
token, err := middleware.ValidateToken(inputRequest.Jwt)
token, err := s.ValidateToken(inputRequest.Jwt)
if err != nil {
return &protos.ValidationResponse{Error: err.Error(), IsValid: false}, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ func DexCallback(userService services.ApplicationService) gin.HandlerFunc {
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
return
}
jwtToken, err := signedInUser.GetSignedJWT()
jwtToken, err := userService.GetSignedJWT(signedInUser)
if err != nil {
log.Error(err)
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func getInvitation(service services.ApplicationService, member entities.MemberIn
func ListInvitations(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {
uID := c.MustGet("uid").(string)
invitationState := c.Param("invitation-state")
invitationState := c.Param("invitation_state")
var response []entities.ListInvitationResponse
projects, err := service.ListInvitations(uID, entities.Invitation(invitationState))
if err != nil {
Expand Down Expand Up @@ -325,6 +325,9 @@ func SendInvitation(service services.ApplicationService) gin.HandlerFunc {
newMember := &entities.Member{
UserID: user.ID,
Role: *member.Role,
Username: user.Username,
Name: user.Name,
Email: user.Email,
Invitation: entities.PendingInvitation,
JoinedAt: time.Now().Unix(),
}
Expand Down Expand Up @@ -499,7 +502,7 @@ func RemoveInvitation(service services.ApplicationService) gin.HandlerFunc {

case entities.DeclinedInvitation, entities.ExitedProject:
{
c.JSON(400, gin.H{"message": "User is already not a part of your project"})
c.JSON(400, gin.H{"message": "User is not a part of your project"})
return
}
}
Expand Down
52 changes: 50 additions & 2 deletions chaoscenter/authentication/api/handlers/rest/user_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"golang.org/x/crypto/bcrypt"
)

const BearerSchema = "Bearer "

func CreateUser(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {
userRole := c.MustGet("role").(string)
Expand Down Expand Up @@ -127,6 +129,12 @@ func GetUser(service services.ApplicationService) gin.HandlerFunc {

func FetchUsers(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {
userRole := c.MustGet("role").(string)

if entities.Role(userRole) != entities.RoleAdmin {
c.AbortWithStatusJSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], presenter.CreateErrorResponse(utils.ErrUnauthorized))
return
}
users, err := service.GetUsers()
if err != nil {
log.Error(err)
Expand Down Expand Up @@ -156,7 +164,7 @@ func InviteUsers(service services.ApplicationService) gin.HandlerFunc {
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
return
}
c.JSON(200, users)
c.JSON(200, gin.H{"data": users})
}
}

Expand Down Expand Up @@ -197,7 +205,7 @@ func LoginUser(service services.ApplicationService) gin.HandlerFunc {
return
}

token, err := user.GetSignedJWT()
token, err := service.GetSignedJWT(user)
if err != nil {
log.Error(err)
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
Expand All @@ -216,6 +224,9 @@ func LoginUser(service services.ApplicationService) gin.HandlerFunc {
UserID: user.ID,
Role: entities.RoleOwner,
Invitation: entities.AcceptedInvitation,
Username: user.Username,
Name: user.Name,
Email: user.Email,
JoinedAt: time.Now().Unix(),
}
var members []*entities.Member
Expand Down Expand Up @@ -259,6 +270,28 @@ func LoginUser(service services.ApplicationService) gin.HandlerFunc {
}
}

// LogoutUser revokes the token passed in the Authorization header
func LogoutUser(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {
authHeader := c.GetHeader("Authorization")
if authHeader == "" {
c.AbortWithStatusJSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], presenter.CreateErrorResponse(utils.ErrUnauthorized))
return
}
tokenString := authHeader[len(BearerSchema):]
// revoke token
err := service.RevokeToken(tokenString)
if err != nil {
log.Error(err)
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
return
}
c.JSON(200, gin.H{
"message": "successfully logged out",
})
}
}

func UpdatePassword(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {
var userPasswordRequest entities.UserPassword
Expand Down Expand Up @@ -295,6 +328,13 @@ func UpdatePassword(service services.ApplicationService) gin.HandlerFunc {

func ResetPassword(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {
userRole := c.MustGet("role").(string)

if entities.Role(userRole) != entities.RoleAdmin {
c.AbortWithStatusJSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], presenter.CreateErrorResponse(utils.ErrUnauthorized))
return
}

var userPasswordRequest entities.UserPassword
err := c.BindJSON(&userPasswordRequest)
if err != nil {
Expand Down Expand Up @@ -338,6 +378,14 @@ func ResetPassword(service services.ApplicationService) gin.HandlerFunc {

func UpdateUserState(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {

userRole := c.MustGet("role").(string)

if entities.Role(userRole) != entities.RoleAdmin {
c.AbortWithStatusJSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], presenter.CreateErrorResponse(utils.ErrUnauthorized))
return
}

var userRequest entities.UpdateUserState
err := c.BindJSON(&userRequest)
if err != nil {
Expand Down
26 changes: 20 additions & 6 deletions chaoscenter/authentication/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/misc"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/project"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/services"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/session"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/user"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/utils"

Expand All @@ -37,6 +38,8 @@ type Config struct {
}

func init() {
log.SetFormatter(&log.JSONFormatter{})
log.SetReportCaller(true)
printVersion()

var c Config
Expand All @@ -48,7 +51,7 @@ func init() {
}

func main() {
// send logs to stderr so we can use 'kubectl logs'
// send logs to stderr, so we can use 'kubectl logs'
_ = flag.Set("logtostderr", "true")
_ = flag.Set("v", "3")

Expand All @@ -64,18 +67,27 @@ func main() {
// Creating User Collection
err = utils.CreateCollection(utils.UserCollection, db)
if err != nil {
log.Fatalf("failed to create collection %s", err)
log.Errorf("failed to create collection %s", err)
}

err = utils.CreateIndex(utils.UserCollection, utils.UsernameField, db)
if err != nil {
log.Fatalf("failed to create index %s", err)
log.Errorf("failed to create index %s", err)
}

// Creating Project Collection
err = utils.CreateCollection(utils.ProjectCollection, db)
if err != nil {
log.Fatalf("failed to create collection %s", err)
log.Errorf("failed to create collection %s", err)
}

// Creating Session Collection
if err = utils.CreateCollection(utils.RevokedTokenCollection, db); err != nil {
log.Errorf("failed to create collection %s", err)
}

if err = utils.CreateTTLIndex(utils.RevokedTokenCollection, db); err != nil {
log.Errorf("failed to create index %s", err)
}

userCollection := db.Collection(utils.UserCollection)
Expand All @@ -84,9 +96,12 @@ func main() {
projectCollection := db.Collection(utils.ProjectCollection)
projectRepo := project.NewRepo(projectCollection)

revokedTokenCollection := db.Collection(utils.RevokedTokenCollection)
sessionRepo := session.NewRepo(revokedTokenCollection)

miscRepo := misc.NewRepo(db, client)

applicationService := services.NewService(userRepo, projectRepo, miscRepo, db)
applicationService := services.NewService(userRepo, projectRepo, miscRepo, sessionRepo, db)

validatedAdminSetup(applicationService)

Expand All @@ -95,7 +110,6 @@ func main() {
}

func validatedAdminSetup(service services.ApplicationService) {

// Assigning UID to admin
uID := uuid.Must(uuid.NewRandom()).String()

Expand Down
31 changes: 11 additions & 20 deletions chaoscenter/authentication/api/middleware/jwt_middlware.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
package middleware

import (
"fmt"

"github.com/litmuschaos/litmus/chaoscenter/authentication/api/presenter"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/utils"

"github.com/gin-gonic/gin"
"github.com/golang-jwt/jwt"
"github.com/sirupsen/logrus"
"github.com/litmuschaos/litmus/chaoscenter/authentication/api/presenter"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/services"
"github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/utils"
log "github.com/sirupsen/logrus"
)

// JwtMiddleware is a Gin Middleware that authorises requests
func JwtMiddleware() gin.HandlerFunc {
func JwtMiddleware(service services.ApplicationService) gin.HandlerFunc {
return func(c *gin.Context) {
const BearerSchema = "Bearer "
authHeader := c.GetHeader("Authorization")
Expand All @@ -21,28 +19,21 @@ func JwtMiddleware() gin.HandlerFunc {
return
}
tokenString := authHeader[len(BearerSchema):]
token, err := ValidateToken(tokenString)
token, err := service.ValidateToken(tokenString)
if err != nil {
log.Error(err)
c.AbortWithStatusJSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], presenter.CreateErrorResponse(utils.ErrUnauthorized))
return
}
if token.Valid {
claims := token.Claims.(jwt.MapClaims)
c.Set("username", claims["username"])
c.Set("uid", claims["uid"])
c.Set("role", claims["role"])
c.Next()
} else {
logrus.Info(err)
c.AbortWithStatusJSON(utils.ErrorStatusCodes[utils.ErrUnauthorized], presenter.CreateErrorResponse(utils.ErrUnauthorized))
return
}
}
}

// ValidateToken validates the given JWT Token
func ValidateToken(encodedToken string) (*jwt.Token, error) {
return jwt.Parse(encodedToken, func(token *jwt.Token) (interface{}, error) {
if _, isValid := token.Method.(*jwt.SigningMethodHMAC); !isValid {
return nil, fmt.Errorf("invalid token %s", token.Header["alg"])
}
return []byte(utils.JwtSecret), nil
})

}
4 changes: 2 additions & 2 deletions chaoscenter/authentication/api/routes/project_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import (

// ProjectRouter creates all the required routes for project related purposes.
func ProjectRouter(router *gin.Engine, service services.ApplicationService) {
router.Use(middleware.JwtMiddleware())
router.Use(middleware.JwtMiddleware(service))
router.GET("/get_project/:project_id", rest.GetProject(service))
router.GET("/get_project_members/:project_id/:state", rest.GetActiveProjectMembers(service))
router.GET("/get_user_with_project/:username", rest.GetUserWithProject(service))
router.GET("/get_owner_projects", rest.GetOwnerProjects(service))
router.GET("/get_project_role/:project_id", rest.GetProjectRole(service))
router.GET("/list_projects", rest.GetProjectsByUserID(service))
router.GET("/get_projects_stats", rest.GetProjectStats(service))
router.GET("/list_invitations_with_filters/:invitation-state", rest.ListInvitations(service))
router.GET("/list_invitations_with_filters/:invitation_state", rest.ListInvitations(service))
router.POST("/create_project", rest.CreateProject(service))
router.POST("/send_invitation", rest.SendInvitation(service))
router.POST("/accept_invitation", rest.AcceptInvitation(service))
Expand Down
3 changes: 2 additions & 1 deletion chaoscenter/authentication/api/routes/user_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
// UserRouter creates all the required routes for user authentications purposes.
func UserRouter(router *gin.Engine, service services.ApplicationService) {
router.POST("/login", rest.LoginUser(service))
router.Use(middleware.JwtMiddleware())
router.POST("/logout", rest.LogoutUser(service))
router.Use(middleware.JwtMiddleware(service))
router.POST("/update/password", rest.UpdatePassword(service))
router.POST("/reset/password", rest.ResetPassword(service))
router.POST("/create_user", rest.CreateUser(service))
Expand Down
8 changes: 8 additions & 0 deletions chaoscenter/authentication/pkg/entities/session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package entities

// RevokedToken struct for storing revoked tokens
type RevokedToken struct {
Token string `bson:"token"`
ExpiresAt int64 `bson:"expires_at"`
CreatedAt int64 `bson:"created_at"`
}
Loading

0 comments on commit 4bb22c7

Please sign in to comment.