Skip to content

Commit

Permalink
- json web token is now created using the model class json_web_token
Browse files Browse the repository at this point in the history
- the download and upload routes are moved from public_api.rb to third_party_apps_api.rb
- updated tests
- test that user is admin is now conducted analogous as in admin_api.rb
  • Loading branch information
Konrad1991 committed Jul 7, 2023
1 parent c6b3956 commit 80caa1a
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 286 deletions.
1 change: 1 addition & 0 deletions app/api/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def authenticate!
def is_public_request?
request.path.start_with?(
'/api/v1/public/',
'/api/v1/public_third_party_app/',
'/api/v1/chemscanner/',
'/api/v1/chemspectra/',
'/api/v1/ketcher/layout',
Expand Down
68 changes: 0 additions & 68 deletions app/api/chemotion/public_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,45 +23,6 @@ def send_notification(attachment, user, status, has_error = false)
data_args: data_args, attach_id: attachment.id, research_plan_id: attachment.attachable_id, level: level
)
end

def decode_token(token)
payload = JWT.decode(token, Rails.application.secrets.secret_key_base) unless token.nil?
error!('401 Unauthorized', 401) if payload&.length&.zero?
att_id = payload[0]['attID']&.to_i
user_id = payload[0]['userID']&.to_i
[att_id, user_id]
end

def verify_token(token)
payload = decode_token(token)
@attachment = Attachment.find_by(id: payload[0])
@user = User.find_by(id: payload[1])
error!('401 Unauthorized', 401) if @attachment.nil? || @user.nil?
end

def download_third_party_app(token)
content_type 'application/octet-stream'
verify_token(token)
payload = decode_token(token)
@attachment = Attachment.find_by(id: payload[0])
@user = User.find_by(id: payload[1])
header['Content-Disposition'] = "attachment; filename=#{@attachment.filename}"
env['api.format'] = :binary
@attachment.read_file
end

def upload_third_party_app(token, file_name, file, file_type)
payload = decode_token(token)
attachment = Attachment.find_by(id: payload[0])
new_attachment = Attachment.new(attachable: attachment.attachable,
created_by: attachment.created_by,
created_for: attachment.created_for,
content_type: file_type)
File.open(file[:tempfile].path, 'rb') do |f|
new_attachment.update(file_path: f, filename: file_name)
end
{ message: 'File uploaded successfully' }
end
end

namespace :public do
Expand Down Expand Up @@ -127,35 +88,6 @@ def upload_third_party_app(token, file_name, file, file_type)
end
end

namespace :download_third_party_app do
desc 'download file from third party app'
before do
error!('401 Unauthorized', 401) if params[:token].nil?
end
get do
download_third_party_app(params[:token])
end
end

namespace :upload_third_party_app do
desc 'Upload file from third party app'
before do
error!('401 Unauthorized', 401) if params[:token].nil?
error!('401 Unauthorized', 401) if params[:attachmentName].nil?
error!('401 Unauthorized', 401) if params[:fileType].nil?
end
params do
requires :attachmentName, type: String, desc: 'Name of new file'
end
post do
verify_token(params[:token])
upload_third_party_app(params[:token],
params[:attachmentName],
params[:file],
params[:file_type])
end
end

namespace :callback do
desc 'start to save a document'
# callback status description
Expand Down
126 changes: 87 additions & 39 deletions app/api/chemotion/third_party_app_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,74 +4,124 @@ module Chemotion
# Publish-Subscription MessageAPI
class ThirdPartyAppAPI < Grape::API
helpers do
def user_type(id)
user = User.find_by(id: params[:userID])
user[:type]
def decode_token(token)
payload = JWT.decode(token, Rails.application.secrets.secret_key_base) unless token.nil?
error!('401 Unauthorized', 401) if payload&.length&.zero?
att_id = payload[0]['attID']&.to_i
user_id = payload[0]['userID']&.to_i
[att_id, user_id]
end

def verify_token(token)
payload = decode_token(token)
@attachment = Attachment.find_by(id: payload[0])
@user = User.find_by(id: payload[1])
error!('401 Unauthorized', 401) if @attachment.nil? || @user.nil?
end

