As we reevaluate how to best support and maintain Staging Ref in the future, we encourage development teams using this environment to highlight their use cases in the following issue: https://gitlab.com/gitlab-com/gl-infra/software-delivery/framework/software-delivery-framework-issue-tracker/-/issues/36.

Skip to content
Snippets Groups Projects

Passing pushauth flag as bool in json body to internal api doesn't become a...

Open Manoj Memana Jayakumar requested to merge mmj/gitlab-shell:506-jsandlin into main
2 files
+ 212
39
Compare changes
  • Side-by-side
  • Inline
Files
2
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
"sync"
"time"
"gitlab.com/gitlab-org/labkit/log"
@@ -27,7 +28,13 @@ type Result struct {
Success bool
}
func (c *Command) Execute(ctx context.Context) error {
var (
mu sync.RWMutex
// TODO: make timeout configurable
ctxMaxTime = time.Second + 30
)
func (c *Command) Execute1(ctx context.Context) error {
ctxlog := log.ContextLogger(ctx)
// config.GetHTTPClient isn't thread-safe so save Client in struct for concurrency
@@ -44,49 +51,71 @@ func (c *Command) Execute(ctx context.Context) error {
// TODO: make timeout configurable
const ctxTimeout = 30
timeoutCtx, cancelTimeout := context.WithTimeout(ctx, ctxTimeout*time.Second)
verifyCtx, cancelVerify := context.WithCancel(timeoutCtx)
pushCtx, cancelPush := context.WithCancel(timeoutCtx)
defer cancelTimeout()
// Create result channel
resultC := make(chan Result)
// Background push notification with timeout
pushauth := make(chan Result)
go func() {
defer close(resultC)
status, success, err := c.pushAuth(timeoutCtx)
defer close(pushauth)
status, success, err := c.pushAuth(pushCtx)
select {
case <-timeoutCtx.Done(): // push cancelled by manual OTP
resultC <- Result{Error: nil, Status: "cancelled", Success: false}
case <-pushCtx.Done(): // push cancelled by manual OTP
pushauth <- Result{Error: nil, Status: "cancelled", Success: false}
default:
resultC <- Result{Error: err, Status: status, Success: success}
cancelTimeout()
pushauth <- Result{Error: err, Status: status, Success: success}
cancelVerify()
}
}()
// Also allow manual OTP entry while waiting for push, with same timeout as push
verify := make(chan Result)
go func() {
defer close(resultC)
defer close(verify)
ctxlog.Info("twofactorverify: execute: waiting for user input")
answer := ""
answer = c.getOTP(timeoutCtx)
answer = c.getOTP(verifyCtx)
select {
case <-timeoutCtx.Done(): // manual OTP cancelled by push
resultC <- Result{Error: nil, Status: "cancelled", Success: false}
case <-verifyCtx.Done(): // manual OTP cancelled by push
verify <- Result{Error: nil, Status: "cancelled", Success: false}
default:
cancelTimeout()
cancelPush()
ctxlog.Info("twofactorverify: execute: verifying entered OTP")
status, success, err := c.verifyOTP(timeoutCtx, answer)
status, success, err := c.verifyOTP(verifyCtx, answer)
fmt.Println("-------------")
fmt.Println("pushAuth.status = ", status)
fmt.Println("pushAuth.success = ", success)
fmt.Println("pushAuth.err = ", err)
fmt.Println("-------------")
ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified")
resultC <- Result{Error: err, Status: status, Success: success}
verify <- Result{Error: err, Status: status, Success: success}
}
}()
for {
select {
case res := <-resultC:
case res := <-verify: // manual OTP
fmt.Println("-------------")
fmt.Println("verify.res = ", res)
fmt.Println("-------------")
if res.Status == "cancelled" {
// request cancelled; don't print anything
// verify cancelled; don't print anything
} else if res.Status == "" {
// channel closed; don't print anything
} else {
fmt.Fprint(c.ReadWriter.Out, res.Status)
return nil
}
case res := <-pushauth: // push
fmt.Println("-------------")
fmt.Println("pushauth.res = ", res)
fmt.Println("-------------")
if res.Status == "cancelled" {
// push cancelled; don't print anything
} else if res.Status == "" {
// channel closed; don't print anything
} else {
@@ -101,6 +130,70 @@ func (c *Command) Execute(ctx context.Context) error {
return nil
}
func (c *Command) Execute(ctx context.Context) error {
ctxlog := log.ContextLogger(ctx)
// config.GetHTTPClient isn't thread-safe so save Client in struct for concurrency
// workaround until #518 is fixed
var err error
c.Client, err = twofactorverify.NewClient(c.Config)
if err != nil {
ctxlog.WithError(err).Error("twofactorverify: execute: OTP verification failed")
return err
}
// Create timeout context
// TODO: make timeout configurable
const ctxTimeout = 30
myctx, mycancel := context.WithCancel(ctx)
defer mycancel()
//defer cancelTimeout()
//
//// Create result channel
//resultC := make(chan Result)
c.processCmd(myctx, mycancel)
//
for {
fmt.Println("for")
fmt.Println(myctx)
select {
case <- myctx.Done():
fmt.Println("myctx.Done")
//case resPush := <-pushAuth.D:
// fmt.Println("resPush => ", resPush.Status)
// //if resPush.Status == "cancelled" {
// // // request cancelled; don't print anything
// //} else if resPush.Status == "" {
// // // channel closed; don't print anything
// //} else {
// // fmt.Fprint(c.ReadWriter.Out, resPush.Status)
// // return nil
// //}
//case resOtp := <-otpAuth:
// fmt.Println("otpAuth => ", resOtp)
// //if resOtp.Status == "cancelled" {
// // // request cancelled; don't print anything
// //} else if resOtp.Status == "" {
// // // channel closed; don't print anything
// //} else {
// // fmt.Fprint(c.ReadWriter.Out, resOtp.Status)
// // return nil
// //}
case <-myctx.Done(): // push timed out
fmt.Fprint(c.ReadWriter.Out, "\nOTP verification timed out\n")
return nil
default:
fmt.Println("myctx == ", myctx)
}
}
return nil
}
func (c *Command) getOTP(ctx context.Context) string {
prompt := "OTP: "
@@ -116,9 +209,84 @@ func (c *Command) getOTP(ctx context.Context) string {
return answer
}
func (c *Command) processCmd(ctx context.Context, cancelTimeout context.CancelFunc) (status string, success bool, err error) {
ctxlog := log.ContextLogger(ctx)
// Background push notification with timeout
pushAuth := make(chan Result)
go func() {
defer close(pushAuth)
status, success, err := c.pushAuth(ctx)
fmt.Println("-------------")
fmt.Println("pushAuth.status = ", status)
fmt.Println("pushAuth.success = ", success)
fmt.Println("pushAuth.err = ", err)
fmt.Println("-------------")
select {
case <-ctx.Done(): // push cancelled by manual OTP
fmt.Println("pushAuth.func.timeoutCtx.Done()")
pushAuth <- Result{Error: nil, Status: "cancelled", Success: false}
default:
fmt.Println("pushAuth.func.default")
pushAuth <- Result{Error: err, Status: status, Success: success}
cancelTimeout()
}
}()
// Also allow manual OTP entry while waiting for push, with same timeout as push
otpAuth := make(chan Result)
go func() {
defer close(otpAuth)
fmt.Println("twofactorverify: execute: waiting for user input")
otpAnswer := c.getOTP(ctx)
fmt.Println("otpAnswer = ", otpAnswer)
select {
case <-ctx.Done(): // manual OTP cancelled by push
fmt.Println("otpAuth.func.timeoutCtx.Done()")
otpAuth <- Result{Error: nil, Status: "cancelled", Success: false}
default:
fmt.Println("otpAuth.func.timeoutCtx.default")
cancelTimeout()
fmt.Println("twofactorverify: execute: verifying entered OTP")
status, success, err := c.verifyOTP(ctx, otpAnswer)
ctxlog.WithError(err).Info("twofactorverify: execute: OTP verified")
otpAuth <- Result{Error: err, Status: status, Success: success}
}
}()
for {
select {
case pres := <- pushAuth:
fmt.Println("-------------")
fmt.Println("pushAuth = ", pres)
fmt.Println("-------------")
if len(pres.Status) > 0 {
fmt.Println("-------------")
fmt.Println("pushAuth = ", pres.Status)
fmt.Println("-------------")
}
case ores := <- otpAuth:
fmt.Println("-------------")
fmt.Println("otpAuth = ", ores)
fmt.Println("-------------")
if len(ores.Status) > 0 {
fmt.Println("-------------")
fmt.Println("otpAuth = ", ores.Status)
fmt.Println("-------------")
}
}
}
return
}
func (c *Command) verifyOTP(ctx context.Context, otp string) (status string, success bool, err error) {
reason := ""
fmt.Println("verifyOTP(ctx, ",otp,")")
success, reason, err = c.Client.VerifyOTP(ctx, c.Args, otp)
if success {
status = fmt.Sprintf("\nOTP validation successful. Git operations are now allowed.\n")
@@ -136,9 +304,14 @@ func (c *Command) verifyOTP(ctx context.Context, otp string) (status string, suc
}
func (c *Command) pushAuth(ctx context.Context) (status string, success bool, err error) {
fmt.Println("---------------------------------------")
reason := ""
fmt.Println(c.Args)
success, reason, err = c.Client.PushAuth(ctx, c.Args)
fmt.Println("pushAuth.reason = ", reason)
fmt.Println("pushAuth.success = ", success)
fmt.Println("pushAuth.err = ", err)
fmt.Println("---------------------------------------")
if success {
status = fmt.Sprintf("\nPush OTP validation successful. Git operations are now allowed.\n")
} else {
Loading