Skip to content
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

Feature/0.8 #14

Merged
merged 8 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ GEM
aws-sigv4 (~> 1.6)
aws-sigv4 (1.6.0)
aws-eventstream (~> 1, >= 1.0.2)
base64 (0.2.0)
bootsnap (1.16.0)
msgpack (~> 1.2)
build-environment (1.13.0)
Expand All @@ -120,6 +121,9 @@ GEM
console (1.17.2)
fiber-annotation
fiber-local
console-adapter-rails (0.1.4)
console
rails (>= 6.1)
counter_culture (3.4.0)
activerecord (>= 4.2)
activesupport (>= 4.2)
Expand Down Expand Up @@ -173,6 +177,8 @@ GEM
reline (>= 0.3.6)
jmespath (1.6.2)
json (2.6.3)
jwt (2.8.1)
base64
language_server-protocol (3.17.0.3)
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
Expand Down Expand Up @@ -267,6 +273,8 @@ GEM
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
rbnacl (7.1.1)
ffi
redis (4.8.1)
redis-client (0.14.1)
connection_pool
Expand Down Expand Up @@ -375,17 +383,20 @@ DEPENDENCIES
color-generator (~> 0.0.4)
connection_pool (~> 2.3)
console (~> 1.17)
console-adapter-rails (~> 0.1.4)
counter_culture (~> 3.2)
debug
dotenv-rails (~> 2.8)
falcon (~> 0.42)
http (~> 5.1)
jwt (~> 2.8)
nokogiri (~> 1.14.0.rc1)
openssl-oaep (~> 0.1.0)
parallel_tests (~> 4.2)
pg (~> 1.4)
puma (~> 6.3)
rails (~> 7.0.4)
rbnacl (~> 7.1)
redis (~> 4.0)
request_store_rails (~> 2.0)
rspec (~> 3.12)
Expand Down
5 changes: 5 additions & 0 deletions backend/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,8 @@ gem "sentry-ruby", "~> 5.10"
gem "sentry-rails", "~> 5.10"

gem "sentry-sidekiq", "~> 5.10"

gem "jwt", "~> 2.8"
gem "rbnacl", "~> 7.1"

gem "console-adapter-rails", "~> 0.1.4"
11 changes: 11 additions & 0 deletions backend/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ GEM
aws-sigv4 (~> 1.6)
aws-sigv4 (1.6.0)
aws-eventstream (~> 1, >= 1.0.2)
base64 (0.2.0)
bootsnap (1.16.0)
msgpack (~> 1.2)
build-environment (1.13.0)
Expand All @@ -120,6 +121,9 @@ GEM
console (1.17.2)
fiber-annotation
fiber-local
console-adapter-rails (0.1.4)
console
rails (>= 6.1)
counter_culture (3.4.0)
activerecord (>= 4.2)
activesupport (>= 4.2)
Expand Down Expand Up @@ -173,6 +177,8 @@ GEM
reline (>= 0.3.6)
jmespath (1.6.2)
json (2.6.3)
jwt (2.8.1)
base64
language_server-protocol (3.17.0.3)
llhttp-ffi (0.4.0)
ffi-compiler (~> 1.0)
Expand Down Expand Up @@ -269,6 +275,8 @@ GEM
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.0.6)
rbnacl (7.1.1)
ffi
redis (4.8.1)
redis-client (0.14.1)
connection_pool
Expand Down Expand Up @@ -378,17 +386,20 @@ DEPENDENCIES
color-generator (~> 0.0.4)
connection_pool (~> 2.3)
console (~> 1.17)
console-adapter-rails (~> 0.1.4)
counter_culture (~> 3.2)
debug
dotenv-rails (~> 2.8)
falcon (~> 0.42)
http (~> 5.1)
jwt (~> 2.8)
nokogiri (~> 1.14.0.rc1)
openssl-oaep (~> 0.1.0)
parallel_tests (~> 4.2)
pg (~> 1.4)
puma (~> 6.3)
rails (~> 7.0.4)
rbnacl (~> 7.1)
redis (~> 4.0)
request_store_rails (~> 2.0)
rspec (~> 3.12)
Expand Down
115 changes: 63 additions & 52 deletions backend/app/controllers/api/auth_controller.rb
Original file line number Diff line number Diff line change
@@ -1,65 +1,76 @@
# frozen_string_literal: true
module Api
class AuthController < FrontendController
def create_code
code = SecureRandom.random_number(100_000_000 - 1).to_s.rjust(8, "0")
Rails.logger.info("New auth code: #{code}")
$redis.with do |conn|
conn.set(
"auth_code/#{code}",
{ authorized: false }.to_json,
ex: 1.5.minutes.to_i
)
end

render json: { code: "ok", authCode: code }
def start
uuid = SecureRandom.uuid
url =
"https://open.sonolus.com/external-login/" + request.host +
"/api/login/callback?uuid=#{uuid}"
render json: { url:, uuid: }
end

