Skip to content

Comments

Add search Engine _ Onyphe#672

Merged
ehsandeep merged 8 commits intoprojectdiscovery:mainfrom
Xanderux:onyphe
May 22, 2025
Merged

Add search Engine _ Onyphe#672
ehsandeep merged 8 commits intoprojectdiscovery:mainfrom
Xanderux:onyphe

Conversation

@Xanderux
Copy link
Contributor

@Xanderux Xanderux commented May 6, 2025

Screenshot from 2025-04-28 14-09-02

Implement additional search engine that called Onyphe
If this code has some bug or improvements Please let me know in the comments

Ref: https://search.onyphe.io/
API docs: https://search.onyphe.io/docs/general-apis/search

Closes #196

Summary by CodeRabbit

  • New Features
    • Added support for the Onyphe search engine, allowing users to perform queries using the Onyphe data source.
    • Introduced a new command-line flag for Onyphe queries and integrated Onyphe API key management.
    • Onyphe is now included in the list of supported engines and rate-limited accordingly.
  • Tests
    • Added integration tests for the Onyphe search engine.
  • Documentation
    • Updated README to include Onyphe configuration, usage instructions, and API key setup.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 6, 2025

"""

Walkthrough

The changes introduce support for the Onyphe data source throughout the codebase. This includes implementing an Onyphe agent, integrating it into the provider and session management, adding command-line options, updating key handling, and providing integration tests. The system now supports querying Onyphe as a first-class engine alongside existing sources.

Changes

Files/Paths Change Summary
sources/agent/onyphe/onyphe.go, sources/agent/onyphe/response.go Added new Onyphe agent implementation and response data structures for querying the Onyphe API.
runner/options.go, uncover.go Integrated "onyphe" as a supported engine/agent in CLI options and service initialization.
sources/keys.go, sources/provider.go Extended key management to support Onyphe API keys in provider and session logic.
sources/session.go Added default rate limit configuration for Onyphe engine.
integration-tests/source-test.go, integration-tests/integration-test.go Added integration test cases for Onyphe, including API key handling and query execution.
README.md Updated documentation to include Onyphe engine, CLI flags, environment variables, and provider configuration.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant Service
    participant OnypheAgent
    participant OnypheAPI

    User->>CLI: Run with --engine onyphe or -on query
    CLI->>Service: Initialize with Onyphe options
    Service->>OnypheAgent: Query("google.com", API key)
    OnypheAgent->>OnypheAPI: HTTP GET /api/v2/simple/port/{query}/{page}
    OnypheAPI-->>OnypheAgent: JSON response (results)
    OnypheAgent-->>Service: Stream results via channel
    Service-->>CLI: Aggregate and return results
Loading

Assessment against linked issues

Objective Addressed Explanation
Add Onyphe as a supported engine/agent (#196)
Implement Onyphe API integration and result parsing (#196)
Support Onyphe API key management in provider/session (#196)
Add CLI and integration test support for Onyphe (#196)

Poem

A hop and a skip, a new engine appears,
Onyphe now joins, let’s all give three cheers!
With keys in the warren and queries that flow,
Results from new sources, as fast as we go.
🐇✨ The code leaps ahead, uncovering more—
The search just got stronger than ever before!
"""

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 5648f3c and 85bf85e.

📒 Files selected for processing (1)
  • README.md (4 hunks)
✅ Files skipped from review due to trivial changes (1)
  • README.md

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (5)
integration-tests/source-test.go (1)

249-266: Implementation looks good, but consider using a more specific test query.

The Onyphe test implementation follows the same pattern as other test cases, which is good for consistency. However, consider using a more specific query similar to other test cases (e.g., a targeted query like "'app=Grafana'" used in other tests) rather than the generic "google.com" to better validate the specific search capabilities of Onyphe.

sources/agent/onyphe/onyphe.go (4)

15-15: Consider moving URL components to separate constants for better maintainability

The URL template contains several hardcoded values that may require changes in the future. Breaking these into separate constants would improve clarity and maintainability.

-const (
-	URLTemplate = "https://www.onyphe.io/api/v2/search/?q=%s&page=%d&size=10"
-)
+const (
+	BaseURL    = "https://www.onyphe.io/api/v2/search/"
+	DefaultPageSize = 10
+	URLTemplate = BaseURL + "?q=%s&page=%d&size=" + fmt.Sprintf("%d", DefaultPageSize)
+)

