github.com/BarDweller/libpak@v0.0.0-20230630201634-8dd5cfc15ec9/carton/netrc.go (about)

     1  /*
     2   * Copyright 2018-2020 the original author or authors.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *      https://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package carton
    18  
    19  import (
    20  	"fmt"
    21  	"net/http"
    22  	"os"
    23  	"os/user"
    24  	"path/filepath"
    25  	"strings"
    26  )
    27  
    28  type Netrc []NetrcLine
    29  
    30  type NetrcLine struct {
    31  	Machine  string
    32  	Login    string
    33  	Password string
    34  }
    35  
    36  func (n Netrc) BasicAuth(request *http.Request) (*http.Request, error) {
    37  	for _, l := range n {
    38  		if l.Machine != request.Host && l.Machine != "default" {
    39  			continue
    40  		}
    41  
    42  		request.SetBasicAuth(l.Login, l.Password)
    43  		break
    44  	}
    45  
    46  	return request, nil
    47  }
    48  
    49  func ParseNetrc(path string) (Netrc, error) {
    50  	b, err := os.ReadFile(path)
    51  	if os.IsNotExist(err) {
    52  		return nil, nil
    53  	} else if err != nil {
    54  		return nil, fmt.Errorf("unable to open %s\n%w", path, err)
    55  	}
    56  
    57  	var (
    58  		n Netrc
    59  		l NetrcLine
    60  		m = false
    61  	)
    62  
    63  	for _, line := range strings.Split(string(b), "\n") {
    64  		if m {
    65  			if line == "" {
    66  				m = false
    67  			}
    68  			continue
    69  		}
    70  
    71  		f := strings.Fields(line)
    72  		for i := 0; i < len(f); {
    73  			switch f[i] {
    74  			case "machine":
    75  				l = NetrcLine{Machine: f[i+1]}
    76  				i += 2
    77  			case "default":
    78  				l = NetrcLine{Machine: "default"}
    79  				i += 1
    80  			case "login":
    81  				l.Login = f[i+1]
    82  				i += 2
    83  			case "password":
    84  				l.Password = f[i+1]
    85  				i += 2
    86  			case "macdef":
    87  				m = true
    88  				i += 2
    89  			}
    90  
    91  			if l.Machine != "" && l.Login != "" && l.Password != "" {
    92  				n = append(n, l)
    93  
    94  				if l.Machine == "default" {
    95  					return n, nil
    96  				}
    97  
    98  				l = NetrcLine{}
    99  			}
   100  		}
   101  	}
   102  
   103  	return n, nil
   104  }
   105  
   106  func NetrcPath() (string, error) {
   107  	if s, ok := os.LookupEnv("NETRC"); ok {
   108  		return s, nil
   109  	}
   110  
   111  	u, err := user.Current()
   112  	if err != nil {
   113  		return "", fmt.Errorf("unable to determine user home directory\n%w", err)
   114  	}
   115  
   116  	return filepath.Join(u.HomeDir, ".netrc"), nil
   117  }