<commit_before>package auth

import (
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
)

// GenerateClientToken generates client token based on project secret key and provided
// connection parameters such as user ID, timestamp and info JSON string.
func GenerateClientToken(secretKey, projectKey, user, timestamp, info string) string {
	token := hmac.New(sha256.New, []byte(secretKey))
	token.Write([]byte(projectKey))
	token.Write([]byte(user))
	token.Write([]byte(timestamp))
	token.Write([]byte(info))
	return fmt.Sprintf("%02x", token.Sum(nil))
}

// CheckClientToken validates correctness of provided (by client connection) token
// comparing it with generated one
func CheckClientToken(secretKey, projectKey, user, timestamp, info, providedToken string) bool {
	token := GenerateClientToken(secretKey, projectKey, user, timestamp, info)
	return hmac.Equal([]byte(token), []byte(providedToken))
}

// GenerateApiSign generates sign which is used to sign HTTP API requests
func GenerateApiSign(secretKey, projectKey, encodedData string) string {
	sign := hmac.New(sha256.New, []byte(secretKey))
	sign.Write([]byte(projectKey))
	sign.Write([]byte(encodedData))
	return fmt.Sprintf("%02x", sign.Sum(nil))
}

// CheckApiSign validates correctness of provided (in HTTP API request) sign
// comparing it with generated one
func CheckApiSign(secretKey, projectKey, encodedData, providedSign string) bool {
	sign := GenerateApiSign(secretKey, projectKey, encodedData)
	return hmac.Equal([]byte(sign), []byte(providedSign))
}

// GenerateChannelSign generates sign which is used to prove permission of
// client to subscribe on private channel
func GenerateChannelSign(secretKey, client, channel, channelData string) string {
	sign := hmac.New(sha256.New, []byte(secretKey))
	sign.Write([]byte(client))
	sign.Write([]byte(channel))
	sign.Write([]byte(channelData))
	return fmt.Sprintf("%02x", sign.Sum(nil))
}

// CheckChannelSign validates a correctness of provided (in subscribe client command)
// sign comparing it with generated one
func CheckChannelSign(secretKey, client, channel, channelData, providedSign string) bool {<commit_msg>check token and sign length before generating reference one<commit_after>package auth

import (
	"crypto/hmac"
	"crypto/sha256"
	"fmt"
)

// Centrifugo uses sha256 as digest algorithm for HMAC tokens and signs
// so all correct tokens must be of fixed length set by HMACLength.
const (
	HMACLength = 64
)

// GenerateClientToken generates client token based on project secret key and provided
// connection parameters such as user ID, timestamp and info JSON string.
func GenerateClientToken(secretKey, projectKey, user, timestamp, info string) string {
	token := hmac.New(sha256.New, []byte(secretKey))
	token.Write([]byte(projectKey))
	token.Write([]byte(user))
	token.Write([]byte(timestamp))
	token.Write([]byte(info))
	return fmt.Sprintf("%02x", token.Sum(nil))
}

// CheckClientToken validates correctness of provided (by client connection) token
// comparing it with generated one
func CheckClientToken(secretKey, projectKey, user, timestamp, info, providedToken string) bool {
	if len(providedToken) != HMACLength {
		return false
	}
	token := GenerateClientToken(secretKey, projectKey, user, timestamp, info)
	return hmac.Equal([]byte(token), []byte(providedToken))
}

// GenerateApiSign generates sign which is used to sign HTTP API requests
func GenerateApiSign(secretKey, projectKey, encodedData string) string {
	sign := hmac.New(sha256.New, []byte(secretKey))
	sign.Write([]byte(projectKey))
	sign.Write([]byte(encodedData))
	return fmt.Sprintf("%02x", sign.Sum(nil))
}

// CheckApiSign validates correctness of provided (in HTTP API request) sign
// comparing it with generated one
func CheckApiSign(secretKey, projectKey, encodedData, providedSign string) bool {
	if len(providedSign) != HMACLength {
		return false
	}
	sign := GenerateApiSign(secretKey, projectKey, encodedData)
	return hmac.Equal([]byte(sign), []byte(providedSign))
}

// GenerateChannelSign generates sign which is used to prove permission of
// client to subscribe on private channel
func GenerateChannelSign(secretKey, client, channel, channelData string) string {
	sign := hmac.New(sha256.New, []byte(secretKey))
	sign.Write([]byte(client))
	sign.Write([]byte(channel))
	sign.Write([]byte(channelData))
	return fmt.Sprintf("%02x", sign.Sum(nil))
}

// CheckChannelSign validates a correctness of provided (in subscribe client command)
// sign comparing it with generated one
func CheckChannelSign(secretKey, client, channel, channelData, providedSign string) bool {
	if len(providedSign) != HMACLength {
		return false
	}
{'fraction_non_alphanumeric': 0.11386672417511322, 'fraction_numerical': 0.008841923657537202, 'mean_word_length': 5.932735426008969, 'pattern_counts': {'":': 0, '<': 3, '<?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': '1330266', 'n_tokens_mistral': 1347, 'n_tokens_neox': 1299, 'n_words': 425}