def check_code
params.require :code
code = params[:code]
if code.blank?
render json: {
code: "invalid_request",
message: "Missing auth code"
},
status: :bad_request
def callback
body = request.body.read
signature = request.headers["Sonolus-Signature"]
unless signature
logger.warn "No signature"
render json: { error: "No signature" }, status: :unauthorized
return
end
unless (
auth_data =
$redis.with do |conn|
conn
.get("auth_code/#{code}")
&.then { |v| JSON.parse(v, symbolize_names: true) }
end
unless JWT::JWA::Ecdsa.verify(
"ES256",
SonolusController::SONOLUS_PUBLIC_KEY.verify_key,
body,
Base64.strict_decode64(signature)
)
render json: {
code: "unknown_code",
message: "Unknown auth code"
},
status: :not_found
logger.warn "Invalid signature"
render json: { error: "Invalid signature" }, status: :unauthorized
return
end
if auth_data[:authorized]
token_data =
$redis.with do |conn|
conn
.get("auth_token/#{auth_data[:token]}")
&.then { |v| JSON.parse(v, symbolize_names: true) }
end
user = User.new(token_data[:user])
render json: {
code: "ok",
user: user.to_frontend
}
session[:user_id] = user.id
else
render json: {
code: "not_authorized",
message: "Auth code not authorized"
},
status: :forbidden
unless params[:type] == "authenticateExternal"
logger.warn "Invalid type: #{params[:type]}"
render json: { error: "Invalid type" }, status: :unauthorized
return
end
unless Rails.env.development?
unless params[:url].ends_with?(
"//" + request.host +
"/api/login/callback?uuid=#{params[:uuid]}"
)
logger.warn "Invalid url: #{params[:url]}"
render json: { error: "Invalid url" }, status: :unauthorized
return
end
end
unless params[:time] && (Time.now.to_i - params[:time] / 1000) < 1.minutes
render json: { error: "Expired time" }, status: :unauthorized
return
end

user = User.from_profile(params[:userProfile])
uuid = params[:uuid]
$redis.with do |conn|
conn.set("sonolus_login/#{uuid}", user.id, ex: 30.minutes)
end

render json: { code: "ok" }
end

def status
uuid = params[:uuid]
unless uuid
render json: { code: "not_found", message: "Not Found" }, status: 404
return
end

$redis.with do |conn|
status = conn.get("sonolus_login/#{uuid}")
if status
session[:user_id] = status.to_i
render json: { code: "ok" }
else
render json: { code: "not_found", message: "Not Found" }, status: 404
end
end
end

Expand Down
1 change: 1 addition & 0 deletions backend/app/controllers/api/charts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ def process_chart_request

unless (current_user.admin?) || author.id == session[:user_id] ||
author.owner_id == session[:user_id]
logger.warn "User #{session[:user_id].inspect} is not allowed to upload charts as user #{author.id}"
render json: {
code: "forbidden",
error: "You are not allowed to upload charts as this user"
Expand Down
63 changes: 42 additions & 21 deletions backend/app/controllers/sonolus/asset_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,29 @@

module Sonolus
class AssetController < SonolusController
def info
params.permit(:type)
type = params[:type]
names =
Rails
.root
.glob("assets/#{type}/*.yml")
.map { |path| File.basename(path).delete_suffix(".yml") }
render json: {
sections: [
{
title: "#ALL",
items:
names.map do |name|
Sonolus::AssetController.asset_get(
type.delete_suffix("s"),
name
)
end
}
]
}
end
def list
params.permit(:type)
type = params[:type]
Expand Down Expand Up @@ -32,7 +55,7 @@ def show
if item.nil?
render json: { error: "not_found", message: "Not Found" }, status: 404
else
render json: { item:, description: "", recommended: [] }
render json: { item:, description: "", sections: [] }
end
end

Expand Down Expand Up @@ -156,28 +179,26 @@ def self.asset_get(type, name)
rescue Errno::ENOENT
return nil
end
data.to_h do |k, v|
next k, v unless v.is_a?(String)
data
.to_h do |k, v|
next k, v unless v.is_a?(String)

if k == "name"
v = "chcy-#{v}"
elsif v.start_with?("!asset:")
v = asset_get(k, v.delete_prefix("!asset:"))
elsif v.start_with?("!file:")
name, srl_type = v.delete_prefix("!file:").split("/")
srl_type ||= name
hash =
Digest::SHA1.file(
Rails.root.join("assets", "#{type}s", name)
).hexdigest
v = {
hash:,
url: "/sonolus/assets/#{type}s/#{name}?hash=#{hash}",
type: srl_type
}
if k == "name"
v = "chcy-#{v}"
elsif v.start_with?("!asset:")
v = asset_get(k, v.delete_prefix("!asset:"))
elsif v.start_with?("!file:")
name, srl_type = v.delete_prefix("!file:").split("/")
srl_type ||= name
hash =
Digest::SHA1.file(
Rails.root.join("assets", "#{type}s", name)
).hexdigest
v = { hash:, url: "/sonolus/assets/#{type}s/#{name}?hash=#{hash}" }
end
[k, v]
end
[k, v]
end
.merge({ source: ENV["HOST"], tags: [] })
end
end
end
Loading
Loading