Skip to content

Commit 1c2603a

Browse files
authored
Merge branch 'main' into lois/1000-return-remix-identifier-with-lesson
2 parents 4eeafa5 + 0abcfbc commit 1c2603a

16 files changed

Lines changed: 497 additions & 14 deletions

File tree

.clabot

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
"chris.lowis@gofreerange.com",
66
"chrisroos",
77
"conorriches",
8+
"Copilot",
89
"create-issue-branch",
910
"create-issue-branch[bot]",
11+
"cursor",
1012
"danhalson",
1113
"dependabot[bot]",
1214
"fspeirs",
@@ -16,17 +18,17 @@
1618
"jamiebenstead",
1719
"jrmhaig",
1820
"KristinaDudnyk",
19-
"lpmi-13",
2021
"loiswells97",
22+
"lpmi-13",
2123
"m-bowley",
2224
"magdalenajadach",
2325
"MarcScott",
2426
"Mohamed-RPF",
25-
"pjbRPF",
2627
"patch0",
2728
"PetarSimonovic",
29+
"pjbRPF",
2830
"sra405",
2931
"tuzz"
3032
],
3133
"message": "We require contributors to sign our Contributor License Agreement, and we don't have you on file. In order for us to review and merge your code, please complete [this form](https://form.raspberrypi.org/4873530) and we'll get you added and review your contribution as soon as possible."
32-
}
34+
}

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,7 @@ ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=deterministic-key
4747
ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=derivation-salt
4848

4949
EDITOR_ENCRYPTION_KEY=a1b2c3d4e5f67890123456789abcdef0123456789abcdef0123456789abcdef0
50+
51+
# The sandbox creds can be found in 1password under "Google Cloud Console: CEfE Sandbox"
52+
GOOGLE_CLIENT_ID=changeme.apps.googleusercontent.com
53+
GOOGLE_CLIENT_SECRET=changeme

app/controllers/api/feedback_controller.rb

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def index
1515
project_feedback.each do |feedback|
1616
authorize! :read, feedback
1717
end
18-
@feedback = project_feedback.accessible_by(current_ability)
18+
@feedback = project_feedback.accessible_by(current_ability).order(created_at: :asc)
1919
render :index, formats: [:json], status: :ok
2020
end
2121

@@ -30,6 +30,18 @@ def create
3030
end
3131
end
3232

33+
def set_read
34+
feedback = Feedback.find(params[:id])
35+
result = Feedback::SetRead.call(feedback: feedback)
36+
37+
if result.success?
38+
@feedback = result[:feedback]
39+
render :show, formats: [:json], status: :ok
40+
else
41+
render json: { error: result[:error] }, status: :unprocessable_entity
42+
end
43+
end
44+
3345
private
3446

3547
def project
@@ -68,8 +80,8 @@ def feedback_create_params
6880
end
6981

7082
def url_params
71-
permitted_params = params.permit(:project_id)
72-
{ identifier: permitted_params[:project_id] }
83+
permitted_params = params.permit(:project_id, :id)
84+
{ identifier: permitted_params[:project_id], id: permitted_params[:id] }
7385
end
7486

7587
def base_params
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# frozen_string_literal: true
2+
3+
module Api
4+
class GoogleAuthController < ApiController
5+
TOKEN_EXCHANGE_URL = 'https://oauth2.googleapis.com/token'
6+
7+
before_action :authorize_user
8+
authorize_resource :google_auth, class: false
9+
10+
def exchange_code
11+
response = faraday.post(TOKEN_EXCHANGE_URL, token_exchange_payload)
12+
@token_response = JSON.parse(response.body)
13+
14+
return render(:exchange_code, status: :ok) if response.success?
15+
16+
render json: { error: response_error_message }, status: :unauthorized
17+
rescue JSON::ParserError => e
18+
render json: { error: e.message }, status: :bad_gateway
19+
rescue Faraday::Error => e
20+
render json: { error: e.message }, status: :service_unavailable
21+
end
22+
23+
private
24+
25+
def faraday
26+
Faraday.new do |f|
27+
f.request :url_encoded
28+
f.options.timeout = 10
29+
f.options.open_timeout = 5
30+
end
31+
end
32+
33+
def token_exchange_payload
34+
payload = google_token_params
35+
{
36+
code: payload[:code],
37+
client_id: ENV.fetch('GOOGLE_CLIENT_ID'),
38+
client_secret: ENV.fetch('GOOGLE_CLIENT_SECRET'),
39+
redirect_uri: payload[:redirect_uri],
40+
grant_type: 'authorization_code'
41+
}
42+
end
43+
44+
def response_error_message
45+
@token_response['error_description'] || @token_response['error'] || 'Unknown error'
46+
end
47+
48+
def google_token_params
49+
params.require(:google_auth).require(:code)
50+
params.require(:google_auth).require(:redirect_uri)
51+
params.require(:google_auth).permit(:code, :redirect_uri)
52+
end
53+
end
54+
end

