Skip to content

Commit

Permalink
Merge branch 'mampf-next' into refactor_abilities
Browse files Browse the repository at this point in the history
  • Loading branch information
fosterfarrell9 committed Mar 15, 2022
2 parents b3b101f + 4b6b431 commit 019e7b4
Show file tree
Hide file tree
Showing 47 changed files with 631 additions and 482 deletions.
60 changes: 15 additions & 45 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ $ cd mampf/docker/development/
# docker-compose up
```

NOTE: Please make sure to clone recursivly as the pdf compression feature is in an extra repository.
NOTE: Please make sure to clone recursively as the pdf compression feature is in an extra repository.
If you have an already checked out version simply run:

```sh
Expand All @@ -19,6 +19,8 @@ You now have the following things ready:
* The MaMpf server on <a href="http://localhost:3000/" target="_blank">localhost:3000</a>
* The mailcatcher service on <a href="http://localhost:1080/" target="_blank">localhost:1080</a>
* The webinterface for ApacheSolr on <a href="http://localhost:8983/" target="_blank">localhost:8983</a>
* A test mailserver instance on Ports 1025, 10143, 10993
* A webpacker dev server on localhost:3035

### Database setup

Expand Down Expand Up @@ -46,11 +48,13 @@ and put it in the `db/backups/docker_development` folder in your project directo
# docker-compose exec mampf rails db:migrate
```
4. Download the sample videos and sample manuscripts that match the data in the prepopulated
database <a href="https://heibox.uni-heidelberg.de/f/d2f72a4069814debaf69/" target="_blank">here</a> and extract the .zip file into the `public/` folder of your project directory.
database <a href="https://heibox.uni-heidelberg.de/f/d2f72a4069814debaf69/" target="_blank">here</a> and extract the .zip file into the `public/` folder of your project directory.
5. Call the MaMpf Server on <a href="http://localhost:3000/" target="_blank">localhost:3000</a>. The prepopulated database contains data for several users
that you can use to sign in: `admin@mampf.edu`, `teacher@mampf.edu`, `tutor@mampf.edu` and `student1@mampf.edu`,..., `student5@mampf.edu` (with the obvious roles). Each of these have `dockermampf` as password.
6. There you go :tada:

Instead you can also uncomment the preseed options in the docker-compose file. When in daut, just follow this guide here.


Note that in both cases, the first start of the MaMpf server can take a while, as
all assets have to provided.
Expand All @@ -67,61 +71,27 @@ A few common commands for `docker-compose` are:
| `docker-compose exec mampf <exec>` | run an executable in the container |


## Installation in production mode (with Docker)
## Installation in production mode

1. Install Database Server (e.g. PostgreSQL) and create Database.
(Don't forget to allow access for the docker network)
```
createuser mampf
createuser -P mampf
createdb -O mampf mampf
psql -c "ALTER USER mampf PASSWORD '$PASSWORD'"
```
2. Create an environment file like this:
```
RAILS_ENV=production
PRODUCTION_DATABASE_ADAPTER=postgresql
PRODUCTION_DATABASE_DATABASE=mampf
PRODUCTION_DATABASE_USERNAME=mampf
PRODUCTION_DATABASE_PASSWORD=$DATABASE_PASSWORD
PRODUCTION_DATABASE_HOST=172.17.0.1
PRODUCTION_DATABASE_PORT=5432
MAILSERVER=localhost
FROM_ADDRESS=mampf@localhost
URL_HOST=localhost
RAILS_MASTER_KEY=$MASTER_KEY
ERDBEERE_SERVER = your_erdbeere_server
MUESLI_SERVER = your_muesli_server
PROJECT_EMAIL = your_project_email
PROJECT_NOTIFICATION_EMAIL= your_project_notification_email
INSTANCE_PATH=mampf
USE_CAPTCHA_SERVICE=true
CAPTCHA_VERIFY_URL=your_captcha_service_verify_url
CAPTCHA_PUZZLE_URL=your_captcha_service_puzzle_url
CAPTCHA_APPLICATION_TOKEN=your_token_for_verifying_puzzle
REWRITE_ENABLED=1_if_you_want_nice_filenames
```
3. Execute the following commands to install and run the service:
```
git clone -b main git@github.com:fosterfarrell9/mampf.git
docker build --label "mampf" mampf
docker create --name mampf --env-file $ENVFILE -p $OUTSIDEPORT:3000 $IMAGEID
docker run --rm --env-file $ENVFILE $IMAGEID 'rm config/credentials.yml.enc && bundle exec rails credentials:edit'
docker start mampf
docker exec mampf bundle exec rake db:migrate
docker exec mampf bundle exec rake db:seed
docker exec mampf bundle exec rake assets:precompile
docker stop mampf
docker start mampf
```
Now you can access *mampf* via `http://localhost:$OUTSIDEPORT`.
2. Create an environment file based on the example in docker/production/docker.env
3. Create a docker-compose file based on docker/production/docker-compose.production.yml . We recommend serving upload caches, submissions and media files by a separate server. They communicate with Mampf using NFS as Docker volumes. See the example options in the sample file.
4. Launch MaMpf using `docker-compose up -d`
5. (Optional) Scale MaMpf horizontally by spawning more workers `docker-compose scale worker=5`
Now you can access *mampf* via `http://localhost:$OUTSIDEPORT`.

