go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/server/auth/authdb/internal/seccfg/seccfg.go (about)

     1  // Copyright 2019 The LUCI Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Package seccfg interprets SecurityConfig proto message.
    16  package seccfg
    17  
    18  import (
    19  	"regexp"
    20  	"strings"
    21  
    22  	"google.golang.org/protobuf/proto"
    23  
    24  	"go.chromium.org/luci/common/errors"
    25  
    26  	"go.chromium.org/luci/server/auth/service/protocol"
    27  )
    28  
    29  // SecurityConfig is parsed queryable form of SecurityConfig proto message.
    30  type SecurityConfig struct {
    31  	internalServices *regexp.Regexp // may be nil
    32  }
    33  
    34  // Parse parses serialized SecurityConfig proto message.
    35  func Parse(blob []byte) (*SecurityConfig, error) {
    36  	// Empty config is allowed.
    37  	if len(blob) == 0 {
    38  		return &SecurityConfig{}, nil
    39  	}
    40  
    41  	msg := protocol.SecurityConfig{}
    42  	if err := proto.Unmarshal(blob, &msg); err != nil {
    43  		return nil, errors.Annotate(err, "failed to deserialize SecurityConfig").Err()
    44  	}
    45  
    46  	secCfg := &SecurityConfig{}
    47  
    48  	// Assemble a single regexp from a bunch of 'internal_service_regexp'.
    49  	if len(msg.InternalServiceRegexp) > 0 {
    50  		b := strings.Builder{}
    51  		b.WriteString("^(")
    52  		for idx, re := range msg.InternalServiceRegexp {
    53  			if idx != 0 {
    54  				b.WriteRune('|')
    55  			}
    56  			b.WriteRune('(')
    57  			b.WriteString(re)
    58  			b.WriteRune(')')
    59  		}
    60  		b.WriteString(")$")
    61  
    62  		var err error
    63  		if secCfg.internalServices, err = regexp.Compile(b.String()); err != nil {
    64  			return nil, errors.Annotate(err, "failed to compile internal_service_regexp").Err()
    65  		}
    66  	}
    67  
    68  	return secCfg, nil
    69  }
    70  
    71  // IsInternalService returns true if the given hostname belongs to a service
    72  // that is a part of the current LUCI deployment.
    73  func (cfg *SecurityConfig) IsInternalService(hostname string) bool {
    74  	if cfg.internalServices == nil {
    75  		return false
    76  	}
    77  	return cfg.internalServices.MatchString(hostname)
    78  }