...

Source file src/edge-infra.dev/pkg/edge/iam/pin/pin_save.go

Documentation: edge-infra.dev/pkg/edge/iam/pin

     1  package pin
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/gin-gonic/gin"
     9  	"github.com/google/uuid"
    10  
    11  	"edge-infra.dev/pkg/edge/iam/apperror"
    12  	iamErrors "edge-infra.dev/pkg/edge/iam/errors"
    13  	"edge-infra.dev/pkg/edge/iam/log"
    14  	"edge-infra.dev/pkg/edge/iam/util"
    15  )
    16  
    17  type saveRequest struct {
    18  	//Username   string `json:"username"`
    19  	Pin        string `json:"pin" binding:"required,len=6"`
    20  	ConfirmPIN string `json:"pin_confirm" binding:"required,len=6"`
    21  	Action     string `json:"action"`
    22  }
    23  
    24  func (pin *PIN) savePIN(c *gin.Context) error {
    25  	logger := log.Get(c.Request.Context()).WithName("save-pin")
    26  
    27  	req := c.Request
    28  	var reqBody saveRequest
    29  	if err := c.BindJSON(&reqBody); err != nil {
    30  		pin.metrics.IncSignUpRequestsTotal(signUpPin, util.Failed)
    31  		return apperror.NewAbortError(
    32  			fmt.Errorf("invalid save pin request body: %w", err),
    33  			http.StatusBadRequest)
    34  	}
    35  	err := req.ParseForm()
    36  	if err != nil {
    37  		return apperror.NewAbortError(
    38  			fmt.Errorf("failed to parse save pin request: %w", err),
    39  			http.StatusBadRequest)
    40  	}
    41  
    42  	session, _ := pin.sessionStore.Get(c.Request, "oauth2")
    43  	if session.Values["method"] != "federated" {
    44  		err := errors.New("no cloud login found in session. need strong auth to set PIN")
    45  		return apperror.NewAbortError(err, http.StatusForbidden)
    46  	}
    47  	sub, ok := session.Values["sub"]
    48  	if !ok {
    49  		err := errors.New("invalid session. could not find subject in the cookie session")
    50  		return apperror.NewAbortError(err, http.StatusUnauthorized)
    51  	}
    52  
    53  	subject := sub.(string)
    54  
    55  	switch reqBody.Action {
    56  	case "save":
    57  		// client already made sure that pin and confirmPin are the same...
    58  		err = pin.storage.SavePIN(c.Request.Context(), subject, reqBody.Pin)
    59  		if err != nil {
    60  			if err == iamErrors.ErrPINPreviouslyUsed {
    61  				return apperror.NewStatusError(err, http.StatusUnprocessableEntity)
    62  			}
    63  
    64  			return apperror.NewAbortError(
    65  				fmt.Errorf("failed to save pin: %w", err),
    66  				http.StatusInternalServerError)
    67  		}
    68  	case "cancel":
    69  		logger.Info(fmt.Sprintf("[%v] - 'cancel' action received, pin not set.", util.ShortOperationID(c.Request.Context())))
    70  	}
    71  
    72  	// save new continuation to the session
    73  	continuation := uuid.New().String()
    74  	session.Values["continuation"] = continuation
    75  
    76  	//remove reason from session
    77  	delete(session.Values, "reason")
    78  
    79  	err = session.Save(c.Request, c.Writer)
    80  	if err != nil {
    81  		return apperror.NewAbortError(
    82  			fmt.Errorf("failed to save cookie session: %w", err),
    83  			http.StatusInternalServerError)
    84  	}
    85  
    86  	pin.metrics.IncSignUpRequestsTotal(signUpPin, util.Succeeded)
    87  
    88  	return util.WriteJSON(c.Writer, http.StatusOK, gin.H{
    89  		"challenge": continuation,
    90  	})
    91  }
    92  

View as plain text