def download_third_party_app(token)
content_type 'application/octet-stream'
verify_token(token)
payload = decode_token(token)
@attachment = Attachment.find_by(id: payload[0])
@user = User.find_by(id: payload[1])
header['Content-Disposition'] = "attachment; filename=#{@attachment.filename}"
env['api.format'] = :binary
@attachment.read_file
end

def upload_third_party_app(token, file_name, file, file_type)
payload = decode_token(token)
attachment = Attachment.find_by(id: payload[0])
new_attachment = Attachment.new(attachable: attachment.attachable,
created_by: attachment.created_by,
created_for: attachment.created_for,
content_type: file_type)
File.open(file[:tempfile].path, 'rb') do |f|
new_attachment.update(file_path: f, filename: file_name)
end
{ message: 'File uploaded successfully' }
end
end

resource :third_party_apps do
desc 'Find all thirdPartyApps'
get 'all' do
ThirdPartyApp.all
namespace :public_third_party_app do
desc 'download file from third party app'
params do
requires :token, type: String, desc: 'Token for authentication'
end
get '/download' do
error!('401 Unauthorized', 401) if params[:token].nil?
download_third_party_app(params[:token])
end

desc 'Upload file from third party app'
params do
requires :token, type: String, desc: 'Token for authentication'
requires :attachmentName, type: String, desc: 'Name of the attachment'
requires :fileType, type: String, desc: 'Type of the file'
end
post '/upload' do
error!('401 Unauthorized', 401) if params[:token].nil?
error!('401 Unauthorized', 401) if params[:attachmentName].nil?
error!('401 Unauthorized', 401) if params[:fileType].nil?
verify_token(params[:token])
upload_third_party_app(params[:token],
params[:attachmentName],
params[:file],
params[:file_type])
end
end

resource :third_party_apps_administration do
before do
error(401) unless current_user.is_a?(Admin)
end

desc 'create new third party app entry'
params do
requires :userID, type: Integer, desc: 'The ID of the current user.'
requires :IPAddress, type: String, desc: 'The IPAddress in order to redirect to the app.'
requires :name, type: String, desc: 'name of third party app. User will chose correct app based on names.'
end
post '/new_third_party_app' do
declared(params, include_missing: false)
if user_type(params[:userID]) == 'Admin'
ThirdPartyApp.create!(IPAddress: params[:IPAddress], name: params[:name])
status 201
else
status 403
{ error: 'Access denied. User must be an Admin.' }
end
ThirdPartyApp.create!(IPAddress: params[:IPAddress], name: params[:name])
status 201
rescue ActiveRecord::RecordInvalid => e
{ error: e.message }
error!('Unauthorized. User has to be admin.', 401)
end

desc 'update a third party app entry'
params do
requires :userID, type: Integer, desc: 'The ID of the current user.'
requires :id, type: String, desc: 'The id of the app which should be updated'
requires :IPAddress, type: String, desc: 'The IPAddress in order to redirect to the app.'
requires :name, type: String, desc: 'name of third party app. User will chose correct app based on names.'
end
post '/update_third_party_app' do
declared(params, include_missing: false)
if user_type(params[:userID]) == 'Admin'
entry = ThirdPartyApp.find(params[:id])
entry.update!(IPAddress: params[:IPAddress], name: params[:name])
status 201
else
status 403
{ error: 'Access denied. User must be an Admin.' }
end
entry = ThirdPartyApp.find(params[:id])
entry.update!(IPAddress: params[:IPAddress], name: params[:name])
status 201
rescue ActiveRecord::RecordInvalid => e
{ error: e.message }
error!('Unauthorized. User has to be admin.', 401)
end

desc 'delete third party app entry'
params do
requires :userID, type: Integer, desc: 'The ID of the current user.'
requires :id, type: String, desc: 'The id of the app which should be deleted'
end
post '/delete_third_party_app' do
if user_type(params[:userID]) == 'Admin'
id = params[:id].to_i
ThirdPartyApp.delete(id)
status 201
else
status 403
{ error: 'Access denied. User must be an Admin.' }
end
id = params[:id].to_i
ThirdPartyApp.delete(id)
status 201
rescue ActiveRecord::RecordInvalid => e
{ error: e.message }
error!('Unauthorized. User has to be admin.', 401)
end
end

resource :third_party_apps do
desc 'Find all thirdPartyApps'
get 'all' do
ThirdPartyApp.all
end