64-92: Add early return when limit is reached

To avoid unnecessary API calls, check if the limit has been reached before processing each result.

 func (agent *Agent) query(session *sources.Session, onypheRequest OnypheRequest, results chan sources.Result) *OnypheResponse {
 	resp, err := agent.queryURL(session, &onypheRequest)
 	if err != nil {
 		results <- sources.Result{Source: agent.Name(), Error: err}
 		return nil
 	}
 	defer resp.Body.Close()
 
 	body, err := io.ReadAll(resp.Body)
 	if err != nil {
 		results <- sources.Result{Source: agent.Name(), Error: err}
 		return nil
 	}
 
 	var apiResponse OnypheResponse
 	if err := json.Unmarshal(body, &apiResponse); err != nil {
 		results <- sources.Result{Source: agent.Name(), Error: err}
 		return nil
 	}
 
+	// Check if API returned an error code
+	if apiResponse.Error != 0 {
+		results <- sources.Result{Source: agent.Name(), Error: fmt.Errorf("API returned error code: %d", apiResponse.Error)}
+		return nil
+	}
+
 	for _, result := range apiResponse.Results {
 		results <- sources.Result{
 			Source: agent.Name(),
 			IP:     result.IP,
 			Port:   result.Port,
 		}
 	}
 	return &apiResponse
 }

18-21: Consider adding comments to struct definition

Adding descriptive comments to the struct definition would improve code documentation and help future maintainers understand the purpose of each field.

+// OnypheRequest contains the parameters needed to query the Onyphe API
 type OnypheRequest struct {
+	// Query is the search term to look for
 	Query string
+	// Page is the pagination parameter (1-based)
 	Page  int
 }

23-23: Add struct documentation

The Agent struct is currently undocumented. Adding a comment would improve code clarity.

+// Agent implements the sources.Agent interface for Onyphe
 type Agent struct{}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4d7a82 and ca8b38c.

⛔ Files ignored due to path filters (1)
  • sources/agent/onyphe/example.json is excluded by !**/*.json
📒 Files selected for processing (9)
  • integration-tests/integration-test.go (1 hunks)
  • integration-tests/source-test.go (1 hunks)
  • runner/options.go (7 hunks)
  • sources/agent/onyphe/onyphe.go (1 hunks)
  • sources/agent/onyphe/response.go (1 hunks)
  • sources/keys.go (2 hunks)
  • sources/provider.go (4 hunks)
  • sources/session.go (1 hunks)
  • uncover.go (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
uncover.go (2)
sources/agent/onyphe/onyphe.go (1)
  • Agent (23-23)
sources/agent.go (1)
  • Agent (8-11)
sources/agent/onyphe/onyphe.go (6)
sources/agent.go (1)
  • Query (3-6)
sources/session.go (1)
  • Session (37-42)
sources/agent/onyphe/response.go (2)
  • Result (11-14)
  • OnypheResponse (3-9)
sources/keys.go (1)
  • Keys (3-22)
uncover.go (1)
  • New (54-106)
sources/util.go (1)
  • NewHTTPRequest (10-17)
🔇 Additional comments (10)
sources/session.go (1)

33-33: Rate limit for Onyphe API looks appropriate

The addition of Onyphe to the DefaultRateLimits map with a rate limit of 1 request per second is consistent with most other engines in the system and aligns with Onyphe's API requirements.

integration-tests/integration-test.go (1)

35-35: Integration test for Onyphe properly registered

The Onyphe test cases are correctly added to the tests map, following the same pattern as other data sources in the integration test framework.

sources/keys.go (2)

21-21: Onyphe API key field properly added

The OnypheKey field has been correctly added to the Keys struct to store the API key needed for authentication with the Onyphe service.


41-42: Empty() method correctly updated

The Empty() method has been properly updated to include the check for the OnypheKey, ensuring the method accurately reports if any API keys are configured.

uncover.go (3)

19-19: Onyphe agent package import correctly added

The import for the onyphe package is properly added to the imports list.


86-87: Onyphe agent properly integrated

The Onyphe agent is correctly instantiated and added to the service's Agents slice when "onyphe" is selected, following the same pattern as other agents.


192-192: Onyphe agent included in AllAgents()

The "onyphe" engine is properly added to the list of all supported agents returned by the AllAgents() method.

runner/options.go (1)

62-62: Integration looks clean and consistent.

The Onyphe engine has been properly added to all relevant parts of the options handling code:

  • Added to the Options struct
  • Included in the engine description list
  • Added as a command-line flag with appropriate shorthand
  • Included in all validation checks
  • Added to the query appending logic

This approach maintains consistency with other engines in the codebase.

Also applies to: 74-74, 93-93, 167-167, 238-238, 264-264, 306-306

sources/provider.go (1)

37-37: Provider integration looks correct.

The Onyphe provider has been properly added to all relevant parts of the provider:

  • Added to the Provider struct for storing API keys
  • Included in the key retrieval logic
  • Added to the environment variable loading process
  • Included in the HasKeys validation check

The implementation follows the established pattern for provider integration.

Also applies to: 120-122, 170-170, 189-189

sources/agent/onyphe/onyphe.go (1)

1-12: The API implementation looks good overall

The Onyphe agent implementation follows the existing pattern for other agents in the codebase. It correctly implements pagination, error handling, and API authentication.

Comment on lines +86 to +87
case "onyphe":
s.Agents = append(s.Agents, &onyphe.Agent{})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the Agent implementation

While the agent integration looks correct, it would be beneficial to verify that the Onyphe agent properly implements the required interface methods and has appropriate error handling.


🏁 Script executed:

#!/bin/bash
# Verify that the Onyphe agent implements the required interface methods

# Check if the Onyphe agent implements the Name() method
echo "Checking for Name() method implementation:"
rg -A 2 "func \(\*?Agent\) Name\(\)" sources/agent/onyphe/

# Check if the Onyphe agent implements the Query() method
echo "Checking for Query() method implementation:"
rg -A 5 "func \(\*?Agent\) Query\(" sources/agent/onyphe/

# Check error handling in the Query method
echo "Checking error handling in Query method:"
rg "if err" -A 2 -B 2 sources/agent/onyphe/onyphe.go

Length of output: 1152


🏁 Script executed:

#!/bin/bash
# Locate the Agent interface and its required methods

echo "Searching for Agent interface definition:"
rg -n "type .*Agent interface"

echo
echo "Context around Agent interface:"
rg -n -A5 -B5 "type .*Agent interface"

echo
echo "Searching for Name() method in interface files:"
rg -n "Name()" -g "*.go"

echo
echo "Searching for Query() method in interface files:"
rg -n "Query(" -g "*.go"

Length of output: 9984


Implement missing Query() and standardize error handling

The Onyphe agent currently only exposes Name() but does not satisfy the Agent interface (which requires Query(*Session, *Query) (chan Result, error)) and its internal query helper returns errors instead of emitting them to the results channel.

Please update sources/agent/onyphe/onyphe.go as follows:

  • Add the public Query method matching the interface in sources/agent.go (lines 8–11):
    func (agent *Agent) Query(session *sources.Session, q *sources.Query) (chan sources.Result, error) {
      results := make(chan sources.Result)
      go func() {
        defer close(results)
        // translate sources.Query → OnypheRequest and invoke internal query
        agent.query(session, onypheReq, results)
      }()
      return results, nil
    }
  • Unify error handling inside the internal query function so that every error is sent to results (rather than returning it):
     request, err := sources.NewHTTPRequest(...)
  • if err != nil {
  • return nil, err
  • }
  • if err != nil {
  • results <- sources.Result{Source: agent.Name(), Error: err}
  • return nil
  • }

With these changes the Onyphe agent will fully implement the interface and handle all errors consistently.

<!-- This is an auto-generated comment by CodeRabbit -->

Xanderux and others added 2 commits May 12, 2025 13:32
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
sources/agent/onyphe/onyphe.go (1)

29-62: Implement support for query limit parameter

The Query struct from sources/agent.go contains a Limit field, but this implementation doesn't use it. The agent should respect the user's requested limit on the number of results.

 func (agent *Agent) Query(session *sources.Session, query *sources.Query) (chan sources.Result, error) {
 	if session.Keys.OnypheKey == "" {
 		return nil, errors.New("empty Onyphe API key")
 	}
 
 	results := make(chan sources.Result)
 
 	go func() {
 		defer close(results)
 
 		currentPage := 1
 		totalResults := 0
+		maxResults := query.Limit
 
 		for {
 			onypheRequest := &OnypheRequest{
 				Query: query.Query,
 				Page:  currentPage,
 			}
 
 			apiResponse := agent.query(session, *onypheRequest, results)
 			if apiResponse == nil {
 				break
 			}
 
 			totalResults += len(apiResponse.Results)
-			if totalResults >= apiResponse.Total || len(apiResponse.Results) == 0 {
+			if totalResults >= apiResponse.Total || len(apiResponse.Results) == 0 || (maxResults > 0 && totalResults >= maxResults) {
 				break
 			}
 			currentPage++
 		}
 	}()
 
 	return results, nil
 }
🧹 Nitpick comments (3)
sources/agent/onyphe/onyphe.go (3)

15-15: Consider making page size configurable instead of hardcoded

The URL template contains a hardcoded page size of 10. This might be better defined as a configurable constant to allow for flexibility in the number of results per page.

-	URLTemplate = "https://www.onyphe.io/api/v2/search/?q=%s&page=%d&size=10"
+	DefaultPageSize = 10
+	URLTemplate = "https://www.onyphe.io/api/v2/search/?q=%s&page=%d&size=%d"

Then update the queryURL method to use this constant.


84-90: Add validation for API response data

The code doesn't validate that the response contains valid data before using it. Consider adding basic validation for the result fields before sending them to the results channel.

 for _, result := range apiResponse.Results {
+	// Skip results with empty IP addresses
+	if result.IP == "" {
+		continue
+	}
+
 	results <- sources.Result{
 		Source: agent.Name(),
 		IP:     result.IP,
 		Port:   result.Port,
 	}
 }

94-115: Ensure proper handling of API request errors

Your implementation now handles the basic HTTP status code errors, which is good. However, you might want to add more specific error handling for different status codes to give users better diagnostics.

 if resp.StatusCode != http.StatusOK {
-	return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
+	switch resp.StatusCode {
+	case http.StatusUnauthorized, http.StatusForbidden:
+		return nil, fmt.Errorf("authentication error: invalid API key or insufficient permissions (status code: %d)", resp.StatusCode)
+	case http.StatusTooManyRequests:
+		return nil, fmt.Errorf("rate limit exceeded (status code: %d)", resp.StatusCode)
+	default:
+		return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
+	}
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between ca8b38c and d57330a.

📒 Files selected for processing (1)
  • sources/agent/onyphe/onyphe.go (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
sources/agent/onyphe/onyphe.go (6)
sources/agent.go (1)
  • Query (3-6)
sources/session.go (1)
  • Session (37-42)
sources/agent/onyphe/response.go (2)
  • Result (11-14)
  • OnypheResponse (3-9)
sources/keys.go (1)
  • Keys (3-22)
uncover.go (1)
  • New (54-106)
sources/util.go (1)
  • NewHTTPRequest (10-17)

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@ehsandeep ehsandeep requested a review from dogancanbakir May 12, 2025 12:44
@dogancanbakir
Copy link
Member

@Xanderux Thanks for the PR!

@dogancanbakir dogancanbakir requested a review from ehsandeep May 14, 2025 03:52
@Xanderux
Copy link
Contributor Author

any advice @ehsandeep ? 😃

@dogancanbakir
Copy link
Member

dogancanbakir commented May 22, 2025

@Xanderux I forgot to mention it. Could you update the README to add this provider? Thanks! See https://github.com/projectdiscovery/uncover?tab=readme-ov-file#provider-configuration - Once it's done, we can merge this.

@Xanderux
Copy link
Contributor Author

@Xanderux I forgot to mention it. Could you update the README to add this provider? Thanks! See https://github.com/projectdiscovery/uncover?tab=readme-ov-file#provider-configuration - Once it's done, we can merge this.

done, sorry for the omission @dogancanbakir ;)

@ehsandeep ehsandeep merged commit efcd52c into projectdiscovery:main May 22, 2025
1 check passed
This was referenced Jun 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Onyphe

3 participants