3 Commits

Author SHA1 Message Date
Evan Hosinski e9dc836c4e Remove SQLite dependencies from go.mod and go.sum 2026-06-04 12:46:11 -04:00
Evan Hosinski daf54bb8c1 Update import paths to use new module path hub.krkn.tech/KrakenTech/crowsnest across the project 2026-06-04 12:45:39 -04:00
Evan Hosinski f23bd04114 Fixed issue where query only exported to file 2026-04-07 09:37:41 -04:00
25 changed files with 222 additions and 133 deletions
+7 -6
View File
@@ -1,15 +1,16 @@
package cmd
import (
"crowsnest/internal/badger"
"crowsnest/internal/debug"
"crowsnest/internal/dehashed"
"crowsnest/internal/files"
"crowsnest/internal/pretty"
"crowsnest/internal/sqlite"
"fmt"
"github.com/spf13/cobra"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/badger"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/dehashed"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
"hub.krkn.tech/KrakenTech/crowsnest/internal/pretty"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func init() {
+9 -8
View File
@@ -1,17 +1,18 @@
package cmd
import (
"crowsnest/internal/badger"
"crowsnest/internal/debug"
"crowsnest/internal/export"
"crowsnest/internal/files"
hunter "crowsnest/internal/hunter.io"
"crowsnest/internal/pretty"
"crowsnest/internal/sqlite"
"fmt"
"time"
"github.com/spf13/cobra"
"go.uber.org/zap"
"time"
"hub.krkn.tech/KrakenTech/crowsnest/internal/badger"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/export"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
hunter "hub.krkn.tech/KrakenTech/crowsnest/internal/hunter.io"
"hub.krkn.tech/KrakenTech/crowsnest/internal/pretty"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func init() {
+4 -3
View File
@@ -1,15 +1,16 @@
package cmd
import (
"crowsnest/internal/easyTime"
"crowsnest/internal/pretty"
"encoding/json"
"fmt"
"github.com/spf13/cobra"
"os"
"path/filepath"
"strings"
"time"
"github.com/spf13/cobra"
"hub.krkn.tech/KrakenTech/crowsnest/internal/easyTime"
"hub.krkn.tech/KrakenTech/crowsnest/internal/pretty"
)
func init() {
+17 -19
View File
@@ -1,16 +1,17 @@
package cmd
import (
"crowsnest/internal/debug"
"crowsnest/internal/export"
"crowsnest/internal/files"
"crowsnest/internal/pretty"
"crowsnest/internal/sqlite"
"encoding/json"
"fmt"
"strings"
"github.com/spf13/cobra"
"go.uber.org/zap"
"strings"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/export"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
"hub.krkn.tech/KrakenTech/crowsnest/internal/pretty"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func init() {
@@ -18,15 +19,16 @@ func init() {
rootCmd.AddCommand(queryCmd)
// Add flags specific to whois command
queryCmd.Flags().StringVarP(&dbQueryTableName, "table", "t", "", "Table to query (results, creds, whois, subdomains, history, runs)")
queryCmd.Flags().StringVarP(&dbQueryTableName, "table", "t", "", "Table to query (dehashed, users, whois, subdomains, lookup, runs)")
queryCmd.Flags().IntVarP(&dbQueryLimitRows, "limit", "l", 100, "Limit number of results")
queryCmd.Flags().StringVarP(&dbQueryNotNull, "not-null", "n", "", "Filter for non-null values (comma-separated list, e.g., 'password,email')")
queryCmd.Flags().StringVarP(&dbQueryColumns, "columns", "c", "", "Columns to display in output (comma-separated list, e.g., 'username,email,password')")
queryCmd.Flags().StringVarP(&dbQueryUserQuery, "user-query", "q", "", "User query to execute")
queryCmd.Flags().StringVarP(&dbQueryRawQuery, "raw-query", "r", "", "Raw SQL query to execute")
queryCmd.Flags().BoolVarP(&dbQueryListAll, "list-all", "a", false, "List all tables and their columns")
queryCmd.Flags().BoolVarP(&dbQueryExport, "export", "x", false, "Export results to file using --file and --format")
queryCmd.Flags().StringVarP(&dbQueryFormat, "format", "f", "json", "Output format (json, yaml, xml, txt, grep)")
queryCmd.Flags().StringVarP(&dbQueryFile, "file", "o", "query", "File to output results to")
queryCmd.Flags().StringVarP(&dbQueryFile, "file", "o", "query", "File to output results to when --export is set")
// Add mutually exclusive flags to query and raw-query
// Cannot use query and raw-query at the same time
@@ -45,6 +47,7 @@ var (
dbQueryUserQuery string
dbQueryRawQuery string
dbQueryListAll bool
dbQueryExport bool
dbQueryFormat string
dbQueryFile string
@@ -52,7 +55,7 @@ var (
Use: "query",
Short: "Query the database",
Long: `Query the database for various information.
If file is specified, results are written to file and not displayed in the terminal.`,
Use --export with --file and --format to write results to a file instead of displaying them.`,
Run: func(cmd *cobra.Command, args []string) {
// If list-all flag is set, list all tables and columns
if dbQueryListAll {
@@ -70,14 +73,14 @@ If file is specified, results are written to file and not displayed in the termi
// Validate table name
if dbQueryTableName == "" {
fmt.Println("[!] Error: Table name is required. Use -t or --table to specify a table.")
fmt.Println("[*] Available tables: results, creds, whois, subdomains, history, runs")
fmt.Println("[*] Available tables: dehashed, users, whois, subdomains, lookup, runs")
fmt.Println("[*] Use --list-all to see all tables and their columns.")
return
}
if !isValidTable(dbQueryTableName) {
fmt.Printf("[!] Error: Unknown table '%s'.\n", dbQueryTableName)
fmt.Println("[*] Available tables: results, creds, whois, subdomains, history, runs")
fmt.Println("[*] Available tables: dehashed, users, whois, subdomains, lookup, runs")
fmt.Println("[*] Use --list-all to see all tables and their columns.")
return
}
@@ -124,7 +127,7 @@ If file is specified, results are written to file and not displayed in the termi
table := sqlite.GetTable(dbQueryTableName)
if table == sqlite.UnknownTable {
fmt.Printf("[!] Error: Unknown table type '%s'.\n", dbQueryTableName)
fmt.Println("[*] Available tables: results, creds, whois, subdomains, history, runs")
fmt.Println("[*] Available tables: dehashed, users, whois, subdomains, lookup, runs")
fmt.Println("[*] Use --list-all to see all tables and their columns.")
return
}
@@ -203,8 +206,7 @@ func tableQuery(table sqlite.Table) {
return
}
// Export results if file name is specified
if len(strings.TrimSpace(dbQueryFile)) > 0 {
if dbQueryExport {
fmt.Println("[*] Exporting results to file...")
if debugGlobal {
@@ -244,8 +246,6 @@ func tableQuery(table sqlite.Table) {
return
}
fmt.Println("[*] Querying Database...")
// Prepare data for pretty.Table
headers := cols
var tableRows [][]string
@@ -336,7 +336,7 @@ func rawDBQuery() {
return
}
if len(strings.TrimSpace(dbQueryFile)) > 0 {
if dbQueryExport {
fmt.Println("[*] Exporting results to file...")
if debugGlobal {
@@ -377,8 +377,6 @@ func rawDBQuery() {
return
}
fmt.Println("[*] Querying Database...")
// Prepare data for pretty.Table
headers := columns
var tableRows [][]string
+4 -3
View File
@@ -1,13 +1,14 @@
package cmd
import (
"crowsnest/internal/badger"
"fmt"
"os"
"strings"
"github.com/fatih/color"
"github.com/spf13/cobra"
"go.uber.org/zap"
"os"
"strings"
"hub.krkn.tech/KrakenTech/crowsnest/internal/badger"
)
var (
+2 -1
View File
@@ -1,9 +1,10 @@
package cmd
import (
"crowsnest/internal/pretty"
"fmt"
"strings"
"hub.krkn.tech/KrakenTech/crowsnest/internal/pretty"
)
// Map of available tables and their columns
+4 -3
View File
@@ -1,12 +1,13 @@
package cmd
import (
"crowsnest/internal/sqlite"
"fmt"
"github.com/spf13/cobra"
"go.uber.org/zap"
"os"
"strings"
"github.com/spf13/cobra"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func init() {
+9 -8
View File
@@ -1,18 +1,19 @@
package cmd
import (
"crowsnest/internal/debug"
"crowsnest/internal/export"
"crowsnest/internal/files"
"crowsnest/internal/pretty"
"crowsnest/internal/sqlite"
"crowsnest/internal/whois"
"fmt"
"github.com/spf13/cobra"
"go.uber.org/zap"
"os"
"strings"
"time"
"github.com/spf13/cobra"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/export"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
"hub.krkn.tech/KrakenTech/crowsnest/internal/pretty"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
"hub.krkn.tech/KrakenTech/crowsnest/internal/whois"
)
func init() {
+6 -5
View File
@@ -1,16 +1,17 @@
package main
import (
"crowsnest/cmd"
"crowsnest/internal/badger"
"crowsnest/internal/sqlite"
"fmt"
"os"
"path/filepath"
"github.com/winking324/rzap"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
"os"
"path/filepath"
"hub.krkn.tech/KrakenTech/crowsnest/cmd"
"hub.krkn.tech/KrakenTech/crowsnest/internal/badger"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
var (
+1 -3
View File
@@ -1,4 +1,4 @@
module crowsnest
module hub.krkn.tech/KrakenTech/crowsnest
go 1.23.0
@@ -14,7 +14,6 @@ require (
go.uber.org/zap v1.20.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/sqlite v1.5.7
gorm.io/gorm v1.26.1
)
@@ -41,7 +40,6 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.4.7 // indirect
-4
View File
@@ -75,8 +75,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
@@ -171,8 +169,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I=
gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.26.1 h1:ghB2gUI9FkS46luZtn6DLZ0f6ooBJ5IbVej2ENFDjRw=
gorm.io/gorm v1.26.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
+4 -3
View File
@@ -2,17 +2,18 @@ package dehashed
import (
"bytes"
"crowsnest/internal/debug"
"crowsnest/internal/sqlite"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"go.uber.org/zap"
"io"
"net/http"
"strings"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
type DehashedParameter string
+18 -14
View File
@@ -12,8 +12,8 @@ import (
"strconv"
"strings"
"crowsnest/internal/files"
"gopkg.in/yaml.v3"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
)
const dataWellsEndpoint = "https://api.dehashed.com/data-wells"
@@ -163,20 +163,24 @@ func (dwr DataWellsResponse) String() string {
}
func dataWellGreppable(well DataWell) string {
fields := []string{
"name=" + cleanGreppableValue(well.Name),
"date=" + cleanGreppableValue(well.Date),
"records=" + strconv.Itoa(well.Records),
"is_sensitive=" + strconv.FormatBool(well.IsSensitive),
"data=" + cleanGreppableValue(well.Data),
"description=" + cleanGreppableValue(well.Description),
}
return strings.Join(fields, "\t")
var fields []string
fields = appendDataWellGreppableField(fields, "name", well.Name)
fields = appendDataWellGreppableField(fields, "date", well.Date)
fields = appendDataWellGreppableField(fields, "records", strconv.Itoa(well.Records))
fields = appendDataWellGreppableField(fields, "is_sensitive", strconv.FormatBool(well.IsSensitive))
fields = appendDataWellGreppableField(fields, "data", well.Data)
fields = appendDataWellGreppableField(fields, "description", well.Description)
return strings.Join(fields, " ")
}
func cleanGreppableValue(value string) string {
value = strings.ReplaceAll(value, "\r", " ")
value = strings.ReplaceAll(value, "\n", " ")
value = strings.ReplaceAll(value, "\t", " ")
return strings.TrimSpace(value)
return strings.Join(strings.Fields(value), "_")
}
func appendDataWellGreppableField(fields []string, key, value string) []string {
value = cleanGreppableValue(value)
if value == "" {
return fields
}
return append(fields, fmt.Sprintf("%s=%s", key, value))
}
+6 -5
View File
@@ -1,14 +1,15 @@
package dehashed
import (
"crowsnest/internal/debug"
"crowsnest/internal/export"
"crowsnest/internal/pretty"
"crowsnest/internal/sqlite"
"fmt"
"go.uber.org/zap"
"os"
"strings"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/export"
"hub.krkn.tech/KrakenTech/crowsnest/internal/pretty"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
const (
+23 -1
View File
@@ -4,7 +4,7 @@ import (
"strings"
"testing"
"crowsnest/internal/sqlite"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func TestSetQueriesCapsSearchAtFiftyThousandResults(t *testing.T) {
@@ -70,3 +70,25 @@ func TestDataWellsURLDoesNotRequireAPIKey(t *testing.T) {
}
}
}
func TestDataWellGreppableUsesSpaceSeparatedNonEmptyTokens(t *testing.T) {
got := dataWellGreppable(DataWell{
Name: "Example Breach",
Date: "2025-03-01",
Records: 500000,
IsSensitive: true,
Data: "name,email,address",
})
if strings.Contains(got, "\t") {
t.Fatalf("greppable output contains tab: %q", got)
}
if strings.Contains(got, "description=") {
t.Fatalf("greppable output contains empty field: %q", got)
}
for _, want := range []string{"name=Example_Breach", "date=2025-03-01", "records=500000", "is_sensitive=true", "data=name,email,address"} {
if !strings.Contains(got, want) {
t.Fatalf("greppable output = %q, want token %q", got, want)
}
}
}
+3 -2
View File
@@ -1,13 +1,14 @@
package easyTime
import (
"crowsnest/internal/debug"
"fmt"
"go.uber.org/zap"
"os"
"strconv"
"strings"
"time"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
)
type TimeChunk struct {
+39 -31
View File
@@ -1,17 +1,18 @@
package export
import (
"crowsnest/internal/files"
"crowsnest/internal/sqlite"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
"gopkg.in/yaml.v3"
"os"
"sort"
"strings"
"time"
"gopkg.in/yaml.v3"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func WriteCredsToFile(creds []sqlite.User, outputFile string, fileType files.FileType) error {
@@ -34,8 +35,11 @@ func WriteCredsToFile(creds []sqlite.User, outputFile string, fileType files.Fil
case files.GREPPABLE:
var outStrings []string
for _, c := range creds {
outStrings = append(outStrings, fmt.Sprintf("email=%s\tusername=%s\tpassword=%s\n",
greppableValue(c.Email), greppableValue(c.Username), greppableValue(c.Password)))
var fields []string
fields = appendGreppableField(fields, "email", c.Email)
fields = appendGreppableField(fields, "username", c.Username)
fields = appendGreppableField(fields, "password", c.Password)
outStrings = append(outStrings, strings.Join(fields, " ")+"\n")
}
data = []byte(strings.Join(outStrings, ""))
default:
@@ -145,9 +149,9 @@ func WriteQueryResultsToFile(results []map[string]interface{}, outputFile string
rowStrings := make([]string, 0, len(keys))
for _, k := range keys {
rowStrings = append(rowStrings, fmt.Sprintf("%s=%s", k, greppableAnyValue(r[k])))
rowStrings = appendGreppableField(rowStrings, k, greppableAnyValue(r[k]))
}
outStrings = append(outStrings, strings.Join(rowStrings, "\t")+"\n")
outStrings = append(outStrings, strings.Join(rowStrings, " ")+"\n")
}
data = []byte(strings.Join(outStrings, ""))
default:
@@ -163,26 +167,25 @@ func WriteQueryResultsToFile(results []map[string]interface{}, outputFile string
}
func dehashedResultGreppable(r sqlite.Result) string {
fields := []string{
"id=" + greppableValue(r.DehashedId),
"email=" + greppableValue(strings.Join(r.Email, ",")),
"ip_address=" + greppableValue(strings.Join(r.IpAddress, ",")),
"username=" + greppableValue(strings.Join(r.Username, ",")),
"password=" + greppableValue(strings.Join(r.Password, ",")),
"hashed_password=" + greppableValue(strings.Join(r.HashedPassword, ",")),
"hash_type=" + greppableValue(r.HashType),
"name=" + greppableValue(strings.Join(r.Name, ",")),
"vin=" + greppableValue(strings.Join(r.Vin, ",")),
"license_plate=" + greppableValue(strings.Join(r.LicensePlate, ",")),
"url=" + greppableValue(strings.Join(r.Url, ",")),
"social=" + greppableValue(strings.Join(r.Social, ",")),
"cryptocurrency_address=" + greppableValue(strings.Join(r.CryptoCurrencyAddress, ",")),
"address=" + greppableValue(strings.Join(r.Address, ",")),
"phone=" + greppableValue(strings.Join(r.Phone, ",")),
"company=" + greppableValue(strings.Join(r.Company, ",")),
"database_name=" + greppableValue(r.DatabaseName),
}
return strings.Join(fields, "\t")
var fields []string
fields = appendGreppableField(fields, "id", r.DehashedId)
fields = appendGreppableField(fields, "email", strings.Join(r.Email, ","))
fields = appendGreppableField(fields, "ip_address", strings.Join(r.IpAddress, ","))
fields = appendGreppableField(fields, "username", strings.Join(r.Username, ","))
fields = appendGreppableField(fields, "password", strings.Join(r.Password, ","))
fields = appendGreppableField(fields, "hashed_password", strings.Join(r.HashedPassword, ","))
fields = appendGreppableField(fields, "hash_type", r.HashType)
fields = appendGreppableField(fields, "name", strings.Join(r.Name, ","))
fields = appendGreppableField(fields, "vin", strings.Join(r.Vin, ","))
fields = appendGreppableField(fields, "license_plate", strings.Join(r.LicensePlate, ","))
fields = appendGreppableField(fields, "url", strings.Join(r.Url, ","))
fields = appendGreppableField(fields, "social", strings.Join(r.Social, ","))
fields = appendGreppableField(fields, "cryptocurrency_address", strings.Join(r.CryptoCurrencyAddress, ","))
fields = appendGreppableField(fields, "address", strings.Join(r.Address, ","))
fields = appendGreppableField(fields, "phone", strings.Join(r.Phone, ","))
fields = appendGreppableField(fields, "company", strings.Join(r.Company, ","))
fields = appendGreppableField(fields, "database_name", r.DatabaseName)
return strings.Join(fields, " ")
}
func greppableAnyValue(value interface{}) string {
@@ -205,10 +208,15 @@ func greppableAnyValue(value interface{}) string {
}
func greppableValue(value string) string {
value = strings.ReplaceAll(value, "\r", " ")
value = strings.ReplaceAll(value, "\n", " ")
value = strings.ReplaceAll(value, "\t", " ")
return strings.TrimSpace(value)
return strings.Join(strings.Fields(value), "_")
}
func appendGreppableField(fields []string, key, value string) []string {
value = greppableValue(value)
if value == "" {
return fields
}
return append(fields, fmt.Sprintf("%s=%s", key, value))
}
func WriteWhoIsHistoryToFile(results []sqlite.HistoryRecord, outputFile string, fileType files.FileType) error {
+29
View File
@@ -0,0 +1,29 @@
package export
import (
"strings"
"testing"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func TestDehashedResultGreppableUsesSpaceSeparatedNonEmptyTokens(t *testing.T) {
got := dehashedResultGreppable(sqlite.Result{
DehashedId: "123",
Name: []string{"Hargrave Mall"},
Address: []string{"irving tx"},
Url: []string{"gdt.com", "GDT.COM"},
})
if strings.Contains(got, "\t") {
t.Fatalf("greppable output contains tab: %q", got)
}
if strings.Contains(got, "vin=") {
t.Fatalf("greppable output contains empty field: %q", got)
}
for _, want := range []string{"id=123", "name=Hargrave_Mall", "address=irving_tx", "url=gdt.com,GDT.COM"} {
if !strings.Contains(got, want) {
t.Fatalf("greppable output = %q, want token %q", got, want)
}
}
}
+4 -3
View File
@@ -1,13 +1,14 @@
package export
import (
"crowsnest/internal/files"
"crowsnest/internal/sqlite"
"encoding/json"
"encoding/xml"
"fmt"
"gopkg.in/yaml.v3"
"os"
"gopkg.in/yaml.v3"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func WriteIStringToFile(iString sqlite.IString, outputFile string, fileType files.FileType) error {
+4 -3
View File
@@ -1,14 +1,15 @@
package hunter_io
import (
"crowsnest/internal/debug"
"crowsnest/internal/sqlite"
"encoding/json"
"fmt"
"go.uber.org/zap"
"io"
"net/http"
"strings"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
const (
+2 -1
View File
@@ -1,10 +1,11 @@
package pretty
import (
"crowsnest/internal/sqlite"
"fmt"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
func WhoIsTree(root string, record sqlite.WhoisRecord) {
+2 -2
View File
@@ -90,11 +90,11 @@ const (
func GetTable(userInput string) Table {
switch strings.ToLower(userInput) {
case "results":
case "dehashed", "results":
return ResultsTable
case "runs":
return RunsTable
case "creds":
case "users", "creds":
return CredsTable
case "whois":
return WhoIsTable
+18
View File
@@ -0,0 +1,18 @@
package sqlite
import "testing"
func TestGetTableAcceptsDisplayedTableNames(t *testing.T) {
tests := map[string]Table{
"dehashed": ResultsTable,
"results": ResultsTable,
"users": CredsTable,
"creds": CredsTable,
}
for input, want := range tests {
if got := GetTable(input); got != want {
t.Fatalf("GetTable(%q) = %v, want %v", input, got, want)
}
}
}
+2 -1
View File
@@ -1,11 +1,12 @@
package sqlite
import (
"crowsnest/internal/files"
"fmt"
"go.uber.org/zap"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"hub.krkn.tech/KrakenTech/crowsnest/internal/files"
)
type QueryOptions struct {
+5 -4
View File
@@ -2,15 +2,16 @@ package whois
import (
"bytes"
"crowsnest/internal/debug"
"crowsnest/internal/dehashed"
"crowsnest/internal/sqlite"
"encoding/json"
"errors"
"fmt"
"go.uber.org/zap"
"io"
"net/http"
"go.uber.org/zap"
"hub.krkn.tech/KrakenTech/crowsnest/internal/debug"
"hub.krkn.tech/KrakenTech/crowsnest/internal/dehashed"
"hub.krkn.tech/KrakenTech/crowsnest/internal/sqlite"
)
type DehashedWHOISSearchRequest struct {