Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
adfb73f
Add SDK auth directory structure and AuthContext class (#2)
Mar 19, 2026
ad3dcad
Add SDK auth error codes and AuthError exception (#2)
Mar 19, 2026
102cf39
Add SDK OAuth model - ProtectedResourceMetadata (RFC 9728) (#2)
Mar 19, 2026
b3f19b2
Add SDK OAuth models - AuthorizationServerMetadata and OpenIdConfigur…
Mar 19, 2026
6df6329
Add SDK OAuth model - ClientRegistrationResponse and WwwAuthenticate …
Mar 19, 2026
530a7f6
Add example project structure and Gemfile (#2)
Mar 19, 2026
d1c3932
Add example Config class with file parsing (#2)
Mar 19, 2026
c93a144
Add CORS middleware with proper headers (#2)
Mar 19, 2026
1815f14
Add health endpoint with CORS (#2)
Mar 19, 2026
7a0e96d
Add OAuth discovery endpoint - Protected Resource Metadata (RFC 9728)…
Mar 19, 2026
3e72717
Add OAuth discovery endpoints - Authorization Server and OpenID Conne…
Mar 19, 2026
4c1af4d
Add OAuth endpoints - Authorize redirect and Dynamic Client Registrat…
Mar 19, 2026
1dabde7
Add OAuth auth middleware - path checking and token extraction (#2)
Mar 19, 2026
4a7ad6c
Add OAuth auth middleware - unauthorized response with WWW-Authentica…
Mar 19, 2026
cdb86e1
Add MCP handler - JSON-RPC 2.0 request/response and error codes (#2)
Mar 19, 2026
26bb240
Add MCP handler - tool registration and method dispatch (#2)
Mar 19, 2026
faaeae1
Add MCP handler - method implementations (#2)
Mar 19, 2026
f60f825
Add MCP HTTP endpoints with CORS (#2)
Mar 19, 2026
919d83d
Add weather tools with scope-based access control (#2)
Mar 19, 2026
555ab55
Add main application entry point and run scripts (#2)
Mar 19, 2026
ed9ff64
Update gopher-orch submodule to br_release branch (#2)
Mar 19, 2026
6f244a0
Add auth example to build script (#2)
Mar 19, 2026
3fa6d25
Resolve auth example for Ruby 4.0 compatibility (#2)
Mar 19, 2026
12dd051
Improve server_url derivation from port (#2)
Mar 19, 2026
d706562
Update OAuth endpoints helpers not being registered (#2)
Mar 19, 2026
062cf9d
Resolve unit tests for helpers pattern and mock apps (#2)
Mar 19, 2026
1657489
Add example server configuration file (#2)
Mar 19, 2026
d1cfa33
Format code (#2)
Mar 19, 2026
348dbcc
Resolve RuboCop-induced test failures (#2)
Mar 19, 2026
edb67bf
Update RuboCop cop name: RSpec/Rails -> RSpecRails (#2)
Mar 19, 2026
12dfa4a
Add rubocop wrapper script for Homebrew Ruby (#2)
Mar 19, 2026
e7f8d6c
Clean up RuboCop config and fix all offenses (#2)
Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "third_party/gopher-orch"]
path = third_party/gopher-orch
url = https://github.com/GopherSecurity/gopher-orch.git
branch = br_release
119 changes: 119 additions & 0 deletions .rspec_status
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
example_id | status | run_time |
-------------------------------------------------------------------------- | ------- | --------------- |
./spec/agent_result_spec.rb[1:1:1] | passed | 0.00277 seconds |
./spec/agent_result_spec.rb[1:2:1] | passed | 0.00014 seconds |
./spec/agent_result_spec.rb[1:3:1] | passed | 0.0001 seconds |
./spec/agent_result_status_spec.rb[1:1:1] | passed | 0.00009 seconds |
./spec/agent_result_status_spec.rb[1:2:1] | passed | 0.00008 seconds |
./spec/agent_result_status_spec.rb[1:3:1] | passed | 0.00009 seconds |
./spec/agent_result_status_spec.rb[1:4:1] | passed | 0.00008 seconds |
./spec/agent_result_status_spec.rb[1:5:1] | passed | 0.00008 seconds |
./spec/agent_result_status_spec.rb[1:6:1] | passed | 0.0001 seconds |
./spec/agent_result_status_spec.rb[1:6:2] | passed | 0.00008 seconds |
./spec/config_builder_spec.rb[1:1:1] | passed | 0.00053 seconds |
./spec/config_builder_spec.rb[1:2:1:1] | passed | 0.00013 seconds |
./spec/config_builder_spec.rb[1:2:2:1] | passed | 0.0001 seconds |
./spec/config_builder_spec.rb[1:2:3:1] | passed | 0.0001 seconds |
./spec/config_builder_spec.rb[1:3:1] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:1:1] | passed | 0.00013 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:1] | passed | 0.00017 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:2] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:3] | passed | 0.00013 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:4] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:5] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:6:1] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:6:2] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:2:7:1] | passed | 0.00014 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:3:1] | passed | 0.00011 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:4:1] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:4:2] | passed | 0.00012 seconds |
./spec/gopher_orch/auth/auth_context_spec.rb[1:4:3] | passed | 0.00014 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:1] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:2] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:3] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:4] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:5] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:6] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:7] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:8] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:9] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:10] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:11] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:12] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:1:13] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:1] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:2] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:3] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:4] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:5] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:6] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:7] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:8] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:9] | passed | 0.00016 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:10] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:11] | passed | 0.00007 seconds |
./spec/gopher_orch/auth/errors_spec.rb[1:2:12] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/errors_spec.rb[2:1:1] | passed | 0.00011 seconds |
./spec/gopher_orch/auth/errors_spec.rb[2:1:2] | passed | 0.00722 seconds |
./spec/gopher_orch/auth/errors_spec.rb[2:1:3] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/errors_spec.rb[2:2:1] | passed | 0.00132 seconds |
./spec/gopher_orch/auth/errors_spec.rb[2:2:2] | passed | 0.00012 seconds |
./spec/gopher_orch/auth/oauth/authorization_server_metadata_spec.rb[1:1:1] | passed | 0.00012 seconds |
./spec/gopher_orch/auth/oauth/authorization_server_metadata_spec.rb[1:1:2] | passed | 0.00011 seconds |
./spec/gopher_orch/auth/oauth/authorization_server_metadata_spec.rb[1:2:1] | passed | 0.00012 seconds |
./spec/gopher_orch/auth/oauth/authorization_server_metadata_spec.rb[1:2:2] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/authorization_server_metadata_spec.rb[1:2:3] | passed | 0.00102 seconds |
./spec/gopher_orch/auth/oauth/authorization_server_metadata_spec.rb[1:3:1] | passed | 0.00014 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:1:1] | passed | 0.00011 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:1:2] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:1:3] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:2:1] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:2:2] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:2:3] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:3:1] | passed | 0.00011 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:3:2] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/client_registration_response_spec.rb[1:4:1] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:1:1] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:2:1] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:2:2] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:3:1] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:3:2] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:3:3] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:4:1] | passed | 0.00011 seconds |
./spec/gopher_orch/auth/oauth/openid_configuration_spec.rb[1:5:1] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:1:1] | passed | 0.00017 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:1:2] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:1:3] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:2:1] | passed | 0.00011 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:2:2] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:2:3] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:3:1] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:3:2] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/oauth/protected_resource_metadata_spec.rb[1:4:1] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:1:1] | passed | 0.00214 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:1:2] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:1:3] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:2:1] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:2:2] | passed | 0.00012 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:2:3] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:2:4] | passed | 0.00008 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:2:5] | passed | 0.00035 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:2:6] | passed | 0.0001 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:2:7] | passed | 0.00009 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:3:1] | passed | 0.00069 seconds |
./spec/gopher_orch/auth/www_authenticate_spec.rb[1:3:2] | passed | 0.00013 seconds |
./spec/gopher_orch_spec.rb[1:1:1] | passed | 0.00082 seconds |
./spec/gopher_orch_spec.rb[1:2:1] | passed | 0.01189 seconds |
./spec/gopher_orch_spec.rb[1:3:1:1] | pending | 0.00016 seconds |
./spec/gopher_orch_spec.rb[1:4:1] | passed | 0.00012 seconds |
./spec/gopher_orch_spec.rb[1:5:1] | passed | 0.00011 seconds |
./spec/gopher_orch_spec.rb[1:5:2] | passed | 0.0009 seconds |
./spec/gopher_orch_spec.rb[1:6:1] | passed | 0.00135 seconds |
./spec/gopher_orch_spec.rb[1:7:1] | passed | 0.00014 seconds |
./spec/native_spec.rb[1:1:1] | passed | 0.0001 seconds |
./spec/native_spec.rb[1:2:1] | passed | 0.00013 seconds |
./spec/native_spec.rb[1:3:1] | passed | 6.21 seconds |
./spec/native_spec.rb[1:3:2] | passed | 1.1 seconds |
./spec/native_spec.rb[1:4:1] | passed | 2.37 seconds |
./spec/native_spec.rb[1:5:1] | passed | 0.00014 seconds |
./spec/native_spec.rb[1:6:1] | passed | 0.0001 seconds |
139 changes: 134 additions & 5 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,52 @@ AllCops:
- 'examples/server*/**/*'
- 'third_party/**/*'
- 'native/**/*'
- 'bin/**/*'

# Layout
Layout/LineLength:
Max: 120
Exclude:
- 'spec/**/*'
- 'examples/**/*'
- '*.gemspec'

Layout/MultilineMethodCallIndentation:
EnforcedStyle: indented

# Metrics
# Metrics - relaxed for this project
Metrics/BlockLength:
Exclude:
- 'spec/**/*'
- 'examples/**/*'
- '*.gemspec'

Metrics/MethodLength:
Max: 20
Max: 25
Exclude:
- 'examples/**/*'

Metrics/ClassLength:
Max: 150

Metrics/AbcSize:
Max: 25

Metrics/ModuleLength:
Max: 120
Exclude:
- 'examples/**/*'

Metrics/CyclomaticComplexity:
Max: 10
Exclude:
- 'examples/**/*'

Metrics/PerceivedComplexity:
Max: 10
Exclude:
- 'examples/**/*'

# Style
Style/Documentation:
Enabled: false
Expand All @@ -54,18 +77,124 @@ Style/TrailingCommaInArrayLiteral:
Style/TrailingCommaInHashLiteral:
EnforcedStyleForMultiline: consistent_comma

Style/ClassVars:
Exclude:
- 'examples/**/*'

Style/MultilineBlockChain:
Exclude:
- 'examples/**/*'
- 'spec/**/*'

# Naming
Naming/FileName:
Exclude:
- 'Gemfile'
- 'Rakefile'

# RSpec
Naming/AccessorMethodName:
Exclude:
- 'examples/**/*'

Naming/PredicateMethod:
Enabled: false

Naming/PredicatePrefix:
Enabled: false

# Lint
Lint/ConstantDefinitionInBlock:
Exclude:
- 'spec/**/*'

# RSpec cops
RSpec/ExampleLength:
Max: 15
Max: 25
Exclude:
- 'examples/**/*'

RSpec/MultipleExpectations:
Max: 5
Max: 12
Exclude:
- 'examples/**/*'

RSpec/NestedGroups:
Max: 4

RSpec/MultipleMemoizedHelpers:
Max: 10

RSpec/FilePath:
Enabled: false

RSpec/SpecFilePathFormat:
Enabled: false

RSpec/DescribeClass:
Enabled: false

RSpec/DescribedClass:
Enabled: false

RSpec/ContextWording:
Exclude:
- 'examples/**/*'

RSpec/MultipleDescribes:
Exclude:
- 'examples/**/*'
- 'spec/**/*'

RSpec/VerifiedDoubles:
Exclude:
- 'examples/**/*'
- 'spec/**/*'

RSpec/ExpectActual:
Exclude:
- 'spec/native_spec.rb'

RSpec/IdenticalEqualityAssertion:
Exclude:
- 'spec/native_spec.rb'

