-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat: add secret file authentication support (-sf flag) #2371
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
Changes from 6 commits
b60bfa2
62eed15
a780d05
a4ae407
fb1ea1c
c125352
93633d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package authx | ||
|
|
||
| import ( | ||
| "net/http" | ||
|
|
||
| "github.com/projectdiscovery/retryablehttp-go" | ||
| ) | ||
|
|
||
| var ( | ||
| _ AuthStrategy = &BasicAuthStrategy{} | ||
| ) | ||
|
|
||
| // BasicAuthStrategy is a strategy for basic auth | ||
| type BasicAuthStrategy struct { | ||
| Data *Secret | ||
| } | ||
|
|
||
| // NewBasicAuthStrategy creates a new basic auth strategy | ||
| func NewBasicAuthStrategy(data *Secret) *BasicAuthStrategy { | ||
| return &BasicAuthStrategy{Data: data} | ||
| } | ||
|
|
||
| // Apply applies the basic auth strategy to the request | ||
| func (s *BasicAuthStrategy) Apply(req *http.Request) { | ||
| req.SetBasicAuth(s.Data.Username, s.Data.Password) | ||
| } | ||
|
|
||
| // ApplyOnRR applies the basic auth strategy to the retryable request | ||
| func (s *BasicAuthStrategy) ApplyOnRR(req *retryablehttp.Request) { | ||
| req.SetBasicAuth(s.Data.Username, s.Data.Password) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package authx | ||
|
|
||
| import ( | ||
| "net/http" | ||
|
|
||
| "github.com/projectdiscovery/retryablehttp-go" | ||
| ) | ||
|
|
||
| var ( | ||
| _ AuthStrategy = &BearerTokenAuthStrategy{} | ||
| ) | ||
|
|
||
| // BearerTokenAuthStrategy is a strategy for bearer token auth | ||
| type BearerTokenAuthStrategy struct { | ||
| Data *Secret | ||
| } | ||
|
|
||
| // NewBearerTokenAuthStrategy creates a new bearer token auth strategy | ||
| func NewBearerTokenAuthStrategy(data *Secret) *BearerTokenAuthStrategy { | ||
| return &BearerTokenAuthStrategy{Data: data} | ||
| } | ||
|
|
||
| // Apply applies the bearer token auth strategy to the request | ||
| func (s *BearerTokenAuthStrategy) Apply(req *http.Request) { | ||
| req.Header.Set("Authorization", "Bearer "+s.Data.Token) | ||
| } | ||
|
|
||
| // ApplyOnRR applies the bearer token auth strategy to the retryable request | ||
| func (s *BearerTokenAuthStrategy) ApplyOnRR(req *retryablehttp.Request) { | ||
| req.Header.Set("Authorization", "Bearer "+s.Data.Token) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| package authx | ||
|
|
||
| import ( | ||
| "net/http" | ||
|
|
||
| "github.com/projectdiscovery/retryablehttp-go" | ||
| ) | ||
|
|
||
| var ( | ||
| _ AuthStrategy = &CookiesAuthStrategy{} | ||
| ) | ||
|
|
||
| // CookiesAuthStrategy is a strategy for cookies auth | ||
| type CookiesAuthStrategy struct { | ||
| Data *Secret | ||
| } | ||
|
|
||
| // NewCookiesAuthStrategy creates a new cookies auth strategy | ||
| func NewCookiesAuthStrategy(data *Secret) *CookiesAuthStrategy { | ||
| return &CookiesAuthStrategy{Data: data} | ||
| } | ||
|
|
||
| // Apply applies the cookies auth strategy to the request | ||
| func (s *CookiesAuthStrategy) Apply(req *http.Request) { | ||
| for _, cookie := range s.Data.Cookies { | ||
| req.AddCookie(&http.Cookie{ | ||
| Name: cookie.Key, | ||
| Value: cookie.Value, | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| // ApplyOnRR applies the cookies auth strategy to the retryable request | ||
| func (s *CookiesAuthStrategy) ApplyOnRR(req *retryablehttp.Request) { | ||
| // Build a set of cookie names to replace | ||
| newCookieNames := make(map[string]struct{}, len(s.Data.Cookies)) | ||
| for _, cookie := range s.Data.Cookies { | ||
| newCookieNames[cookie.Key] = struct{}{} | ||
| } | ||
|
|
||
| // Filter existing cookies, keeping only those not being replaced | ||
| existingCookies := req.Cookies() | ||
| filteredCookies := make([]*http.Cookie, 0, len(existingCookies)) | ||
| for _, cookie := range existingCookies { | ||
| if _, shouldReplace := newCookieNames[cookie.Name]; !shouldReplace { | ||
| filteredCookies = append(filteredCookies, cookie) | ||
| } | ||
| } | ||
|
|
||
| // Clear and reset cookies | ||
| req.Header.Del("Cookie") | ||
| for _, cookie := range filteredCookies { | ||
| req.AddCookie(cookie) | ||
| } | ||
| // Add new cookies | ||
| for _, cookie := range s.Data.Cookies { | ||
| req.AddCookie(&http.Cookie{ | ||
| Name: cookie.Key, | ||
| Value: cookie.Value, | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,244 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package authx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "encoding/json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "path/filepath" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "regexp" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/projectdiscovery/utils/errkit" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/projectdiscovery/utils/generic" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| stringsutil "github.com/projectdiscovery/utils/strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "gopkg.in/yaml.v3" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type AuthType string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BasicAuth AuthType = "BasicAuth" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BearerTokenAuth AuthType = "BearerToken" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HeadersAuth AuthType = "Header" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CookiesAuth AuthType = "Cookie" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| QueryAuth AuthType = "Query" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // SupportedAuthTypes returns the supported auth types | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func SupportedAuthTypes() []string { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return []string{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string(BasicAuth), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string(BearerTokenAuth), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string(HeadersAuth), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string(CookiesAuth), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| string(QueryAuth), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Authx is a struct for secrets or credentials file | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type Authx struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ID string `json:"id" yaml:"id"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Info AuthFileInfo `json:"info" yaml:"info"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Secrets []Secret `json:"static" yaml:"static"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type AuthFileInfo struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Name string `json:"name" yaml:"name"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Author string `json:"author" yaml:"author"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Severity string `json:"severity" yaml:"severity"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Description string `json:"description" yaml:"description"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Secret is a struct for secret or credential | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type Secret struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Type string `json:"type" yaml:"type"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Domains []string `json:"domains" yaml:"domains"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DomainsRegex []string `json:"domains-regex" yaml:"domains-regex"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Headers []KV `json:"headers" yaml:"headers"` // Headers preserve exact casing (useful for case-sensitive APIs) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Cookies []Cookie `json:"cookies" yaml:"cookies"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Params []KV `json:"params" yaml:"params"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Username string `json:"username" yaml:"username"` // can be either email or username | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Password string `json:"password" yaml:"password"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Token string `json:"token" yaml:"token"` // Bearer Auth token | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetStrategy returns the auth strategy for the secret | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (s *Secret) GetStrategy() AuthStrategy { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(BasicAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NewBasicAuthStrategy(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(BearerTokenAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NewBearerTokenAuthStrategy(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(HeadersAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NewHeadersAuthStrategy(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(CookiesAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NewCookiesAuthStrategy(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(QueryAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return NewQueryAuthStrategy(s) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (s *Secret) Validate() error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !stringsutil.EqualFoldAny(s.Type, SupportedAuthTypes()...) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid type: %s", s.Type) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(s.Domains) == 0 && len(s.DomainsRegex) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("domains or domains-regex cannot be empty") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(s.DomainsRegex) > 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, domain := range s.DomainsRegex { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _, err := regexp.Compile(domain) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid domain regex: %s", domain) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(BasicAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if s.Username == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("username cannot be empty in basic auth") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if s.Password == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("password cannot be empty in basic auth") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(BearerTokenAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if s.Token == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("token cannot be empty in bearer token auth") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(HeadersAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(s.Headers) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("headers cannot be empty in headers auth") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, header := range s.Headers { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := header.Validate(); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid header in headersAuth: %s", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(CookiesAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(s.Cookies) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("cookies cannot be empty in cookies auth") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, cookie := range s.Cookies { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if cookie.Raw != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := cookie.Parse(); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid raw cookie in cookiesAuth: %s", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := cookie.Validate(); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid cookie in cookiesAuth: %s", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+119
to
+132
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Raw cookie parsing doesn't persist to original slice. The loop iterates over Proposed fix - iterate by index case strings.EqualFold(s.Type, string(CookiesAuth)):
if len(s.Cookies) == 0 {
return fmt.Errorf("cookies cannot be empty in cookies auth")
}
- for _, cookie := range s.Cookies {
- if cookie.Raw != "" {
- if err := cookie.Parse(); err != nil {
+ for i := range s.Cookies {
+ if s.Cookies[i].Raw != "" {
+ if err := s.Cookies[i].Parse(); err != nil {
return fmt.Errorf("invalid raw cookie in cookiesAuth: %s", err)
}
}
- if err := cookie.Validate(); err != nil {
+ if err := s.Cookies[i].Validate(); err != nil {
return fmt.Errorf("invalid cookie in cookiesAuth: %s", err)
}
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case strings.EqualFold(s.Type, string(QueryAuth)): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(s.Params) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("query cannot be empty in query auth") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, query := range s.Params { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := query.Validate(); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid query in queryAuth: %s", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type KV struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Key string `json:"key" yaml:"key"` // Header key (preserves exact casing) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Value string `json:"value" yaml:"value"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (k *KV) Validate() error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if k.Key == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("key cannot be empty") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if k.Value == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("value cannot be empty") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type Cookie struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Key string `json:"key" yaml:"key"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Value string `json:"value" yaml:"value"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Raw string `json:"raw" yaml:"raw"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (c *Cookie) Validate() error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if c.Raw != "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if c.Key == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("key cannot be empty") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if c.Value == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("value cannot be empty") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Parse parses the cookie | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // in raw the cookie is in format of | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>; Path=<path>; Domain=<domain_name>; Secure; HttpOnly | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (c *Cookie) Parse() error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if c.Raw == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("raw cookie cannot be empty") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tmp := strings.TrimPrefix(c.Raw, "Set-Cookie: ") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| slice := strings.Split(tmp, ";") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(slice) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid raw cookie no ; found") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // first element is the cookie name and value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Use SplitN to preserve '=' characters in the cookie value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cookie := strings.SplitN(slice[0], "=", 2) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(cookie) != 2 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid raw cookie: missing '=' in cookie name=value: %s", c.Raw) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| c.Key = strings.TrimSpace(cookie[0]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| c.Value = strings.TrimSpace(cookie[1]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if c.Key == "" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("invalid raw cookie: empty cookie name: %s", c.Raw) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetAuthDataFromFile reads the auth data from file | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func GetAuthDataFromFile(file string) (*Authx, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ext := strings.ToLower(filepath.Ext(file)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !generic.EqualsAny(ext, ".yml", ".yaml", ".json") { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("invalid file extension: supported extensions are .yml,.yaml and .json got %s", ext) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bin, err := os.ReadFile(file) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, err | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ext == ".yml" || ext == ".yaml" { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return GetAuthDataFromYAML(bin) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return GetAuthDataFromJSON(bin) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetAuthDataFromYAML reads the auth data from yaml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func GetAuthDataFromYAML(data []byte) (*Authx, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var auth Authx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err := yaml.Unmarshal(data, &auth) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorErr := errkit.FromError(err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorErr.Msgf("could not unmarshal yaml") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, errorErr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return &auth, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // GetAuthDataFromJSON reads the auth data from json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func GetAuthDataFromJSON(data []byte) (*Authx, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var auth Authx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err := json.Unmarshal(data, &auth) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorErr := errkit.FromError(err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errorErr.Msgf("could not unmarshal json") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, errorErr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return &auth, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.