Refactor to make the library reusable

Signed-off-by: Hadi <[email protected]>
This commit is contained in:
Hadi
2025-09-15 14:20:22 +02:00
parent fd79420749
commit c7a1689084
7 changed files with 172 additions and 174 deletions
-41
View File
@@ -1,41 +0,0 @@
package main
import (
"fmt"
"io"
"net/http"
"os"
github_recon_settings "github.com/anotherhadi/github-recon/settings"
gopixels "github.com/saran13raj/go-pixels"
)
func printAvatar(settings github_recon_settings.Settings, url string) {
if settings.HideAvatar || url == "" || settings.Silent {
return
}
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
tmpfile, err := os.CreateTemp("", "avatar-*.png")
if err != nil {
return
}
defer os.Remove(tmpfile.Name())
_, err = io.Copy(tmpfile, resp.Body)
if err != nil {
return
}
output, err := gopixels.FromImagePath(tmpfile.Name(), 30, 25, "halfcell", true)
if err != nil {
return
}
fmt.Println(output + "\n")
}
-42
View File
@@ -1,42 +0,0 @@
package main
import (
recon "github.com/anotherhadi/github-recon/github-recon/email"
github_recon_settings "github.com/anotherhadi/github-recon/settings"
)
type EmailResult struct {
DateTime string
Target string
TargetType github_recon_settings.TargetType
Commits recon.CommitsResult
Spoofing recon.SpoofingResult
}
func email(settings github_recon_settings.Settings, datetime string) {
result := EmailResult{
Target: settings.Target,
TargetType: settings.TargetType,
DateTime: datetime,
}
printTitle(settings.Silent, "👤 Commits author")
result.Commits = recon.Commits(settings)
printStruct(settings, result.Commits, 0)
if settings.SpoofEmail {
if settings.Token == "null" {
settings.Logger.Warn("Skipping email spoofing test, please provide a Github token")
} else {
printTitle(settings.Silent, "🎭 Spoofing test")
result.Spoofing = recon.Spoofing(settings)
if result.Spoofing.AvatarURL != "" {
printAvatar(settings, result.Spoofing.AvatarURL)
}
printStruct(settings, result.Spoofing, 0)
}
}
writeJson(settings, result)
}
+9 -9
View File
@@ -1,32 +1,32 @@
package main package main
import ( import (
"time" recon_email "github.com/anotherhadi/github-recon/github-recon/email"
recon_username "github.com/anotherhadi/github-recon/github-recon/username"
github_recon_settings "github.com/anotherhadi/github-recon/settings" github_recon_settings "github.com/anotherhadi/github-recon/settings"
"github.com/anotherhadi/github-recon/utils"
) )
func main() { func main() {
settings := github_recon_settings.GetSettings() settings := github_recon_settings.GetSettings()
datetime := time.Now().String()
if !settings.Silent { if !settings.Silent {
header() utils.Header()
printStruct(settings, struct { utils.PrintStruct(settings, struct {
Target string Target string
TargetType string TargetType string
DateTime string
}{ }{
Target: settings.Target, Target: settings.Target,
TargetType: string(settings.TargetType), TargetType: string(settings.TargetType),
DateTime: datetime,
}, 0) }, 0)
} }
if settings.TargetType == github_recon_settings.TargetUsername { if settings.TargetType == github_recon_settings.TargetUsername {
username(settings, datetime) result := recon_username.Username(settings)
writeJson(settings, result)
} else { } else {
email(settings, datetime) result := recon_email.Email(settings)
writeJson(settings, result)
} }
} }
-75
View File
@@ -1,75 +0,0 @@
package main
import (
recon "github.com/anotherhadi/github-recon/github-recon/username"
github_recon_settings "github.com/anotherhadi/github-recon/settings"
)
type UsernameResult struct {
DateTime string // Now
Target string
TargetType github_recon_settings.TargetType
User recon.UserResult
Socials recon.SocialsResult
Orgs recon.OrgsResult
SshKeys recon.SshKeysResult
SshSigningKeys recon.SshSigningKeysResult
GpgKeys recon.GpgKeysResult
CloseFriends recon.CloseFriendsResult
Commits recon.CommitsResult
DeepScan recon.DeepScanResult
}
func username(settings github_recon_settings.Settings, datetime string) {
result := UsernameResult{
Target: settings.Target,
TargetType: settings.TargetType,
DateTime: datetime,
}
printTitle(settings.Silent, "👤 User informations")
result.User = recon.User(settings)
printAvatar(settings, result.User.AvatarURL)
printStruct(settings, result.User, 0)
printTitle(settings.Silent, "🐥 Socials")
result.Socials = recon.Socials(settings)
printStruct(settings, result.Socials, 0)
printTitle(settings.Silent, "🏢 Organizations")
result.Orgs = recon.Orgs(settings)
printStruct(settings, result.Orgs, 0)
printTitle(settings.Silent, "🔑 SSH Keys")
result.SshKeys = recon.SshKeys(settings)
printStruct(settings, result.SshKeys, 0)
printTitle(settings.Silent, "🖋️ SSH Signing Keys")
result.SshSigningKeys = recon.SshSigningKeys(settings)
printStruct(settings, result.SshSigningKeys, 0)
printTitle(settings.Silent, "🔐 GPG Keys")
result.GpgKeys = recon.GpgKeys(settings)
printStruct(settings, result.GpgKeys, 0)
printTitle(settings.Silent, "🤝 Close Friends")
result.CloseFriends = recon.CloseFriends(settings)
printStruct(settings, result.CloseFriends, 0)
printTitle(settings.Silent, "📝 Commits")
result.Commits = recon.Commits(settings)
printStruct(settings, result.Commits, 0)
if settings.DeepScan {
printTitle(settings.Silent, "🔍 Deep Scan")
result.DeepScan = recon.DeepScan(settings)
printStruct(settings, result.DeepScan, 0)
}
writeJson(settings, result)
}
+44
View File
@@ -0,0 +1,44 @@
package recon
import (
"time"
github_recon_settings "github.com/anotherhadi/github-recon/settings"
"github.com/anotherhadi/github-recon/utils"
)
type EmailResult struct {
DateTime string
Target string
TargetType github_recon_settings.TargetType
Commits CommitsResult
Spoofing SpoofingResult
}
func Email(settings github_recon_settings.Settings) EmailResult {
result := EmailResult{
Target: settings.Target,
TargetType: settings.TargetType,
DateTime: time.Now().String(),
}
utils.PrintTitle(settings.Silent, "👤 Commits author")
result.Commits = Commits(settings)
utils.PrintStruct(settings, result.Commits, 0)
if settings.SpoofEmail {
if settings.Token == "null" {
settings.Logger.Warn("Skipping email spoofing test, please provide a Github token")
} else {
utils.PrintTitle(settings.Silent, "🎭 Spoofing test")
result.Spoofing = Spoofing(settings)
if result.Spoofing.AvatarURL != "" {
utils.PrintAvatar(settings, result.Spoofing.AvatarURL)
}
utils.PrintStruct(settings, result.Spoofing, 0)
}
}
return result
}
+78
View File
@@ -0,0 +1,78 @@
package recon
import (
"time"
github_recon_settings "github.com/anotherhadi/github-recon/settings"
"github.com/anotherhadi/github-recon/utils"
)
type UsernameResult struct {
DateTime string // Now
Target string
TargetType github_recon_settings.TargetType
User UserResult
Socials SocialsResult
Orgs OrgsResult
SshKeys SshKeysResult
SshSigningKeys SshSigningKeysResult
GpgKeys GpgKeysResult
CloseFriends CloseFriendsResult
Commits CommitsResult
DeepScan DeepScanResult
}
func Username(settings github_recon_settings.Settings) UsernameResult {
result := UsernameResult{
Target: settings.Target,
TargetType: settings.TargetType,
DateTime: time.Now().String(),
}
utils.PrintTitle(settings.Silent, "👤 User informations")
result.User = User(settings)
utils.PrintAvatar(settings, result.User.AvatarURL)
utils.PrintStruct(settings, result.User, 0)
utils.PrintTitle(settings.Silent, "🐥 Socials")
result.Socials = Socials(settings)
utils.PrintStruct(settings, result.Socials, 0)
utils.PrintTitle(settings.Silent, "🏢 Organizations")
result.Orgs = Orgs(settings)
utils.PrintStruct(settings, result.Orgs, 0)
utils.PrintTitle(settings.Silent, "🔑 SSH Keys")
result.SshKeys = SshKeys(settings)
utils.PrintStruct(settings, result.SshKeys, 0)
utils.PrintTitle(settings.Silent, "🖋️ SSH Signing Keys")
result.SshSigningKeys = SshSigningKeys(settings)
utils.PrintStruct(settings, result.SshSigningKeys, 0)
utils.PrintTitle(settings.Silent, "🔐 GPG Keys")
result.GpgKeys = GpgKeys(settings)
utils.PrintStruct(settings, result.GpgKeys, 0)
utils.PrintTitle(settings.Silent, "🤝 Close Friends")
result.CloseFriends = CloseFriends(settings)
utils.PrintStruct(settings, result.CloseFriends, 0)
utils.PrintTitle(settings.Silent, "📝 Commits")
result.Commits = Commits(settings)
utils.PrintStruct(settings, result.Commits, 0)
if settings.DeepScan {
utils.PrintTitle(settings.Silent, "🔍 Deep Scan")
result.DeepScan = DeepScan(settings)
utils.PrintStruct(settings, result.DeepScan, 0)
}
return result
}
+41 -7
View File
@@ -1,13 +1,17 @@
package main package utils
import ( import (
"fmt" "fmt"
"io"
"net/http"
"os"
"reflect" "reflect"
"sort" "sort"
"strings" "strings"
github_recon_settings "github.com/anotherhadi/github-recon/settings" github_recon_settings "github.com/anotherhadi/github-recon/settings"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
gopixels "github.com/saran13raj/go-pixels"
) )
var ( var (
@@ -20,7 +24,7 @@ var (
titleStyle = lipgloss.NewStyle().Bold(true).Foreground(blue) titleStyle = lipgloss.NewStyle().Bold(true).Foreground(blue)
) )
func printStruct(settings github_recon_settings.Settings, s any, indent int) { func PrintStruct(settings github_recon_settings.Settings, s any, indent int) {
if settings.Silent { if settings.Silent {
return return
} }
@@ -68,7 +72,7 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) {
switch value.Kind() { switch value.Kind() {
case reflect.Struct, reflect.Slice, reflect.Array, reflect.Ptr, reflect.Map, reflect.Interface: case reflect.Struct, reflect.Slice, reflect.Array, reflect.Ptr, reflect.Map, reflect.Interface:
fmt.Println(prefix + greyStyle.Render(field+":")) fmt.Println(prefix + greyStyle.Render(field+":"))
printStruct(settings, value.Interface(), indent+1) PrintStruct(settings, value.Interface(), indent+1)
case reflect.String: case reflect.String:
fmt.Printf("%s%s %s\n", prefix, greyStyle.Render(field+":"), greenStyle.Render(fmt.Sprintf("%q", value.Interface()))) fmt.Printf("%s%s %s\n", prefix, greyStyle.Render(field+":"), greenStyle.Render(fmt.Sprintf("%q", value.Interface())))
@@ -89,7 +93,7 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) {
return return
} }
for i := 0; i < v.Len(); i++ { for i := 0; i < v.Len(); i++ {
printStruct(settings, v.Index(i).Interface(), indent) PrintStruct(settings, v.Index(i).Interface(), indent)
} }
case reflect.Map: case reflect.Map:
@@ -110,7 +114,7 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) {
if fmt.Sprintf("%v", k.Interface()) == keyStr { if fmt.Sprintf("%v", k.Interface()) == keyStr {
val := v.MapIndex(k) val := v.MapIndex(k)
fmt.Println(prefix + greyStyle.Render(fmt.Sprintf("%v:", k.Interface()))) fmt.Println(prefix + greyStyle.Render(fmt.Sprintf("%v:", k.Interface())))
printStruct(settings, val.Interface(), indent+1) PrintStruct(settings, val.Interface(), indent+1)
} }
} }
} }
@@ -120,7 +124,7 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) {
} }
} }
func header() { func Header() {
asciiArt := " __ \n ___ _/ / _______ _______ ___ \n / _ `/ _ \\/ __/ -_) __/ _ \\/ _ \\\n \\_, /_//_/_/ \\__/\\__/\\___/_//_/\n/___/ " asciiArt := " __ \n ___ _/ / _______ _______ ___ \n / _ `/ _ \\/ __/ -_) __/ _ \\/ _ \\\n \\_, /_//_/_/ \\__/\\__/\\___/_//_/\n/___/ "
grey := lipgloss.Color("#7d7d7d") grey := lipgloss.Color("#7d7d7d")
@@ -131,9 +135,39 @@ func header() {
) )
} }
func printTitle(silent bool, title string) { func PrintTitle(silent bool, title string) {
if silent { if silent {
return return
} }
fmt.Println(titleStyle.Render(title) + "\n") fmt.Println(titleStyle.Render(title) + "\n")
} }
func PrintAvatar(settings github_recon_settings.Settings, url string) {
if settings.HideAvatar || url == "" || settings.Silent {
return
}
resp, err := http.Get(url)
if err != nil {
return
}
defer resp.Body.Close()
tmpfile, err := os.CreateTemp("", "avatar-*.png")
if err != nil {
return
}
defer os.Remove(tmpfile.Name())
_, err = io.Copy(tmpfile, resp.Body)
if err != nil {
return
}
output, err := gopixels.FromImagePath(tmpfile.Name(), 30, 25, "halfcell", true)
if err != nil {
return
}
fmt.Println(output + "\n")
}