app/controllers/auth_controller.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
# frozen_string_literal: true
22

33
class AuthController < ApplicationController
4-
# def index
5-
6-
# end
7-
84
def callback
95
Rails.logger.debug { "callback: #{omniauth_params}" }
106
# Prevent session fixation. If the session has been initialized before

app/models/ability.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def define_school_owner_abilities(school:)
6969
can(%i[read create create_batch update destroy], :school_student)
7070
can(%i[create create_copy], Lesson, school_id: school.id)
7171
can(%i[read update destroy], Lesson, school_id: school.id, visibility: %w[teachers students public])
72+
can(%i[exchange_code], :google_auth)
7273
end
7374

7475
def define_school_teacher_abilities(user:, school:)
@@ -98,6 +99,7 @@ def define_school_teacher_abilities(user:, school:)
9899
can(%i[read], Project, remixed_from_id: teacher_project_ids)
99100
can(%i[show_status unsubmit return complete], SchoolProject, project: { remixed_from_id: teacher_project_ids })
100101
can(%i[read create], Feedback, school_project: { project: { remixed_from_id: teacher_project_ids } })
102+
can(%i[exchange_code], :google_auth)
101103
end
102104

103105
def define_school_student_abilities(user:, school:)
@@ -113,7 +115,7 @@ def define_school_student_abilities(user:, school:)
113115
can(%i[read], Lesson, school_id: school.id, visibility: 'students', school_class: { students: { student_id: user.id } })
114116
can(%i[read create update], Project, school_id: school.id, user_id: user.id, lesson_id: nil, remixed_from_id: visible_lesson_project_ids)
115117
can(%i[read show_context], Project, lesson: { school_id: school.id, visibility: 'students', school_class: { students: { student_id: user.id } } })
116-
can(%i[read], Feedback, school_project: { project: { school_id: school.id, user_id: user.id, lesson_id: nil, remixed_from_id: visible_lesson_project_ids } })
118+
can(%i[read set_read], Feedback, school_project: { project: { school_id: school.id, user_id: user.id, lesson_id: nil, remixed_from_id: visible_lesson_project_ids } })
117119
can(%i[show_finished set_finished show_status unsubmit submit], SchoolProject, project: { user_id: user.id, lesson_id: nil }, school_id: school.id)
118120
end
119121

app/views/api/feedback/_feedback.json.jbuilder

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ json.call(
77
:user_id,
88
:content,
99
:created_at,
10-
:updated_at
10+
:updated_at,
11+
:read_at
1112
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
json.call(
4+
@token_response,
5+
'access_token',
6+
'expires_in',
7+
'token_type',
8+
'scope'
9+
)

config/routes.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@
4848
end
4949
resources :remixes, only: %i[index], controller: 'projects/remixes'
5050
resource :images, only: %i[show create], controller: 'projects/images'
51-
resources :feedback, only: %i[index create], controller: 'feedback'
51+
resources :feedback, only: %i[index create], controller: 'feedback' do
52+
put :read, on: :member, to: 'feedback#set_read'
53+
end
5254
end
5355

5456
resource :project_errors, only: %i[create]
@@ -79,6 +81,8 @@
7981
end
8082

8183
resources :user_jobs, only: %i[index show]
84+
85+
post '/google/auth/exchange-code', to: 'google_auth#exchange_code', defaults: { format: :json }
8286
end
8387

8488
resource :github_webhooks, only: :create, defaults: { formats: :json }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class AddReadAtToFeedback < ActiveRecord::Migration[7.2]
2+
def change
3+
add_column :feedback, :read_at, :datetime
4+
end
5+
end

0 commit comments

Comments
 (0)