<commit_before>package netboundfileenc

import (
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"math/rand"
	"sync"

	"github.com/HouzuoGuo/laitos/datastruct"
	"github.com/HouzuoGuo/laitos/lalog"
	"github.com/HouzuoGuo/laitos/misc"
	"github.com/HouzuoGuo/laitos/netboundfileenc/unlocksvc"
	"google.golang.org/grpc/peer"
)

const (
	// MaxRandomChallengeLen is the maximum length accepted for a client-generated random challenge string.
	MaxRandomChallengeLen = 64
)

// GetRandomChallenge returns a randomly generated string that an RPC client may use as challenge string to identify its intent.
// The function uses the default PRNG source internally.
func GetRandomChallenge() string {
	buf := make([]byte, 16)
	_, err := rand.Read(buf)
	if err != nil {
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(buf)
}

// getRPCClientIP returns the string representation of the client IP address that made a gRPC request.
// If the IP cannot be determined, the function will return an empty string.
func getRPCClientIP(ctx context.Context) string {
	peerInfo, ok := peer.FromContext(ctx)
	if ok {
		return peerInfo.Addr.String()
	}
	return ""
}

// UnlockAttemptRPCClientInfo contains the identification information from an unlocking request along with network transport information about the client.
type UnlockAttemptRPCClientInfo struct {
	*unlocksvc.UnlockAttemptIdentification
	ClientIP string
}

// PasswordRegister provides facilities for an instance of laitos program to register an intent of obtaining unlocking password
// for its config/data files, and then obtain the password after a user has honoured the intent.
type PasswordRegister struct {
	unlocksvc.UnimplementedPasswordUnlockServiceServer
	// IntentsChallenge record the random string challenge generated by the client. They reside in an in-memory buffer, hence the capacity is
	// sufficient for a limited number of entries.
	// The identification of these challenge strings are stored in IntentIdentifications and kept in-sync.<commit_msg>correctly extract client IP address from gRPC peer information<commit_after>package netboundfileenc

import (
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"math/rand"
	"net"
	"sync"

	"github.com/HouzuoGuo/laitos/datastruct"
	"github.com/HouzuoGuo/laitos/lalog"
	"github.com/HouzuoGuo/laitos/misc"
	"github.com/HouzuoGuo/laitos/netboundfileenc/unlocksvc"
	"google.golang.org/grpc/peer"
)

const (
	// MaxRandomChallengeLen is the maximum length accepted for a client-generated random challenge string.
	MaxRandomChallengeLen = 64
)

// GetRandomChallenge returns a randomly generated string that an RPC client may use as challenge string to identify its intent.
// The function uses the default PRNG source internally.
func GetRandomChallenge() string {
	buf := make([]byte, 16)
	_, err := rand.Read(buf)
	if err != nil {
		panic(err)
	}
	return base64.StdEncoding.EncodeToString(buf)
}

// getRPCClientIP returns the string representation of the client IP address that made a gRPC request.
// If the IP cannot be determined, the function will return an empty string.
func getRPCClientIP(ctx context.Context) string {
	peerInfo, ok := peer.FromContext(ctx)
	if ok {
		if tcpAddr, ok := peerInfo.Addr.(*net.TCPAddr); ok {
			return tcpAddr.IP.String()
		}
	}
	return ""
}

// UnlockAttemptRPCClientInfo contains the identification information from an unlocking request along with network transport information about the client.
type UnlockAttemptRPCClientInfo struct {
	*unlocksvc.UnlockAttemptIdentification
	ClientIP string
}

// PasswordRegister provides facilities for an instance of laitos program to register an intent of obtaining unlocking password
// for its config/data files, and then obtain the password after a user has honoured the intent.
type PasswordRegister struct {
	unlocksvc.UnimplementedPasswordUnlockServiceServer
	// IntentsChallenge record the random string challenge generated by the client. They reside in an in-memory buffer, hence the capacity is
	// sufficient for a limited number of entries.
	// The identification of these challenge strings are stored in IntentIdentifications and kept in-sync.
{'fraction_non_alphanumeric': 0.07285886610373944, 'fraction_numerical': 0.0038600723763570566, 'mean_word_length': 4.718620689655173, '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': '345898', 'n_tokens_mistral': 1230, 'n_tokens_neox': 1180, 'n_words': 435}