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 }