Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for jwt secret creation of each user upon user login #4719

Merged
merged 22 commits into from
Jul 5, 2024

Conversation

Saranya-jena
Copy link
Contributor

@Saranya-jena Saranya-jena commented Jun 19, 2024

Proposed changes

As part of the fix we are storing the JWT secret in the DB which is generated using randomization and then encoded into base64 format before inserting into DB. This secret is generated once during litmus installation and is being used for token validation.

Summarize your changes here to communicate with the maintainers and make sure to put the link of that issue

Types of changes

What types of changes does your code introduce to Litmus? Put an x in the boxes that apply

  • New feature (non-breaking change which adds functionality)
  • Bugfix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation Update (if none of the other choices applies)

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • I have read the CONTRIBUTING doc
  • I have signed the commit for DCO to be passed.
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if appropriate)
  • I have added necessary documentation (if appropriate)

Dependency

  • Please add the links to the dependent PR need to be merged before this (if any).

Special notes for your reviewer:

// UpdateUser updates user details in the database
func (r repository) UpdateUser(user *entities.UserDetails) error {
data, _ := toDoc(user)
_, err := r.Collection.UpdateOne(context.Background(), bson.M{"_id": user.ID}, bson.M{"$set": data})
_, err := r.Collection.UpdateMany(context.Background(), bson.M{"_id": user.ID}, bson.M{"$set": data})

Check failure

Code scanning / CodeQL

Database query built from user-controlled sources High

This query depends on a
user-provided value
.
Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
Comment on lines 291 to 310
salt := utils.RandomString(6)
newHashedSalt, err := bcrypt.GenerateFromPassword([]byte(salt), utils.PasswordEncryptionCost)
if err != nil {
log.Error(err)
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
return
}

err = service.UpdateUserByQuery(bson.D{
{"user_id", user.ID},
}, bson.D{
{"$set", bson.D{
{"salt", string(newHashedSalt)},
}},
})
if err != nil {
log.Error(err)
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
return
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please make this a new function which can be reused in both the places

@@ -206,10 +207,20 @@ func (r repository) CreateUser(user *entities.User) (*entities.User, error) {
return user.SanitizedUser(), nil
}

// UpdateUserByQuery updates user details in the database
func (r repository) UpdateUserByQuery(filter bson.D, updateQuery bson.D) error {
_, err := r.Collection.UpdateMany(context.Background(), filter, updateQuery)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be just Update not UpdateMany

func RandomString(n int) string {
if n > 0 {
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-")
rand.Seed(time.Now().UnixNano())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will give the same seed value for a given input which can be easy to guess, how about using crypto/rand?

Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
return a.authConfigRepo.GetConfig(key)
}

func (a applicationService) UpdateConfig(ctx context.Context, key string, value interface{}) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this will be ever used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have kept it for future use in case we need to add more such cases

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can always add it back if needed. As they say "developers spend more time reading the code than writing". We can keep it if you can think of any use case in the future where this can be utilised, but if not then this can be removed.

Collection *mongo.Collection
}

func (r repository) CreateConfig(config AuthConfig) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about renaming this to CreateSalt and GetSalt, code will be more readable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above, if you look at the schema it's like key value pair, which can be used to store different types od data so to generalise it, I have given such naming.

package response

import (
authConfig2 "github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/authConfig"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to add alias to this import

@@ -138,7 +138,20 @@ func DexCallback(userService services.ApplicationService) gin.HandlerFunc {
c.JSON(utils.ErrorStatusCodes[utils.ErrServerError], presenter.CreateErrorResponse(utils.ErrServerError))
return
}
jwtToken, err := userService.GetSignedJWT(signedInUser)

salt, err := userService.GetConfig("salt")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The salt value being returned here is an encrypted value and should be decrypted before using it to generate the JWT

@@ -294,7 +293,13 @@ func LoginUser(service services.ApplicationService) gin.HandlerFunc {
return
}

token, err := service.GetSignedJWT(user)
salt, err := service.GetConfig("salt")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
@@ -294,7 +293,13 @@ func LoginUser(service services.ApplicationService) gin.HandlerFunc {
return
}

token, err := service.GetSignedJWT(user)
salt, err := service.GetConfig("salt")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you create a constant for the "salt"?

encodedSalt := base64.StdEncoding.EncodeToString([]byte(salt))

config := authConfig.AuthConfig{
Key: "salt",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the constant here.

@@ -90,7 +95,12 @@ func (a applicationService) CreateApiToken(user *entities.User, request entities
claims["username"] = user.Username
claims["exp"] = expiresAt

tokenString, err := token.SignedString([]byte(utils.JwtSecret))
salt, err := a.GetConfig("salt")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same


func (m *MongoOperations) GetAuthConfig(ctx context.Context, key string) (*AuthConfig, error) {

authDb := MgoClient.Database("auth")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From constants?

}

func (c *Operator) GetAuthConfig(ctx context.Context) (*mongodb.AuthConfig, error) {
salt, err := c.operator.GetAuthConfig(ctx, "salt")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

constant

Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: Saranya-jena <[email protected]>
@Saranya-jena Saranya-jena merged commit 9d58d8b into litmuschaos:master Jul 5, 2024
18 of 19 checks passed
andoriyaprashant pushed a commit to andoriyaprashant/litmus that referenced this pull request Jul 6, 2024
…itmuschaos#4719)

* Added support for jwt secret creation of each user upon logic

Signed-off-by: Saranya-jena <[email protected]>

* Fixed imports

Signed-off-by: Saranya-jena <[email protected]>

* Add fixes in dex service

Signed-off-by: Saranya-jena <[email protected]>

* Fixed UTs

Signed-off-by: Saranya-jena <[email protected]>

* resolved comments

Signed-off-by: Saranya-jena <[email protected]>

* updated logic

Signed-off-by: Saranya-jena <[email protected]>

* fixed UTs and removed unecessary test cases

Signed-off-by: Saranya-jena <[email protected]>

* fixed imports

Signed-off-by: Saranya-jena <[email protected]>

* fixed imports

Signed-off-by: Saranya-jena <[email protected]>

* resolved comments

Signed-off-by: Saranya-jena <[email protected]>

* fixed imports

Signed-off-by: Saranya-jena <[email protected]>

* resolved comments

Signed-off-by: Saranya-jena <[email protected]>

* added server endpoint in allowed origins

Signed-off-by: Saranya-jena <[email protected]>

* fixed imports

Signed-off-by: Saranya-jena <[email protected]>

* minor chnages

Signed-off-by: Saranya-jena <[email protected]>

* minor chnages

Signed-off-by: Saranya-jena <[email protected]>

* fixed imports

Signed-off-by: Saranya-jena <[email protected]>

---------

Signed-off-by: Saranya-jena <[email protected]>
Signed-off-by: andoriyaprashant <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants