Skip to content
This repository was archived by the owner on Jun 24, 2024. It is now read-only.

Commit fc7cf0b

Browse files
author
Eric Pickup
committed
Use assignment creators token to create repo in certain cases
1 parent 697b70e commit fc7cf0b

File tree

80 files changed

+176
-88
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+176
-88
lines changed

app/services/create_github_repo_service.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# rubocop:disable ClassLength
44
class CreateGitHubRepoService
55
attr_reader :exercise, :stats_sender
6-
delegate :assignment, :collaborator, :organization, :invite_status, to: :exercise
6+
delegate :assignment, :collaborator, :organization, :invite_status, :github_organization, to: :exercise
77

88
def initialize(assignment, collaborator)
99
@exercise = Exercise.build(assignment, collaborator)
@@ -60,7 +60,7 @@ def create_github_repository!
6060
description: "#{exercise.repo_name} created by GitHub Classroom"
6161
}
6262

63-
organization.github_organization.create_repository(exercise.repo_name, options)
63+
github_organization.create_repository(exercise.repo_name, options)
6464
rescue GitHub::Error => error
6565
raise Result::Error.new errors(:repository_creation_failed), error.message
6666
end
@@ -75,7 +75,7 @@ def create_github_repository_from_template!
7575

7676
options = repo_from_template_options
7777

78-
github_repository = organization.github_organization.create_repository_from_template(
78+
github_repository = github_organization.create_repository_from_template(
7979
assignment.starter_code_repo_id,
8080
exercise.repo_name,
8181
options
@@ -114,7 +114,7 @@ def create_assignment_repo!(github_repository)
114114

115115
def delete_github_repository(github_repo_id)
116116
return true if github_repo_id.nil?
117-
organization.github_organization.delete_repository(github_repo_id)
117+
github_organization.delete_repository(github_repo_id)
118118
rescue GitHub::Error
119119
true
120120
end
@@ -227,7 +227,7 @@ def repo_from_template_options
227227
{
228228
private: assignment.private?,
229229
description: "#{exercise.repo_name} created by GitHub Classroom",
230-
owner: organization.github_organization.login,
230+
owner: exercise.organization_login,
231231
include_all_branches: true
232232
}
233233
end

app/services/create_github_repo_service/exercise.rb

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ def self.build(assignment, collaborator)
1010
end
1111
end
1212

13-
attr_reader :assignment, :collaborator, :organization, :invite_status
13+
attr_reader :assignment, :collaborator, :organization, :invite_status, :github_organization
1414
delegate :status, to: :invite_status
1515

1616
def initialize(assignment, collaborator)
1717
@assignment = assignment
1818
@collaborator = collaborator
1919
@organization = assignment.organization
2020
@invite_status = assignment.invitation.status(collaborator)
21+
@github_organization = github_organization_with_access
2122
end
2223

2324
def repo_name
@@ -29,7 +30,7 @@ def default_repo_name
2930
end
3031

3132
def organization_login
32-
@organization_login ||= organization.github_organization.login
33+
@organization_login ||= @github_organization.login
3334
end
3435

3536
def assignment_type
@@ -69,5 +70,27 @@ def suffixed_repo_name(suffix_count)
6970
suffix = "-#{suffix_count}"
7071
default_repo_name.truncate(100 - suffix.length, omission: "") + suffix
7172
end
73+
74+
# rubocop:disable MethodLength
75+
def github_organization_with_access
76+
github_organization_with_random_token = @organization.github_organization
77+
return github_organization_with_random_token unless assignment.starter_code?
78+
79+
github_client = assignment.creator.github_client
80+
starter_code_repository = GitHub::Errors.with_error_handling do
81+
github_client.repository(assignment.starter_code_repo_id)
82+
end
83+
84+
return github_organization_with_random_token unless
85+
require_creators_token?(starter_code_repository, github_organization_with_random_token)
86+
87+
GitHubOrganization.new(github_client, starter_code_repository)
88+
rescue GitHub::NotFound
89+
github_organization_with_random_token
90+
end
91+
92+
def require_creators_token?(starter_code_repository, github_org)
93+
starter_code_repository.private && starter_code_repository.owner.login != github_org.login
94+
end
7295
end
7396
end

spec/services/create_github_repo_service/exercise_spec.rb

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
let(:exercise) { described_class.new(assignment, student) }
77

88
describe ".build" do
9-
let(:assignment) { double(organization: double, invitation: double(status: double)) }
9+
let(:assignment) do
10+
double(
11+
organization: double(github_organization: double),
12+
invitation: double(status: double),
13+
starter_code?: false
14+
)
15+
end
1016

1117
it "builds a Individual if collaborator is a user" do
12-
collaborator = double("is_a?": true)
18+
collaborator = double("is_a?": true, github_organization: "Yeet")
1319
expect(described_class.build(assignment, collaborator))
1420
.to be_an_instance_of(CreateGitHubRepoService::IndividualExercise)
1521
end
@@ -40,4 +46,69 @@
4046
expect(exercise.organization_login).to eq(organization.github_organization.login)
4147
end
4248
end
49+
50+
describe "#github_organization_with_access", :vcr do
51+
let(:client) { oauth_client }
52+
let(:organization) { classroom_org }
53+
let(:github_organization) { organization.github_organization }
54+
let(:teacher) { classroom_teacher }
55+
let(:student) { classroom_student }
56+
let(:assignment) do
57+
options = {
58+
title: "Learn Elm",
59+
organization: organization,
60+
students_are_repo_admins: true,
61+
public_repo: true
62+
}
63+
build(:assignment, options)
64+
end
65+
let(:exercise) { described_class.new(assignment, student) }
66+
67+
before(:each) do
68+
assignment.update(starter_code_repo_id: github_repository.id)
69+
end
70+
71+
after(:each) do
72+
teacher.github_client.delete_repository(github_repository.id)
73+
end
74+
75+
context "repository is public" do
76+
let(:github_repository) do
77+
options = { private: false, is_template: true, auto_init: true }
78+
github_organization.create_repository("#{Faker::Company.name} Public Template", options)
79+
end
80+
81+
it "uses Organization#github_organization" do
82+
exercise = described_class.new(assignment, student)
83+
expect(exercise.github_organization).to eql(github_organization)
84+
end
85+
end
86+
87+
context "repository is private" do
88+
context "repository belongs to classroom organization" do
89+
let(:github_repository) do
90+
options = { private: true, is_template: true, auto_init: true }
91+
github_organization.create_repository("#{Faker::Company.name} Private Template on Org", options)
92+
end
93+
94+
it "uses Organization#github_organization" do
95+
exercise = described_class.new(assignment, student)
96+
expect(exercise.github_organization).to eql(github_organization)
97+
end
98+
end
99+
100+
context "repository does not belong to classroom organization" do
101+
let(:github_repository) do
102+
options = { private: true, is_template: true, auto_init: true }
103+
teacher.github_client.create_repository("#{Faker::Company.name} Private Template on User", options)
104+
end
105+
106+
it "uses a new GitHubOrganization with the assignment creator's token" do
107+
exercise = described_class.new(assignment, student)
108+
expect(exercise.github_organization).not_to eql(github_organization)
109+
expect(exercise.github_organization.access_token).to eql(assignment.creator.github_client.access_token)
110+
end
111+
end
112+
end
113+
end
43114
end

spec/services/create_github_repo_service_spec.rb

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
options = {
4949
private: false,
5050
is_template: true,
51-
auto_init: true,
52-
accept: "application/vnd.github.baptiste-preview"
51+
auto_init: true
5352
}
5453
github_organization.create_repository("#{Faker::Company.name} Template", options)
5554
end
@@ -290,8 +289,7 @@
290289
options = {
291290
private: false,
292291
is_template: true,
293-
auto_init: true,
294-
accept: "application/vnd.github.baptiste-preview"
292+
auto_init: true
295293
}
296294
github_organization.create_repository("#{Faker::Company.name} Template", options)
297295
end
@@ -548,8 +546,7 @@
548546
options = {
549547
private: false,
550548
is_template: true,
551-
auto_init: true,
552-
accept: "application/vnd.github.baptiste-preview"
549+
auto_init: true
553550
}
554551
github_organization.create_repository("#{Faker::Company.name} Template", options)
555552
end

spec/support/cassettes/CreateGitHubRepoService/for_Assignment/_add_collaborator_to_github_repository_/calls_add_user_to_github_repository_.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

spec/support/cassettes/CreateGitHubRepoService/for_Assignment/_add_collaborator_to_github_repository_/raises_GitHub_Error_if_user_addition_failed.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

spec/support/cassettes/CreateGitHubRepoService/for_Assignment/_add_user_to_github_repository_/invites_user_to_a_github_repository.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

spec/support/cassettes/CreateGitHubRepoService/for_Assignment/_create_assignment_repo_/gets_correct_github_repository_attributes_and_saves_the_repo.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

spec/support/cassettes/CreateGitHubRepoService/for_Assignment/_create_assignment_repo_/raises_a_Result_Error_if_record_not_saved.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

spec/support/cassettes/CreateGitHubRepoService/for_Assignment/_create_github_repository_/creates_a_new_github_repo.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)