Use the GUI to register your future admin user.
Open a rails console inside the docker container.
```
rails c
docker-compose exec master rails c
```
Give admin rights to this user:
```
User.first.update(admin: true)
```
That's it. Everything else can be done entirely via the GUI. In a production environment you might want to delete upload caches `/usr/src/app/public/uploads/cache/*` and expired quizzes (`bundle exec rake cleanup:destroy_random_quizzes`) regularly.
That's it. Everything else can be done entirely via the GUI.
12 changes: 12 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Security Policy

## Supported Versions

We only release patches for the production branch.

## Reporting a Vulnerability

Please report (suspected) security vulnerabilities to
mampf-security@mathi.uni-heidelberg.de. You will receive a response from us
within 48 hours. If the issue is confirmed, we will release a patch as soon
as possible depending on complexity but usually within a few days.
3 changes: 2 additions & 1 deletion app/controllers/assignments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ def set_assignment_locale

def assignment_params
params.require(:assignment).permit(:title, :medium_id, :lecture_id,
:deadline, :accepted_file_type, :protected)
:deadline, :accepted_file_type,
:deletion_date)
end
end
3 changes: 2 additions & 1 deletion app/controllers/media_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,8 @@ def publish_params
params.require(:medium).permit(:release_now, :released, :release_date,
:lock_comments, :publish_vertices,
:create_assignment, :assignment_title,
:assignment_deadline, :assignment_file_type)
:assignment_deadline, :assignment_file_type,
:assignment_deletion_date)
end

def set_medium
Expand Down
2 changes: 2 additions & 0 deletions app/mailers/notification_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def submission_rejection_email

