From c7a16890846938c22d13033f1fda6da61cd776c2 Mon Sep 17 00:00:00 2001 From: Hadi <112569860+anotherhadi@users.noreply.github.com> Date: Mon, 15 Sep 2025 14:20:22 +0200 Subject: [PATCH] Refactor to make the library reusable Signed-off-by: Hadi <112569860+anotherhadi@users.noreply.github.com> --- cmd/avatar.go | 41 ------------------ cmd/email.go | 42 ------------------- cmd/main.go | 18 ++++---- cmd/username.go | 75 --------------------------------- github-recon/email/main.go | 44 ++++++++++++++++++++ github-recon/username/main.go | 78 +++++++++++++++++++++++++++++++++++ {cmd => utils}/print.go | 48 +++++++++++++++++---- 7 files changed, 172 insertions(+), 174 deletions(-) delete mode 100644 cmd/avatar.go delete mode 100644 cmd/email.go delete mode 100644 cmd/username.go create mode 100644 github-recon/email/main.go create mode 100644 github-recon/username/main.go rename {cmd => utils}/print.go (77%) diff --git a/cmd/avatar.go b/cmd/avatar.go deleted file mode 100644 index 69eb4c6..0000000 --- a/cmd/avatar.go +++ /dev/null @@ -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") -} diff --git a/cmd/email.go b/cmd/email.go deleted file mode 100644 index 194c6e6..0000000 --- a/cmd/email.go +++ /dev/null @@ -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) -} diff --git a/cmd/main.go b/cmd/main.go index ff1caa8..841a504 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -1,32 +1,32 @@ package main 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.com/anotherhadi/github-recon/utils" ) func main() { settings := github_recon_settings.GetSettings() - datetime := time.Now().String() if !settings.Silent { - header() + utils.Header() - printStruct(settings, struct { + utils.PrintStruct(settings, struct { Target string TargetType string - DateTime string }{ Target: settings.Target, TargetType: string(settings.TargetType), - DateTime: datetime, }, 0) } if settings.TargetType == github_recon_settings.TargetUsername { - username(settings, datetime) + result := recon_username.Username(settings) + writeJson(settings, result) } else { - email(settings, datetime) + result := recon_email.Email(settings) + writeJson(settings, result) } } diff --git a/cmd/username.go b/cmd/username.go deleted file mode 100644 index 013c29d..0000000 --- a/cmd/username.go +++ /dev/null @@ -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) -} diff --git a/github-recon/email/main.go b/github-recon/email/main.go new file mode 100644 index 0000000..9a66bae --- /dev/null +++ b/github-recon/email/main.go @@ -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 +} diff --git a/github-recon/username/main.go b/github-recon/username/main.go new file mode 100644 index 0000000..6531a1f --- /dev/null +++ b/github-recon/username/main.go @@ -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 +} diff --git a/cmd/print.go b/utils/print.go similarity index 77% rename from cmd/print.go rename to utils/print.go index a0d7918..1067ddc 100644 --- a/cmd/print.go +++ b/utils/print.go @@ -1,13 +1,17 @@ -package main +package utils import ( "fmt" + "io" + "net/http" + "os" "reflect" "sort" "strings" github_recon_settings "github.com/anotherhadi/github-recon/settings" "github.com/charmbracelet/lipgloss" + gopixels "github.com/saran13raj/go-pixels" ) var ( @@ -20,7 +24,7 @@ var ( 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 { return } @@ -68,7 +72,7 @@ func printStruct(settings github_recon_settings.Settings, s any, indent int) { switch value.Kind() { case reflect.Struct, reflect.Slice, reflect.Array, reflect.Ptr, reflect.Map, reflect.Interface: fmt.Println(prefix + greyStyle.Render(field+":")) - printStruct(settings, value.Interface(), indent+1) + PrintStruct(settings, value.Interface(), indent+1) case reflect.String: 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 } for i := 0; i < v.Len(); i++ { - printStruct(settings, v.Index(i).Interface(), indent) + PrintStruct(settings, v.Index(i).Interface(), indent) } 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 { val := v.MapIndex(k) 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/___/ " grey := lipgloss.Color("#7d7d7d") @@ -131,9 +135,39 @@ func header() { ) } -func printTitle(silent bool, title string) { +func PrintTitle(silent bool, title string) { if silent { return } 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") +}