add check_uuid_url to codeharbor_link

This commit is contained in:
Karol
2019-10-20 16:20:04 +02:00
parent 7e7be4721a
commit 9512fe4a79
14 changed files with 51 additions and 85 deletions

View File

@ -28,17 +28,8 @@ $(document).on('turbolinks:load', function() {
return replace(Array(32).join('x'));
});
$('.generate-client-id').on('click', function () {
$('.client-id').val(generateUUID());
});
$('.generate-client-secret').on('click', function () {
$('.client-secret').val(generateRandomHex32());
});
$('.generate-oauth2-token').on('click', function () {
$('.oauth2-token').val(generateRandomHex32())
$('.generate-api_key').on('click', function () {
$('.api_key').val(generateRandomHex32())
});
}
}

View File

@ -261,18 +261,16 @@ $(document).on('turbolinks:load', function() {
var $messageDiv = $exerciseDiv.children('.export-message');
var $actionsDiv = $exerciseDiv.children('.export-exercise-actions');
$messageDiv.html('requesting status');
$actionsDiv.html('spinning');
$messageDiv.removeClass('export-failure');
$messageDiv.html('<%= I18n.t('exercises.export_codeharbor.checking_codeharbor') %>');
$actionsDiv.html('<div class="spinner-border"></div>');
return $.ajax({
type: 'POST',
url: '/exercises/' + exerciseID + '/export_external_check',
dataType: 'json',
success: function(response) {
if (response.error) {
$messageDiv.html(response.error);
$actionsDiv.html('Retry?');
}
$messageDiv.html(response.message);
return $actionsDiv.html(response.actions);
},
@ -380,7 +378,6 @@ $(document).on('turbolinks:load', function() {
observeExecutionEnvironment();
observeUnpublishedState();
overrideTextareaTabBehavior();
} else if ($('#files.jstree').isPresent()) {
var fileTypeSelect = $('#code_ocean_file_file_type_id');
fileTypeSelect.on("change", function() {updateFileTemplates(fileTypeSelect.val())});

View File

@ -179,8 +179,11 @@ a.file-heading {
#export-modal {
.modal-content {
min-height: unset;
height: 300px;
min-height: 300px;
}
.modal-body {
overflow: auto;
}
}

View File

@ -5,7 +5,8 @@ class CodeharborLinksController < ApplicationController
before_action :set_codeharbor_link, only: %i[show edit update destroy]
def new
@codeharbor_link = CodeharborLink.new
base_url = CodeOcean::Config.new(:code_ocean).read[:codeharbor][:url]
@codeharbor_link = CodeharborLink.new(push_url: base_url + '/import_exercise', check_uuid_url: base_url + '/import_uuid_check')
authorize!
end
@ -42,6 +43,6 @@ class CodeharborLinksController < ApplicationController
end
def codeharbor_link_params
params.require(:codeharbor_link).permit(:push_url, :oauth2token, :client_id, :client_secret)
params.require(:codeharbor_link).permit(:push_url, :check_uuid_url, :api_key)
end
end

View File

@ -7,7 +7,7 @@ class ExercisesController < ApplicationController
before_action :handle_file_uploads, only: [:create, :update]
before_action :set_execution_environments, only: [:create, :edit, :new, :update]
before_action :set_exercise_and_authorize, only: MEMBER_ACTIONS + [:push_proforma_xml, :clone, :implement, :working_times, :intervention, :search, :run, :statistics, :submit, :reload, :feedback, :study_group_dashboard, :export_external_check, :export_external_confirm]
before_action :set_exercise_and_authorize, only: MEMBER_ACTIONS + [:clone, :implement, :working_times, :intervention, :search, :run, :statistics, :submit, :reload, :feedback, :study_group_dashboard, :export_external_check, :export_external_confirm]
before_action :set_external_user_and_authorize, only: [:statistics]
before_action :set_file_types, only: [:create, :edit, :new, :update]
before_action :set_course_token, only: [:implement]
@ -107,54 +107,37 @@ class ExercisesController < ApplicationController
@feedbacks = @exercise.user_exercise_feedbacks.paginate(page: params[:page])
end
def push_proforma_xml
error = ExerciseService::PushExternal.call(
zip: ProformaService::ExportTask.call(exercise: @exercise),
codeharbor_link: current_user.codeharbor_link
)
if error.nil?
redirect_to exercises_path, notice: t('exercises.export_codeharbor.success')
else
redirect_to exercises_path, alert: t('exercises.export_codeharbor.fail')
end
end
def export_external_check
@codeharbor_link = current_user.codeharbor_link
url = 'http://localhost:3001/import_uuid_check'
conn = Faraday.new(url: url) do |faraday|
conn = Faraday.new(url: @codeharbor_link.check_uuid_url) do |faraday|
faraday.options[:open_timeout] = 5
faraday.options[:timeout] = 5
faraday.adapter Faraday.default_adapter
end
error = false
response_hash = {}
message = ''
begin
codeharbor_check = begin
response = conn.post do |req|
req.headers['Content-Type'] = 'application/json'
req.headers['Authorization'] = 'Bearer ' + @codeharbor_link.api_key
req.body = {uuid: @exercise.uuid}.to_json
end
response_hash = JSON.parse(response.body, symbolize_names: true)
message = response_hash[:message]
{error: false}.merge(response_hash.slice(:message, :exercise_found, :update_right))
rescue Faraday::Error => e
message = t('exercises.export_codeharbor.error', message: e.message)
error = true
{error: true, message: t('exercises.export_codeharbor.error', message: e.message)}
end
render json: {
message: message,
message: codeharbor_check[:message],
actions: render_to_string(
partial: 'export_actions',
locals: {
exercise: @exercise,
exercise_found: response_hash[:exercise_found],
update_right: response_hash[:update_right],
error: error,
exercise_found: codeharbor_check[:exercise_found],
update_right: codeharbor_check[:update_right],
error: codeharbor_check[:error],
exported: false
}
)
@ -179,15 +162,12 @@ class ExercisesController < ApplicationController
message: t('exercises.export_codeharbor.successfully_exported', id: @exercise.id, title: @exercise.title),
actions: render_to_string(partial: 'export_actions', locals: {exercise: @exercise, exported: true, error: error})
}
# @exercise, notice: t('controllers.exercise.push_external_notice', account_link: account_link.readable)
else
# logger.debug(error)
render json: {
status: 'fail',
message: t('exercises.export_codeharbor.export_failed', id: @exercise.id, title: @exercise.title, error: error),
actions: render_to_string(partial: 'export_actions', locals: {exercise: @exercise, exported: true, error: error})
}
# redirect_to @exercise, alert: t('controllers.account_links.not_working', account_link: account_link.readable)
end
end

View File

@ -1,11 +1,13 @@
# frozen_string_literal: true
class CodeharborLink < ApplicationRecord
validates :oauth2token, presence: true
validates :push_url, presence: true
validates :check_uuid_url, presence: true
validates :api_key, presence: true
belongs_to :user, foreign_key: :user_id, class_name: 'InternalUser'
def to_s
oauth2token
id.to_s
end
end

View File

@ -7,7 +7,7 @@ class ExercisePolicy < AdminOrAuthorPolicy
define_method(action) { admin? || teacher? }
end
[:clone?, :destroy?, :edit?, :statistics?, :update?, :feedback?, :push_proforma_xml?, :export_external_check?, :export_external_confirm?].each do |action|
[:clone?, :destroy?, :edit?, :statistics?, :update?, :feedback?, :export_external_check?, :export_external_confirm?].each do |action|
define_method(action) { admin? || author? }
end

View File

@ -2,7 +2,6 @@
module ExerciseService
class PushExternal < ServiceBase
CODEHARBOR_PUSH_LINK = Rails.env.production? ? 'https://codeharbor.openhpi.de/import_exercise' : 'http://localhost:3001/import_exercise'
def initialize(zip:, codeharbor_link:)
@zip = zip
@codeharbor_link = codeharbor_link
@ -11,7 +10,7 @@ module ExerciseService
def execute
body = @zip.string
begin
conn = Faraday.new(url: CODEHARBOR_PUSH_LINK) do |faraday|
conn = Faraday.new(url: @codeharbor_link.push_url) do |faraday|
faraday.adapter Faraday.default_adapter
end

View File

@ -4,23 +4,14 @@
= f.label(:push_url)
= f.text_field :push_url, data: {toggle: 'tooltip', placement: 'bottom'}, title: t('codeharbor_link.info.push_url'), class: 'form-control'
.form-group
= f.label(:oauth2token)
= f.label(:check_uuid_url)
= f.text_field :check_uuid_url, data: {toggle: 'tooltip', placement: 'bottom'}, title: t('codeharbor_link.info.check_uuid_url'), class: 'form-control'
.form-group
= f.label(:api_key)
.input-group
= f.text_field(:oauth2token, data: {toggle: 'tooltip', placement: 'bottom'}, title: t('codeharbor_link.info.token'), class: 'form-control oauth2-token')
= f.text_field(:api_key, data: {toggle: 'tooltip', placement: 'bottom'}, title: t('codeharbor_link.info.token'), class: 'form-control api_key')
.input-group-btn
= button_tag t('codeharbor_link.generate'), type: 'button', class: 'generate-oauth2-token btn btn-default'
.field-element.form-group
= f.label(:client_id)
.input-group
= f.text_field(:client_id, data: {toggle: 'tooltip', placement: 'bottom'}, title: t('codeharbor_link.info.client_id'), class: 'form-control client-id')
.input-group-btn
= button_tag t('codeharbor_link.generate'), type: 'button', class: 'generate-client-id btn btn-default'
.field-element.form-group
= f.label(:client_secret)
.input-group
= f.text_field(:client_secret, data: {toggle: 'tooltip', placement: 'bottom'}, title: t('codeharbor_link.info.client_secret'), class: 'form-control client-secret')
.input-group-btn
= button_tag t('codeharbor_link.generate'), type: 'button', class: 'generate-client-secret btn btn-default'
= button_tag t('codeharbor_link.generate'), type: 'button', class: 'generate-api_key btn btn-default'
.actions
= render('shared/submit_button', f: f, object: @codeharbor_link)
- if @codeharbor_link.persisted?

View File

@ -46,7 +46,7 @@ h1 = Exercise.model_name.human(count: 2)
li = link_to(t('activerecord.models.user_exercise_feedback.other'), feedback_exercise_path(exercise), class: 'dropdown-item') if policy(exercise).feedback?
li = link_to(t('shared.destroy'), exercise, data: {confirm: t('shared.confirm_destroy')}, method: :delete, class: 'dropdown-item') if policy(exercise).destroy?
li = link_to(t('.clone'), clone_exercise_path(exercise), data: {confirm: t('shared.confirm_destroy')}, method: :post, class: 'dropdown-item') if policy(exercise).clone?
li = link_to(t('exercises.export_codeharbor.label'), '', class: 'dropdown-item export-start', data: {'exercise-id' => exercise.id}) if policy(exercise).push_proforma_xml?
li = link_to(t('exercises.export_codeharbor.label'), '', class: 'dropdown-item export-start', data: {'exercise-id' => exercise.id}) if policy(exercise).export_external_confirm?
= render('shared/pagination', collection: @exercises)
p = render('shared/new_button', model: Exercise)

View File

@ -246,7 +246,9 @@ en:
generate: Generate
info:
push_url: |
The address on CodeHarbor side your exercise can be exported to. If you don't know what to write here, ask an admin.
The url from Codeharbor where your exercise can be exported to. If you don't know what to write here, ask an admin.
check_uuid_url: |
The url from Codeharbor where we can check if the exercise already exists. If you don't know what to write here, ask an admin.
name: |
Can be anything to Identify your account link.
token: |
@ -323,13 +325,12 @@ en:
exercise_found: A corresponding exercise has been found on Codeocean. You can either <ul><li>Create a new exercise as a duplicate of this one on Codeharbor and push it to Codeocean, using the "Create new" button.</li><li>Overwrite the exercise on Codeocean, by pushing all changes. Only use "Overwrite" for bugfixes or very small changes - it will alter and may break published exercises.</li></ul>
exercise_found_no_right: A corresponding exercise has been found on Codeocean, but you don't have the rights to edit it. You can only <ul><li>Create a new exercise as a duplicate of this one on Codeharbor and push it to Codeocean, using the "Create new" button.</li></ul>
export_codeharbor:
fail: Failed to push the exercise to CodeHarbor.
label: Export to Codeharbor
success: Successfully pushed the exercise to CodeHarbor.
dialogtitle: Export to Codeharbor
successfully_exported: 'Exercise has successfully been exported.<br>ID: %{id}<br>Title: %{title}'
export_failed: 'Export has failed.<br>ID: %{id}<br>Title: %{title}<br><br>Error: %{error}'
error: 'An error occurred while contacting Codeharbor<br>Error: %{message}'
checking_codeharbor: Checking whether exercise exists on Codeharbor.
file_form:
hints:
feedback_message: This message is used as a hint for failing tests.

View File

@ -85,7 +85,6 @@ Rails.application.routes.draw do
get :reload
post :submit
get 'study_group_dashboard/:study_group_id', to: 'exercises#study_group_dashboard'
post :push_proforma_xml
post :export_external_check
post :export_external_confirm
end

View File

@ -1,6 +1,7 @@
class AddPushUrlRenameOauth2tokenInCodeharborLinks < ActiveRecord::Migration[5.2]
def change
add_column :codeharbor_links, :push_url, :string
add_column :codeharbor_links, :check_uuid_url, :string
rename_column :codeharbor_links, :oauth2token, :api_key
end
end

View File

@ -34,6 +34,7 @@ ActiveRecord::Schema.define(version: 2019_10_08_163045) do
t.datetime "updated_at"
t.integer "user_id"
t.string "push_url"
t.string "check_uuid_url"
t.index ["user_id"], name: "index_codeharbor_links_on_user_id"
end