def submission_deletion_email
@term = params[:term]
@deletion_date = params[:deletion_date]
subject = params[:reminder] ? t('basics.reminder') + ': ' : ''
subject += t('mailer.submission_deletion_subject',
term: @term.to_label)
Expand All @@ -138,6 +139,7 @@ def submission_deletion_email
def submission_deletion_lecture_email
@term = params[:term]
@lecture = params[:lecture]
@deletion_date = params[:deletion_date]
subject = params[:reminder] ? t('basics.reminder') + ': ' : ''
subject += t('mailer.submission_deletion_lecture_subject',
term: @term.to_label,
Expand Down
19 changes: 19 additions & 0 deletions app/models/assignment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ class Assignment < ApplicationRecord

validates :title, uniqueness: { scope: [:lecture_id] }, presence: true
validates :deadline, presence: true
validates :deletion_date, presence: true
validate :deletion_date_cannot_be_in_the_past

def deletion_date_cannot_be_in_the_past
return unless deletion_date.present? && deletion_date < Time.zone.now.to_date

errors.add(:deletion_date, I18n.t('activerecord.errors.models.' \
'assignment.attributes.deletion_date.' \
'in_past'))
end

scope :active, -> { where('deadline >= ?', Time.now) }

Expand All @@ -25,6 +35,14 @@ def submission(user)
&.first&.submission
end

def submitter_ids
UserSubmissionJoin.where(submission: submissions).pluck(:user_id).uniq
end

def submitters
User.where(id: submitter_ids)
end

def active?
Time.now <= deadline
end
Expand Down Expand Up @@ -126,4 +144,5 @@ def accepted_for_file_input
return accepted_file_type unless accepted_file_type == '.tar.gz'
'.gz'
end

end
30 changes: 26 additions & 4 deletions app/models/medium_publisher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
class MediumPublisher
attr_reader :medium_id, :user_id, :release_now, :release_for, :release_date,
:lock_comments, :vertices, :create_assignment, :assignment_title,
:assignment_file_type, :assignment_deadline
:assignment_file_type, :assignment_deadline,
:assignment_deletion_date

def initialize(medium_id:, user_id:, release_now:,
release_for: 'all', release_date: nil,
lock_comments: false, vertices: false,
create_assignment: false, assignment_title: '',
assignment_file_type: '', assignment_deadline: nil)
assignment_file_type: '', assignment_deadline: nil,
assignment_deletion_date: nil)
@medium_id = medium_id
@user_id = user_id
@release_now = release_now
Expand All @@ -22,6 +24,7 @@ def initialize(medium_id:, user_id:, release_now:,
@assignment_title = assignment_title
@assignment_file_type = assignment_file_type
@assignment_deadline = assignment_deadline
@assignment_deletion_date = assignment_deletion_date
end

def self.load(text)
Expand All @@ -43,6 +46,11 @@ def self.parse(medium, user, params)
rescue ArgumentError
puts 'Argument error for medium assignment deadline'
end
begin
assignment_deletion_date = Time.zone.parse(params[:assignment_deletion_date] || '')
rescue ArgumentError
puts 'Argument error for medium assignment deletion date'
end
MediumPublisher.new(medium_id: medium.id, user_id: user.id,
release_now: params[:release_now] == '1',
release_for: params[:released],
Expand All @@ -52,7 +60,8 @@ def self.parse(medium, user, params)
create_assignment: params[:create_assignment] == '1',
assignment_title: params[:assignment_title],
assignment_file_type: params[:assignment_file_type],
assignment_deadline: assignment_deadline)
assignment_deadline: assignment_deadline,
assignment_deletion_date: assignment_deletion_date)
end

def publish!
Expand All @@ -78,7 +87,8 @@ def assignment
medium_id: @medium_id,
title: @assignment_title,
deadline: @assignment_deadline,
accepted_file_type: @assignment_file_type)
accepted_file_type: @assignment_file_type,
deletion_date: @assignment_deletion_date)
end

def errors
Expand All @@ -89,6 +99,7 @@ def errors
return {} unless @create_assignment

add_assignment_deadline_error if invalid_assignment_deadline?
add_assignment_deletion_date_error if invalid_assignment_deletion_date?
add_assignment_title_error if invalid_assignment_title?
@errors
end
Expand Down Expand Up @@ -160,6 +171,10 @@ def invalid_assignment_deadline?
@assignment_deadline.nil? || (@assignment_deadline < earliest_deadline)
end

def invalid_assignment_deletion_date?
@assignment_deletion_date.nil? || (@assignment_deletion_date < Time.zone.today)
end

def invalid_assignment_title?
@assignment_title.blank? ||
@assignment_title.in?(Assignment.where(lecture: medium.teachable)
Expand All @@ -175,6 +190,13 @@ def add_assignment_deadline_error
'.invalid_assignment_deadline')
end

def add_assignment_deletion_date_error
@errors[:assignment_deletion_date] = I18n.t('activerecord.errors.' \
'models.assignment.' \
'attributes.deletion_date.' \
'in_past')
end

def add_assignment_title_error
@errors[:assignment_title] = I18n.t('admin.medium' \
'.invalid_assignment_title')
Expand Down
Loading

0 comments on commit 019e7b4

Please sign in to comment.