RSpec/LeakyConstantDeclaration:
Exclude:
- 'spec/**/*'

RSpec/PredicateMatcher:
Enabled: false

Capybara/RSpec/PredicateMatcher:
Enabled: false

# Disable Rails-specific cops (not using Rails)
RSpecRails/AvoidSetupHook:
Enabled: false

RSpecRails/HaveHttpStatus:
Enabled: false
Exclude:
- 'examples/**/*'
- 'spec/**/*'

RSpecRails/HttpStatus:
Enabled: false

RSpecRails/InferredSpecType:
Enabled: false

RSpecRails/MinitestAssertions:
Enabled: false

RSpecRails/NegationBeValid:
Enabled: false

RSpecRails/TravelAround:
Enabled: false

# Allow OpenStruct in tests
Style/OpenStructUse:
Exclude:
- 'spec/**/*'
- 'examples/**/*'
13 changes: 13 additions & 0 deletions bin/rubocop
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
# Wrapper script to run rubocop with Homebrew Ruby

# Prefer Homebrew Ruby on macOS
if [[ "$OSTYPE" == "darwin"* ]]; then
if [ -d "/opt/homebrew/opt/ruby/bin" ]; then
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"
elif [ -d "/usr/local/opt/ruby/bin" ]; then
export PATH="/usr/local/opt/ruby/bin:$PATH"
fi
fi

exec bundle exec rubocop "$@"
35 changes: 35 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,40 @@ else
echo -e "${YELLOW}⚠ RSpec not found, skipping tests${NC}"
fi

echo ""

# Step 7: Build auth example
echo -e "${YELLOW}Step 6: Building auth example...${NC}"
AUTH_EXAMPLE_DIR="${SCRIPT_DIR}/examples/auth"

if [ -d "${AUTH_EXAMPLE_DIR}" ] && [ -f "${AUTH_EXAMPLE_DIR}/Gemfile" ]; then
cd "${AUTH_EXAMPLE_DIR}"

if [ "$RUBY_READY" = true ]; then
echo -e "${YELLOW} Installing auth example dependencies...${NC}"
if bundle install --quiet 2>/dev/null; then
echo -e "${GREEN}✓ Auth example dependencies installed${NC}"

# Run auth example tests
echo -e "${YELLOW} Running auth example tests...${NC}"
if bundle exec rspec --format documentation 2>/dev/null; then
echo -e "${GREEN}✓ Auth example tests passed${NC}"
else
echo -e "${YELLOW}⚠ Some auth example tests may have failed${NC}"
fi
else
echo -e "${YELLOW}⚠ Failed to install auth example dependencies${NC}"
bundle install 2>&1 | tail -5
fi
else
echo -e "${YELLOW}⚠ Skipping auth example (Ruby environment not ready)${NC}"
fi

cd "${SCRIPT_DIR}"
else
echo -e "${YELLOW}⚠ Auth example not found at ${AUTH_EXAMPLE_DIR}${NC}"
fi

echo ""
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN}Build completed successfully!${NC}"
Expand All @@ -353,3 +387,4 @@ echo -e "Native libraries: ${YELLOW}${NATIVE_LIB_DIR}${NC}"
echo -e "Native headers: ${YELLOW}${NATIVE_INCLUDE_DIR}${NC}"
echo -e "Run tests: ${YELLOW}bundle exec rspec${NC}"
echo -e "Run example: ${YELLOW}ruby examples/client_example_json.rb${NC}"
echo -e "Run auth server: ${YELLOW}./examples/auth/run_example.sh${NC}"
23 changes: 23 additions & 0 deletions examples/auth/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

source 'https://rubygems.org'

# Use the SDK from parent directory
gem 'gopher_orch', path: '../../'

# Web framework
gem 'json', '~> 2.6'
gem 'puma', '~> 6.0'
gem 'sinatra', '~> 3.0'

# Rack utilities
gem 'rack', '~> 2.2'

# Ruby 4.0 compatibility (gems removed from stdlib)
gem 'logger'
gem 'ostruct'

group :development, :test do
gem 'rack-test', '~> 2.1'
gem 'rspec', '~> 3.12'
end
Loading