desc 'get third party app by id'
Expand Down Expand Up @@ -101,9 +151,7 @@ def user_type(id)
end
get 'Token' do
payload = { attID: params[:attID], userID: params[:userID] }
secret = Rails.application.secrets.secret_key_base
token = JWT.encode payload, secret, 'HS256'
token
JsonWebToken.encode(payload, 48.hours.from_now)
end
end

Expand Down
17 changes: 1 addition & 16 deletions app/packs/src/apps/admin/ThirdPartyApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Panel, Table, Button, Modal, FormGroup, ControlLabel, Form, Col, FormCo
import Select from 'react-select';
import { CSVReader } from 'react-papaparse';
import ThirdPartyAppFetcher from 'src/fetchers/ThirdPartyAppFetcher';
import UsersFetcher from 'src/fetchers/UsersFetcher';

const editTip = <Tooltip id="inchi_tooltip">edit third party app</Tooltip>;
const newTip = <Tooltip id="inchi_tooltip">create new third party app</Tooltip>;
Expand All @@ -24,8 +23,7 @@ export default class ThirdPartyApp extends React.Component {
thirdPartyAppNames: [""],
currentName: '',
currentIP: '',
currentID: '',
currentUser: ''
currentID: ''
};
this.thirdPartyApps();
this.closeNewThirdPartyAppModal = this.closeNewThirdPartyAppModal.bind(this);
Expand All @@ -45,16 +43,6 @@ export default class ThirdPartyApp extends React.Component {

componentDidMount() {
this.getThirdPartyAppNames();
this.getCurrentUser();
}

getCurrentUser() {
UsersFetcher.fetchCurrentUser()
.then((result) => {
this.setState({
currentUser: result.user.id
})
});
}

thirdPartyApps() {
Expand All @@ -78,7 +66,6 @@ export default class ThirdPartyApp extends React.Component {

new(name, IPAddress) {
ThirdPartyAppFetcher.newThirdPartyApp(
this.state.currentUser,
name,
IPAddress)
.then((result) => {
Expand All @@ -94,7 +81,6 @@ export default class ThirdPartyApp extends React.Component {

edit(name, IPAddress) {
return ThirdPartyAppFetcher.editThirdPartyApp(
this.state.currentUser,
this.state.currentID,
name,
IPAddress)
Expand All @@ -112,7 +98,6 @@ export default class ThirdPartyApp extends React.Component {

delete(id) {
ThirdPartyAppFetcher.deleteThirdPartyApp(
this.state.currentUser,
id)
.then((result) => {
if (result.error) {
Expand Down
15 changes: 6 additions & 9 deletions app/packs/src/fetchers/ThirdPartyAppFetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ export default class ThirdPartyAppFetcher {
.catch((errorMessage) => { console.log(errorMessage); });
}

static newThirdPartyApp(userID, name, IPAddress) {
static newThirdPartyApp(name, IPAddress) {
const obj = {
userID,
name,
IPAddress
};
return fetch('/api/v1/third_party_apps/new_third_party_app', {
return fetch('/api/v1/third_party_apps_administration/new_third_party_app', {
credentials: 'same-origin',
method: 'POST',
headers: {
Expand All @@ -30,14 +29,13 @@ export default class ThirdPartyAppFetcher {
.catch((errorMessage) => { console.log(errorMessage); });
}

static editThirdPartyApp(userID, id, name, IPAddress) {
static editThirdPartyApp(id, name, IPAddress) {
const obj = {
userID: userID,
id: id,
IPAddress: IPAddress,
name: name
};
return fetch('/api/v1/third_party_apps/update_third_party_app', {
return fetch('/api/v1/third_party_apps_administration/update_third_party_app', {
credentials: 'same-origin',
method: 'POST',
headers: {
Expand All @@ -50,12 +48,11 @@ export default class ThirdPartyAppFetcher {
.catch((errorMessage) => { console.log(errorMessage); });
}

static deleteThirdPartyApp(userID, id) {
static deleteThirdPartyApp(id) {
const obj = {
userID,
id
};
return fetch('/api/v1/third_party_apps/delete_third_party_app', {
return fetch('/api/v1/third_party_apps_administration/delete_third_party_app', {
credentials: 'same-origin',
method: 'POST',
headers: {
Expand Down
Loading

0 comments on commit 80caa1a

Please sign in to comment.