<commit_before>package jwt

import (
	"errors"
	"net/http"
	"time"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/hellofresh/janus/pkg/request"
	"github.com/hellofresh/janus/pkg/response"
)

// Handler struct
type Handler struct {
	Config Config
}

// Login form structure.
type Login struct {
	Username string `form:"username" json:"username" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

// Login can be used by clients to get a jwt token.
// Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}.
// Reply will be of the form {"token": "TOKEN"}.
func (j *Handler) Login() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var loginVals Login

		if request.BindJSON(r, &loginVals) != nil {
			j.Config.Unauthorized(w, r, errors.New("missing username or password"))
			return
		}

		userID, ok := j.Config.Authenticator(loginVals.Username, loginVals.Password)

		if !ok {
			j.Config.Unauthorized(w, r, errors.New("invalid username or password"))
			return
		}

		// Create the token
		token := jwt.New(jwt.GetSigningMethod(j.Config.SigningAlgorithm))
		claims := token.Claims.(jwt.MapClaims)

		if userID == "" {
			userID = loginVals.Username
		}

		if 0 == j.Config.Timeout {
			j.Config.Timeout = time.Hour
		}

		expire := time.Now().Add(j.Config.Timeout)
		claims["id"] = userID
		claims["exp"] = expire.Unix()
		claims["iat"] = time.Now().Unix()

		tokenString, err := token.SignedString(j.Config.Secret)

		if err != nil {
			j.Config.Unauthorized(w, r, errors.New("problem signing JWT"))
			return
		}

		response.JSON(w, http.StatusOK, response.H{
			"token":  tokenString,
			"expire": expire.Format(time.RFC3339),
		})
	}
}

func (j *Handler) Refresh() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		parser := Parser{j.Config}
		token, _ := parser.Parse(r)
		claims := token.Claims.(jwt.MapClaims)

		origIat := int64(claims["iat"].(float64))

		if origIat < time.Now().Add(-j.Config.MaxRefresh).Unix() {
			j.Config.Unauthorized(w, r, errors.New("token is expired"))
			return
		}

		// Create the token
		newToken := jwt.New(jwt.GetSigningMethod(j.Config.SigningAlgorithm))
		newClaims := newToken.Claims.(jwt.MapClaims)

		for key := range claims {
			newClaims[key] = claims[key]
		}

		expire := time.Now().Add(j.Config.Timeout)
		newClaims["id"] = claims["id"]
		newClaims["exp"] = expire.Unix()
		newClaims["orig_iat"] = origIat
<commit_msg>Fixed wrong key<commit_after>package jwt

import (
	"errors"
	"net/http"
	"time"

	jwt "github.com/dgrijalva/jwt-go"
	"github.com/hellofresh/janus/pkg/request"
	"github.com/hellofresh/janus/pkg/response"
)

// Handler struct
type Handler struct {
	Config Config
}

// Login form structure.
type Login struct {
	Username string `form:"username" json:"username" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

// Login can be used by clients to get a jwt token.
// Payload needs to be json in the form of {"username": "USERNAME", "password": "PASSWORD"}.
// Reply will be of the form {"token": "TOKEN"}.
func (j *Handler) Login() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var loginVals Login

		if request.BindJSON(r, &loginVals) != nil {
			j.Config.Unauthorized(w, r, errors.New("missing username or password"))
			return
		}

		userID, ok := j.Config.Authenticator(loginVals.Username, loginVals.Password)

		if !ok {
			j.Config.Unauthorized(w, r, errors.New("invalid username or password"))
			return
		}

		// Create the token
		token := jwt.New(jwt.GetSigningMethod(j.Config.SigningAlgorithm))
		claims := token.Claims.(jwt.MapClaims)

		if userID == "" {
			userID = loginVals.Username
		}

		if 0 == j.Config.Timeout {
			j.Config.Timeout = time.Hour
		}

		expire := time.Now().Add(j.Config.Timeout)
		claims["id"] = userID
		claims["exp"] = expire.Unix()
		claims["iat"] = time.Now().Unix()

		tokenString, err := token.SignedString(j.Config.Secret)

		if err != nil {
			j.Config.Unauthorized(w, r, errors.New("problem signing JWT"))
			return
		}

		response.JSON(w, http.StatusOK, response.H{
			"token":  tokenString,
			"expire": expire.Format(time.RFC3339),
		})
	}
}

func (j *Handler) Refresh() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		parser := Parser{j.Config}
		token, _ := parser.Parse(r)
		claims := token.Claims.(jwt.MapClaims)

		origIat := int64(claims["iat"].(float64))

		if origIat < time.Now().Add(-j.Config.MaxRefresh).Unix() {
			j.Config.Unauthorized(w, r, errors.New("token is expired"))
			return
		}

		// Create the token
		newToken := jwt.New(jwt.GetSigningMethod(j.Config.SigningAlgorithm))
		newClaims := newToken.Claims.(jwt.MapClaims)

		for key := range claims {
			newClaims[key] = claims[key]
		}

		expire := time.Now().Add(j.Config.Timeout)
		newClaims["id"] = claims["id"]
		newClaims["exp"] = expire.Unix()
		newClaims["iat"] = origIat

{'fraction_non_alphanumeric': 0.15849509705823495, 'fraction_numerical': 0.003602161296778067, 'mean_word_length': 3.8760975609756096, 'pattern_counts': {'":': 10, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '873094', 'n_tokens_mistral': 1965, 'n_tokens_neox': 1764, 'n_words': 388}