106 lines
2.7 KiB
Go
106 lines
2.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"ripper/internal/response"
|
|
)
|
|
|
|
const (
|
|
clientID = "Iv1.b507a08c87ecfe98"
|
|
deviceCodeURL = "https://github.com/login/device/code"
|
|
tokenURL = "https://github.com/login/oauth/access_token"
|
|
)
|
|
|
|
type githubLoginDeviceRequest struct {
|
|
DeviceCode string `form:"device_code" json:"device_code" binding:"required"`
|
|
}
|
|
|
|
// getDeviceCode returns the device code for GitHub login.
|
|
func getDeviceCode(c *gin.Context) {
|
|
body := map[string]string{
|
|
"client_id": clientID,
|
|
}
|
|
|
|
result, err := makeRequest(c, http.MethodPost, deviceCodeURL, body)
|
|
if err != nil {
|
|
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, result)
|
|
}
|
|
|
|
// getGhuToken returns the GitHub user token.
|
|
func getGhuToken(c *gin.Context) {
|
|
var params githubLoginDeviceRequest
|
|
if err := c.ShouldBind(¶ms); err != nil {
|
|
response.FailJson(c, response.FailStruct{
|
|
Code: -1,
|
|
Msg: "Invalid request: " + err.Error(),
|
|
}, false)
|
|
return
|
|
}
|
|
|
|
body := map[string]string{
|
|
"client_id": clientID,
|
|
"device_code": params.DeviceCode,
|
|
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
|
|
}
|
|
|
|
result, err := makeRequest(c, http.MethodPost, tokenURL, body)
|
|
if err != nil {
|
|
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, result)
|
|
}
|
|
|
|
// getGithubLoginDevice returns the login page for GitHub.
|
|
func getGithubLoginDevice(ctx *gin.Context) {
|
|
ctx.Header("Content-Type", "text/html; charset=utf-8")
|
|
ctx.HTML(http.StatusOK, "login.html", gin.H{})
|
|
}
|
|
|
|
// makeRequest makes a request to the given URL with the given method and body.
|
|
func makeRequest(c *gin.Context, method, url string, body map[string]string) (interface{}, error) {
|
|
jsonBody, err := json.Marshal(body)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req, err := http.NewRequestWithContext(c, method, url, bytes.NewBuffer(jsonBody))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req.Header.Set("accept", "application/json")
|
|
req.Header.Set("content-type", "application/json")
|
|
req.Header.Set("editor-plugin-version", "copilot-intellij/1.5.21.6667")
|
|
req.Header.Set("copilot-language-server-version", "1.228.0")
|
|
req.Header.Set("user-agent", "GithubCopilot/1.228.0")
|
|
req.Header.Set("editor-version", "JetBrains-IU/242.21829.142")
|
|
|
|
httpClientTimeout, _ := time.ParseDuration(os.Getenv("HTTP_CLIENT_TIMEOUT") + "s")
|
|
client := &http.Client{Timeout: httpClientTimeout}
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
var result interface{}
|
|
err = json.NewDecoder(resp.Body).Decode(&result)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|