Skip to content

Instantly share code, notes, and snippets.

@liu316484231
Last active November 27, 2021 02:27
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save liu316484231/0e02025cb507788b1d3be351006e599a to your computer and use it in GitHub Desktop.
Save liu316484231/0e02025cb507788b1d3be351006e599a to your computer and use it in GitHub Desktop.
Golang Script for obtaining Gitlab API Personal Access Token
/**
* Created by bing at 2019-12-17 08:58
*/
package rscrawler
import (
"github.com/anaskhan96/soup"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
)
const (
RootPoint string = "http://gitlab.k8s.test/"
SignInRoute = RootPoint + "users/sign_in"
PatRoute = RootPoint + "profile/personal_access_tokens"
SimUserLoginRoute = RootPoint + "users/auth/jwt/callback?jwt="
)
const (
User string = "root"
Password string = "Rscode123"
Token string = "tokenx"
TokenExpire string = "2025-12-30"
)
func findCsrfToken() (string, string, error) {
resp, err := http.Get(RootPoint)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", "", err
}
//cookie := resp.Header.Get("Set-Cookie")
cookies := resp.Cookies()
var c string
for _, cookie := range cookies {
if cookie.Name == "_gitlab_session" {
c = cookie.Name + "=" + cookie.Value
}
}
if err != nil {
log.Println(err)
return "", "", err
}
doc := soup.HTMLParse(string(body))
token := doc.Find("meta", "name", "csrf-token").Attrs()["content"]
return token, c, nil
}
func parseHtmlToken(text string) string {
doc := soup.HTMLParse(text)
token := doc.Find("meta", "name", "csrf-token")
log.Printf("csrf token is %s", token.Attrs()["content"])
return token.Attrs()["content"]
}
func signIn() (string, string, error) {
token, cookie, err := findCsrfToken()
log.Printf("token: %s, cookie: %s", token, cookie)
if err != nil {
log.Println(err)
return "", "", nil
}
data := url.Values{}
data.Set("user[login]", User)
data.Set("user[password]", Password)
data.Set("user[remember_me]", "0")
data.Set("utf8", "✓")
data.Set("authenticity_token", token)
r, err := http.NewRequest("POST", SignInRoute, strings.NewReader(data.Encode()))
if err != nil {
log.Println(err)
return "", "", nil
}
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
r.Header.Set("Cookie", cookie)
client := &http.Client{}
resp, err := client.Do(r)
defer resp.Body.Close()
if err != nil {
log.Println(err)
return "", "", nil
}
cookies := resp.Request.Response.Request.Response.Cookies()
var c string
for _, cookie := range cookies {
if cookie.Name == "_gitlab_session" {
c = cookie.Name + "=" + cookie.Value
}
}
log.Printf("logged in cookie is %s", c)
//get this page token
r, err = http.NewRequest("GET", PatRoute, nil)
if err != nil {
log.Println(err)
return "", "", nil
}
r.Header.Set("Cookie", c)
resp, err = client.Do(r)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", "", err
}
doc := soup.HTMLParse(string(body))
t2ele := doc.Find("meta", "name", "csrf-token")
t2 := t2ele.Attrs()["content"]
return t2, c, nil
}
func GetPAT() (string, error) {
token, cookie, err := signIn()
if err != nil {
log.Println(err)
return "", nil
}
data := url.Values{}
data.Set("personal_access_token[expires_at]", TokenExpire)
data.Set("personal_access_token[name]", Token)
data.Add("personal_access_token[scopes][]", "api")
data.Add("personal_access_token[scopes][]", "write_repository")
data.Add("personal_access_token[scopes][]", "read_repository")
data.Add("personal_access_token[scopes][]", "read_user")
data.Add("personal_access_token[scopes][]", "sudo")
data.Set("utf8", "✓")
data.Set("authenticity_token", token)
request, err := http.NewRequest("POST", PatRoute, strings.NewReader(data.Encode()))
if err != nil {
log.Println(err)
return "", nil
}
request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
request.Header.Set("Cookie", cookie)
client := &http.Client{}
resp, err := client.Do(request)
if err != nil {
log.Println(err)
return "", nil
}
respBytes, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
log.Println(err.Error())
return "", err
}
doc := soup.HTMLParse(string(respBytes))
node := doc.Find("input", "id", "created-personal-access-token")
if node.Error != nil {
return "", node.Error
}
return node.Attrs()["value"], nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment