Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use github api instead of raw file to download fingerprint #61

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 45 additions & 20 deletions runner/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package runner
import (
"bytes"
"crypto/md5"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"net/http"
"os"
Expand All @@ -16,10 +17,15 @@ import (
)

var (
fingerprintPath = "https://raw.githubusercontent.com/EdOverflow/can-i-take-over-xyz/master/fingerprints.json"
subzyDir = "subzy"
fingerprintPath = "https://api.github.com/repos/EdOverflow/can-i-take-over-xyz/contents/fingerprints.json"

subzyDir = "subzy"
)

type GitHubFileContent struct {
Content string `json:"content"`
}

func GetFingerprintPath() (string, error) {
home, err := homedir.Dir()
if err != nil {
Expand All @@ -46,54 +52,73 @@ func DownloadFingerprints() error {
}
defer out.Close()

resp, err := http.Get(fingerprintPath)
// Get the file from the GitHub API instead of the raw URL
resp, err := http.Get(fingerprintPath) // Use API URL
if err != nil {
return fmt.Errorf("downloadFingerprints: %v", err)
}
defer resp.Body.Close()

_, err = io.Copy(out, resp.Body)
bytes, err := decodeResponseFromApi(*resp)
if err != nil {
return fmt.Errorf("downloadFingerprints: %v", err)
return fmt.Errorf("failed to decode base64 content: %v", err)
}

// Write the decoded content to the file
_, err = out.Write(bytes)
if err != nil {
return fmt.Errorf("failed to write to fingerprints file: %v", err)
}

return nil
}

func CheckIntegrity() (bool, error) {
resp, err := http.Get(fingerprintPath)
// Fetch the upstream content via GitHub API
resp, err := http.Get(fingerprintPath) // Use API URL
if err != nil {
return false, fmt.Errorf("downloadFingerprints: %v", err)
}
defer resp.Body.Close()

outBytes, err := io.ReadAll(resp.Body)
// Decode the api response
upstreamBytes, err := decodeResponseFromApi(*resp)
if err != nil {
return false, err
return false, fmt.Errorf("failed to decode base64 content: %v", err)
}

h := md5.New()
upstreamSum := h.Sum(outBytes)

// Get local file content
fingerprintsLocal, err := GetFingerprintPath()
if err != nil {
return false, err
}

f, err := os.Open(fingerprintsLocal)
localBytes, err := os.ReadFile(fingerprintsLocal)
if err != nil {
return false, err
return false, fmt.Errorf("failed to read local fingerprints file: %v", err)
}
defer f.Close()

localBytes := make([]byte, len(outBytes))
_, err = f.Read(localBytes)
if err != nil {
return false, err
}
// Calculate MD5 checksums for both upstream and local files
h := md5.New()
upstreamSum := h.Sum(upstreamBytes)

h = md5.New()
localSum := h.Sum(localBytes)

// Compare the checksums
return bytes.Equal(upstreamSum, localSum), nil
}

func decodeResponseFromApi(resp http.Response) ([]byte, error) {
// Decode the JSON response from GitHub API
var fileContent GitHubFileContent
err := json.NewDecoder(resp.Body).Decode(&fileContent)
if err != nil {
return nil, fmt.Errorf("failed to decode json response: %v", err)
}
upstreamBytes, err := base64.StdEncoding.DecodeString(fileContent.Content)
if err != nil {
return nil, err
}
return upstreamBytes, nil
}