<commit_before>package api

import (
	"fmt"
	"net"

	"github.com/Sirupsen/logrus"
	"github.com/asaskevich/govalidator"
	"github.com/cad/ovpm"
	"github.com/cad/ovpm/permset"
	gcontext "golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

// AuthUnaryInterceptor is a interceptor function.
//
// See https://godoc.org/google.golang.org/grpc#UnaryServerInterceptor.
func AuthUnaryInterceptor(ctx gcontext.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	var enableAuthCheck bool

	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return nil, fmt.Errorf("Expected 2 metadata items in context; got %v", md)
	}

	// We enable auth check if we find a non-loopback
	// or invalid IP in the headers coming from the grpc-gateway.
	for _, userAgentIP := range md["x-forwarded-for"] {
		// Check if the remote user IP addr is a proper IP addr.
		if !govalidator.IsIP(userAgentIP) {
			enableAuthCheck = true
			logrus.Debugf("grpc request user agent ip can not be fetched from x-forwarded-for metadata, enabling auth check module '%s'", userAgentIP)
			break
		}

		// Check if the remote user IP addr is a loopback IP addr.
		if ip := net.ParseIP(userAgentIP); !ip.IsLoopback() {
			enableAuthCheck = true
			logrus.Debugf("grpc request user agent ips include non-loopback ip, enabling auth check module '%s'", userAgentIP)
			break
		}

		// TODO(cad): We assume gRPC endpoints are for cli only therefore
		//            we are listening only on looback IP.
		//
		// But if we decide use gRPC endpoints publicly, we need to add
		// extra checks against gRPC remote peer IP to test if the request
		// is coming from a remote peer IP or also from a loopback ip.
	}

	if !enableAuthCheck {
		logrus.Debugf("rpc: auth-check not enabled: %s", md["x-forwarded-for"])
		ctx = NewUsernameContext(ctx, "root")
		permissions := permset.New(ovpm.AdminPerms()...)
		ctx = permset.NewContext(ctx, permissions)
	}

	if enableAuthCheck {
		switch info.FullMethod {
		// AuthService methods
		case "/pb.AuthService/Status":
			return authRequired(ctx, req, handler)

		// UserService methods
		case "/pb.UserService/List":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Create":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Update":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Delete":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Renew":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/GenConfig":
			return authRequired(ctx, req, handler)

		// VPNService methods
		case "/pb.VPNService/Status":
			return authRequired(ctx, req, handler)
		case "/pb.VPNService/Init":
			return authRequired(ctx, req, handler)
		case "/pb.VPNService/Update":
			return authRequired(ctx, req, handler)
		case "/pb.VPNService/Restart":
			return authRequired(ctx, req, handler)

		// NetworkService methods
		case "/pb.NetworkService/Create":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/List":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/Delete":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/GetAllTypes":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/GetAssociatedUsers":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/Associate":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/Dissociate":
			return authRequired(ctx, req, handler)
		default:
			logrus.Debugln("rpc: auth is not required for this endpoint: '%s'", info.FullMethod)
		}
	}<commit_msg>doc(api): use Debugf when formatting log msg<commit_after>package api

import (
	"fmt"
	"net"

	"github.com/Sirupsen/logrus"
	"github.com/asaskevich/govalidator"
	"github.com/cad/ovpm"
	"github.com/cad/ovpm/permset"
	gcontext "golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

// AuthUnaryInterceptor is a interceptor function.
//
// See https://godoc.org/google.golang.org/grpc#UnaryServerInterceptor.
func AuthUnaryInterceptor(ctx gcontext.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	var enableAuthCheck bool

	md, ok := metadata.FromIncomingContext(ctx)
	if !ok {
		return nil, fmt.Errorf("Expected 2 metadata items in context; got %v", md)
	}

	// We enable auth check if we find a non-loopback
	// or invalid IP in the headers coming from the grpc-gateway.
	for _, userAgentIP := range md["x-forwarded-for"] {
		// Check if the remote user IP addr is a proper IP addr.
		if !govalidator.IsIP(userAgentIP) {
			enableAuthCheck = true
			logrus.Debugf("grpc request user agent ip can not be fetched from x-forwarded-for metadata, enabling auth check module '%s'", userAgentIP)
			break
		}

		// Check if the remote user IP addr is a loopback IP addr.
		if ip := net.ParseIP(userAgentIP); !ip.IsLoopback() {
			enableAuthCheck = true
			logrus.Debugf("grpc request user agent ips include non-loopback ip, enabling auth check module '%s'", userAgentIP)
			break
		}

		// TODO(cad): We assume gRPC endpoints are for cli only therefore
		//            we are listening only on looback IP.
		//
		// But if we decide use gRPC endpoints publicly, we need to add
		// extra checks against gRPC remote peer IP to test if the request
		// is coming from a remote peer IP or also from a loopback ip.
	}

	if !enableAuthCheck {
		logrus.Debugf("rpc: auth-check not enabled: %s", md["x-forwarded-for"])
		ctx = NewUsernameContext(ctx, "root")
		permissions := permset.New(ovpm.AdminPerms()...)
		ctx = permset.NewContext(ctx, permissions)
	}

	if enableAuthCheck {
		switch info.FullMethod {
		// AuthService methods
		case "/pb.AuthService/Status":
			return authRequired(ctx, req, handler)

		// UserService methods
		case "/pb.UserService/List":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Create":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Update":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Delete":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/Renew":
			return authRequired(ctx, req, handler)
		case "/pb.UserService/GenConfig":
			return authRequired(ctx, req, handler)

		// VPNService methods
		case "/pb.VPNService/Status":
			return authRequired(ctx, req, handler)
		case "/pb.VPNService/Init":
			return authRequired(ctx, req, handler)
		case "/pb.VPNService/Update":
			return authRequired(ctx, req, handler)
		case "/pb.VPNService/Restart":
			return authRequired(ctx, req, handler)

		// NetworkService methods
		case "/pb.NetworkService/Create":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/List":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/Delete":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/GetAllTypes":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/GetAssociatedUsers":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/Associate":
			return authRequired(ctx, req, handler)
		case "/pb.NetworkService/Dissociate":
			return authRequired(ctx, req, handler)
		default:
			logrus.Debugf("rpc: auth not required for endpoint: '%s'", info.FullMethod)
		}
	}
{'fraction_non_alphanumeric': 0.11775115709229513, 'fraction_numerical': 0.0002722570106180234, 'mean_word_length': 3.91438127090301, 'pattern_counts': {'":': 36, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, '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': '4500041', 'n_tokens_mistral': 2560, 'n_tokens_neox': 2347, 'n_words': 692}