Skip to content

Commit 5eb7134

Browse files
feat: 2FA totp integration (#729) (#734)
(cherry picked from commit f2858e4) Co-authored-by: Tanmoy Sarkar <[email protected]>
1 parent eb10694 commit 5eb7134

16 files changed

+659
-16
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ require (
2323
github.com/spf13/cobra v1.8.0
2424
github.com/testcontainers/testcontainers-go v0.31.0
2525
github.com/vektah/gqlparser/v2 v2.5.12
26+
github.com/xlzd/gotp v0.1.0
2627
golang.org/x/term v0.21.0
2728
gopkg.in/yaml.v3 v3.0.1
2829
gorm.io/driver/postgres v1.5.7

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ github.com/vektah/gqlparser/v2 v2.5.12 h1:COMhVVnql6RoaF7+aTBWiTADdpLGyZWU3K/NwW
325325
github.com/vektah/gqlparser/v2 v2.5.12/go.mod h1:WQQjFc+I1YIzoPvZBhUQX7waZgg3pMLi0r8KymvAE2w=
326326
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
327327
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
328+
github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
329+
github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
328330
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
329331
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
330332
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=

swiftwave_service/cmd/user.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import (
1414
func init() {
1515
userManagementCmd.AddCommand(createUserCmd)
1616
userManagementCmd.AddCommand(deleteUserCmd)
17+
userManagementCmd.AddCommand(disableTotpCmd)
1718
createUserCmd.Flags().StringP("username", "u", "", "Username")
1819
createUserCmd.Flags().StringP("password", "p", "", "Password [Optional]")
1920
deleteUserCmd.Flags().StringP("username", "u", "", "Username")
21+
disableTotpCmd.Flags().StringP("username", "u", "", "Username")
2022
}
2123

2224
var userManagementCmd = &cobra.Command{
@@ -136,3 +138,34 @@ var deleteUserCmd = &cobra.Command{
136138
printSuccess("Deleted user > " + username)
137139
},
138140
}
141+
142+
var disableTotpCmd = &cobra.Command{
143+
Use: "disable-totp",
144+
Short: "Disable Totp for a user",
145+
Long: "Disable Totp for a user",
146+
Run: func(cmd *cobra.Command, args []string) {
147+
username := cmd.Flag("username").Value.String()
148+
if username == "" {
149+
printError("Username is required")
150+
err := cmd.Help()
151+
if err != nil {
152+
return
153+
}
154+
return
155+
}
156+
// Initiating database client
157+
dbClient, err := db.GetClient(config.LocalConfig, 10)
158+
if err != nil {
159+
printError("Failed to connect to database")
160+
return
161+
}
162+
// Disable Totp
163+
err = core.DisableTotp(context.Background(), *dbClient, username)
164+
if err != nil {
165+
printError("Failed to disable Totp")
166+
printError("Reason: " + err.Error())
167+
return
168+
}
169+
printSuccess("Disabled Totp for user > " + username)
170+
},
171+
}

swiftwave_service/core/models.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ type User struct {
4141
Username string `json:"username" gorm:"unique"`
4242
Role UserRole `json:"role" gorm:"default:'user'"`
4343
PasswordHash string `json:"password_hash"`
44+
TotpEnabled bool `json:"totp_enabled" gorm:"default:false"`
45+
TotpSecret string `json:"totp_secret"`
4446
}
4547

4648
// ************************************************************************************* //

swiftwave_service/core/user.operations.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,15 @@ func ChangePassword(ctx context.Context, db gorm.DB, username string, oldPasswor
7676
err = db.Save(&user).Error
7777
return err
7878
}
79+
80+
// DisableTotp : disable Totp for user
81+
func DisableTotp(ctx context.Context, db gorm.DB, username string) error {
82+
user, err := FindUserByUsername(ctx, db, username)
83+
if err != nil {
84+
return errors.New("user not found")
85+
}
86+
// disable TOTP
87+
user.TotpEnabled = false
88+
err = db.Save(&user).Error
89+
return err
90+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- reverse: modify "users" table
2+
ALTER TABLE "public"."users" DROP COLUMN "totp_secret", DROP COLUMN "totp_enabled";
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- modify "users" table
2+
ALTER TABLE "public"."users" ADD COLUMN "totp_enabled" boolean NULL DEFAULT false, ADD COLUMN "totp_secret" text NULL;

swiftwave_service/db/migrations/atlas.sum

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
h1:ats7Dhdc37WkTpGvkMFA0GlEzBlFmXB3EBwYk6vd+c8=
1+
h1:MRdojbnoeAO6RPVZNvsQv+HbTbJc1JqIOUkC+XRGPDo=
22
20240413191732_init.down.sql h1:HoitObGwuKF/akF4qg3dol2FfNTLCEuf6wHYDuCez8I=
33
20240413191732_init.up.sql h1:USKdQx/yTz1KJ0+mDwYGhKm3WzX7k+I9+6B6SxImwaE=
44
20240414051823_server_custom_ssh_port_added.down.sql h1:IC1DFQBQceTPTRdZOo5/WqytH+ZbgcKrQuMCkhArF/0=
@@ -23,3 +23,5 @@ h1:ats7Dhdc37WkTpGvkMFA0GlEzBlFmXB3EBwYk6vd+c8=
2323
20240602144400_add_application_resource_limit_and_reserve.up.sql h1:Qs5+63C2xrVKbRjDAQ+/Aw0x9JVj7c0Msli1Fv5c48Q=
2424
20240603064438_add_uid_gid_in_cifs_pv.down.sql h1:EVlD++5wMSaSGQA4gPMyZiBaOjVvm/QURa1t4RwdIwQ=
2525
20240603064438_add_uid_gid_in_cifs_pv.up.sql h1:eJqHJ0QQxzz21//f3iU9hvVavHxbPoUrKPGt914/0Ik=
26+
20240606063101_add_totp_support.down.sql h1:PaklVxao4OkfGMxp0x2AOeUBtZcVuY3aDl9BmQWOJE0=
27+
20240606063101_add_totp_support.up.sql h1:Ty6yz+Qd1xOMXMtYMDQAu8bJtBiqoG3B54djDinX4hE=

0 commit comments

Comments
 (0)