Skip to content

Commit

Permalink
implement reset-user-mfa
Browse files Browse the repository at this point in the history
  • Loading branch information
duaraghav8 committed Oct 16, 2019
1 parent 45996f2 commit 60141e0
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 9 deletions.
108 changes: 101 additions & 7 deletions command/reset_user_multifactor.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,109 @@
package command

type ResetUserMultifactorCommand struct {}
import (
"context"
"fmt"
"github.com/duaraghav8/okta-admin/common"
oktaapi "github.com/duaraghav8/okta-admin/okta"
"github.com/okta/okta-sdk-golang/okta"
"net/http"
)

func (c *ResetUserMultifactorCommand) Help() string {
return ""
type ResetUserMultifactorsCommand struct {
Meta *common.CommandMetadata
}

func (c *ResetUserMultifactorCommand) Run(args []string) int {
return 0
type ResetUserMultifactorsCommandConfig struct {
EmailID string
}

func (c *ResetUserMultifactorsCommand) Synopsis() string {
return "Reset all Multifactors of an organization member"
}

func (c *ResetUserMultifactorCommand) Synopsis() string {
return "Reset organization member's Multifactor"
func (c *ResetUserMultifactorsCommand) Help() string {
helpText := `
Usage: okta-admin reset-user-mfa [options]
Resets all Multifactors of an organization member.
Okta doesn't notify the user of this reset explicity,
but rather lets them setup their Multifactors when they
log into the domain post MFA reset.
{{.GlobalOptionsHelpText}}
Options:
-email Email ID of the organization member
`

res, err := common.PrepareMessage(
helpText,
map[string]interface{}{
"GlobalOptionsHelpText": c.Meta.GlobalOptionsHelpText,
},
)
if err != nil {
return fmt.Sprintf("Failed to render help message: %v\n", err)
}
return res
}

func (c *ResetUserMultifactorsCommand) ParseArgs(args []string) (*ResetUserMultifactorsCommandConfig, error) {
var cfg ResetUserMultifactorsCommandConfig

flags := c.Meta.FlagSet
flags.StringVar(&cfg.EmailID, "email", "", "")

if err := flags.Parse(args); err != nil {
return &cfg, err
}
return &cfg, common.RequiredArgs(map[string]string{
"email": cfg.EmailID,
"org url": c.Meta.GlobalOptions.OrgUrl,
"api token": c.Meta.GlobalOptions.ApiToken,
})
}

func (c *ResetUserMultifactorsCommand) Run(args []string) int {
cfg, err := c.ParseArgs(args)
if err != nil {
fmt.Printf("Failed to parse arguments: %v\n", err)
return 1
}

client, err := okta.NewClient(
context.Background(),
okta.WithOrgUrl(c.Meta.GlobalOptions.OrgUrl),
okta.WithToken(c.Meta.GlobalOptions.ApiToken),
)
if err != nil {
fmt.Printf("Failed to initialize Okta client: %v\n", err)
return 1
}

// Fetch user ID
user, _, err := oktaapi.GetUserByEmail(
&oktaapi.Credentials{
OrgUrl: c.Meta.GlobalOptions.OrgUrl,
ApiToken: c.Meta.GlobalOptions.ApiToken,
},
cfg.EmailID,
)
if err != nil {
fmt.Printf("Failed to resolve user ID: %v\n", err)
return 1
}

// Reset all Multifactors
resp, err := client.User.ResetAllFactors(user["id"].(string))
if err != nil {
fmt.Printf("Failed to reset member's multifactors: %v\n", err)
return 1
}
if resp.StatusCode != http.StatusOK {
fmt.Printf("Failed to reset member's multifactors: %v\n", resp)
return 1
}

fmt.Printf("All multifactors for %s have been reset\n", cfg.EmailID)
return 0
}
49 changes: 49 additions & 0 deletions command/reset_user_multifactor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package command

import (
"flag"
"github.com/duaraghav8/okta-admin/common"
"strings"
"testing"
)

func createTestResetUserMultifactorsCommand(globalOptsHelpText string) *ResetUserMultifactorsCommand {
m := &common.CommandMetadata{
GlobalOptionsHelpText: globalOptsHelpText,
GlobalOptions: &common.CommandConfig{
OrgUrl: "https://foo.okta.com/",
ApiToken: "123abc",
},
FlagSet: flag.NewFlagSet("test_reset_user_mfa_cmd", flag.ContinueOnError),
}
return &ResetUserMultifactorsCommand{Meta: m}
}

func TestResetUserMultifactorsCommand_Help(t *testing.T) {
t.Parallel()
const globalHelpMsg = `
Welcome to Hogwarts!
`
c := createTestResetUserMultifactorsCommand(globalHelpMsg)
if !strings.Contains(c.Help(), globalHelpMsg) {
t.Errorf("Expected final help message to contain \"%s\"", globalHelpMsg)
}
}

func TestResetUserMultifactorsCommand_ParseArgs(t *testing.T) {
t.Parallel()

c := createTestDeactivateUserCommand("")
args := []string{
"-email", "[email protected]",
}

cfg, err := c.ParseArgs(args)
if err != nil {
t.Fatalf("Failed to parse arguments: %v", err)
}

if cfg.EmailID != args[1] {
t.Errorf("Expected email id to be %s, received %s", args[1], cfg.EmailID)
}
}
6 changes: 4 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ func main() {
"assign-applications": func() (command cli.Command, err error) {
return &cmd.AssignApplicationsCommand{}, nil
},
"reset-user-multifactor": func() (command cli.Command, err error) {
return &cmd.ResetUserMultifactorCommand{}, nil
"reset-user-mfa": func() (command cli.Command, err error) {
return &cmd.ResetUserMultifactorsCommand{
Meta: meta,
}, nil
},
},
Args: os.Args[1:],
Expand Down

0 comments on commit 60141e0

Please sign in to comment.