github.com/sirkon/goproxy@v1.4.8/plugin/gitlab/plugin.go (about)

     1  package gitlab
     2  
     3  import (
     4  	"net/http"
     5  	path2 "path"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/sirkon/gitlab"
    10  
    11  	"github.com/sirkon/goproxy/internal/errors"
    12  
    13  	"github.com/sirkon/goproxy"
    14  )
    15  
    16  // plugin of sources for gitlab
    17  type plugin struct {
    18  	apiAccess gitlab.APIAccess
    19  	needAuth  bool
    20  	token     string
    21  }
    22  
    23  func (f *plugin) String() string {
    24  	return "gitlab"
    25  }
    26  
    27  // NewPlugin constructor
    28  func NewPlugin(access gitlab.APIAccess, needAuth bool) goproxy.Plugin {
    29  	return &plugin{
    30  		apiAccess: access,
    31  		needAuth:  needAuth,
    32  	}
    33  }
    34  
    35  // NewPluginToken constructor
    36  func NewPluginToken(access gitlab.APIAccess, token string) goproxy.Plugin {
    37  	return &plugin{
    38  		apiAccess: access,
    39  		token:     token,
    40  		needAuth:  true,
    41  	}
    42  }
    43  
    44  // NewPluginGitlabClient constructor with given gitlab apiAccess
    45  func NewPluginGitlabClient(needAuth bool, access gitlab.APIAccess) goproxy.Plugin {
    46  	return &plugin{
    47  		apiAccess: access,
    48  		needAuth:  needAuth,
    49  	}
    50  }
    51  
    52  // NewPluginGitlabTokenClient constructor with given gitlab apiAccess
    53  func NewPluginGitlabTokenClient(token string, access gitlab.APIAccess) goproxy.Plugin {
    54  	return &plugin{
    55  		apiAccess: access,
    56  		token:     token,
    57  		needAuth:  true,
    58  	}
    59  }
    60  
    61  func getGitlabPath(fullPath string) string {
    62  	pos := strings.IndexByte(fullPath, '/')
    63  	if pos >= 0 {
    64  		return fullPath[pos+1:]
    65  	}
    66  	return fullPath
    67  }
    68  
    69  func (f *plugin) Module(req *http.Request, prefix string) (goproxy.Module, error) {
    70  	path, _, err := goproxy.GetModInfo(req, prefix)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	// url prefix (gitlab.XXXX, etc) is not needed for gitlab projects
    75  	fullPath := path
    76  	path = getGitlabPath(fullPath)
    77  
    78  	var token string
    79  	if f.needAuth && len(f.token) == 0 {
    80  		var ok bool
    81  		token, _, ok = req.BasicAuth()
    82  		if !ok || len(token) == 0 {
    83  			return nil, errors.New("gitlab authorization info required")
    84  		}
    85  	} else if f.needAuth {
    86  		token = f.token
    87  	}
    88  
    89  	// cut the tail and see if it denounces version suffix (vXYZ)
    90  	pos := strings.LastIndexByte(fullPath, '/')
    91  	if pos < 0 {
    92  		return &gitlabModule{
    93  			client:          f.apiAccess.Client(token),
    94  			fullPath:        fullPath,
    95  			path:            path,
    96  			pathUnversioned: path,
    97  			major:           0,
    98  		}, nil
    99  	}
   100  
   101  	tail := fullPath[pos+1:]
   102  	var ve pathVersionExtractor
   103  	if ok, _ := ve.Extract(tail); !ok {
   104  		return &gitlabModule{
   105  			client:          f.apiAccess.Client(token),
   106  			fullPath:        fullPath,
   107  			path:            path,
   108  			pathUnversioned: path,
   109  			major:           0,
   110  		}, nil
   111  	}
   112  
   113  	unversionedPath, base := path2.Split(path)
   114  	if isVersion(base) {
   115  		return &gitlabModule{
   116  			client:          f.apiAccess.Client(token),
   117  			fullPath:        fullPath,
   118  			path:            path,
   119  			pathUnversioned: strings.Trim(unversionedPath, "/"),
   120  			major:           ve.Version,
   121  		}, nil
   122  	} else {
   123  		return &gitlabModule{
   124  			client:          f.apiAccess.Client(token),
   125  			fullPath:        fullPath,
   126  			path:            path,
   127  			pathUnversioned: path,
   128  			major:           ve.Version,
   129  		}, nil
   130  	}
   131  }
   132  
   133  func isVersion(s string) bool {
   134  	if len(s) < 2 {
   135  		return false
   136  	}
   137  	if !strings.HasPrefix(s, "v") {
   138  		return false
   139  	}
   140  	if _, err := strconv.Atoi(s[1:]); err != nil {
   141  		return false
   142  	}
   143  	return true
   144  }
   145  
   146  func (f *plugin) Leave(source goproxy.Module) error {
   147  	return nil
   148  }
   149  
   150  func (f *plugin) Close() error {
   151  	return nil
   152  }