mirror of
https://github.com/gitlabhq/gitlabhq.git
synced 2025-07-25 17:08:32 +00:00
127 lines
3.3 KiB
Ruby
127 lines
3.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'net/http'
|
|
|
|
module Observability
|
|
class O11yToken
|
|
AuthenticationError = Class.new(StandardError)
|
|
ConfigurationError = Class.new(StandardError)
|
|
NetworkError = Class.new(StandardError)
|
|
|
|
class TokenResponse
|
|
attr_reader :user_id, :access_jwt, :refresh_jwt
|
|
|
|
def self.from_json(data)
|
|
data ||= {}
|
|
new(
|
|
user_id: data.dig('data', 'userId'),
|
|
access_jwt: data.dig('data', 'accessJwt'),
|
|
refresh_jwt: data.dig('data', 'refreshJwt')
|
|
)
|
|
end
|
|
|
|
def initialize(user_id:, access_jwt:, refresh_jwt:)
|
|
@user_id = user_id
|
|
@access_jwt = access_jwt
|
|
@refresh_jwt = refresh_jwt
|
|
end
|
|
|
|
def to_h
|
|
{
|
|
userId: user_id,
|
|
accessJwt: access_jwt,
|
|
refreshJwt: refresh_jwt
|
|
}
|
|
end
|
|
end
|
|
|
|
def self.generate_tokens(o11y_settings)
|
|
new(o11y_settings).generate_tokens
|
|
end
|
|
|
|
def initialize(o11y_settings)
|
|
@o11y_settings = o11y_settings
|
|
@http_client = HttpClient.new
|
|
end
|
|
|
|
def generate_tokens
|
|
validate_settings!
|
|
|
|
response = authenticate_user
|
|
parse_response(response)
|
|
rescue ConfigurationError, AuthenticationError, NetworkError => e
|
|
Gitlab::ErrorTracking.log_exception(e)
|
|
{}
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :o11y_settings, :http_client
|
|
|
|
def validate_settings!
|
|
raise ConfigurationError, "O11y settings are not set" if o11y_settings.blank?
|
|
|
|
raise ConfigurationError, "o11y_service_url is not configured" if o11y_settings.o11y_service_url.blank?
|
|
|
|
if o11y_settings.o11y_service_user_email.blank?
|
|
raise ConfigurationError,
|
|
"o11y_service_user_email is not configured"
|
|
end
|
|
|
|
raise ConfigurationError, "o11y_service_password is not configured" if o11y_settings.o11y_service_password.blank?
|
|
end
|
|
|
|
def authenticate_user
|
|
payload = build_payload
|
|
http_client.post(login_url, payload)
|
|
rescue *Gitlab::HTTP::HTTP_ERRORS => e
|
|
raise NetworkError, "Failed to connect to O11y service (#{e.class.name}): #{e.message}"
|
|
end
|
|
|
|
def build_payload
|
|
{
|
|
email: o11y_settings.o11y_service_user_email,
|
|
password: o11y_settings.o11y_service_password
|
|
}
|
|
end
|
|
|
|
def login_url
|
|
"#{o11y_settings.o11y_service_url}/api/v1/login"
|
|
end
|
|
|
|
def parse_response(response)
|
|
unless response.code.to_i == 200
|
|
Gitlab::AppLogger.warn("O11y authentication failed with status #{response.code}")
|
|
return {}
|
|
end
|
|
|
|
response_body = response.body.to_s.strip
|
|
raise AuthenticationError, "Empty response from O11y service" if response_body.blank?
|
|
|
|
data = Gitlab::Json.parse(response.body)
|
|
TokenResponse.from_json(data).to_h
|
|
rescue JSON::ParserError => e
|
|
raise AuthenticationError, "Invalid response format from O11y service: #{e.message}"
|
|
end
|
|
|
|
class HttpClient
|
|
def post(url, payload)
|
|
::Gitlab::HTTP.post(
|
|
url,
|
|
headers: { 'Content-Type' => 'application/json' },
|
|
body: Gitlab::Json.dump(payload),
|
|
allow_local_requests: allow_local_requests?
|
|
)
|
|
end
|
|
|
|
private
|
|
|
|
def allow_local_requests?
|
|
Rails.env.development? ||
|
|
Rails.env.test? ||
|
|
::Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
|
|
end
|
|
end
|
|
end
|
|
end
|