diff --git a/Sources/SIS/sis-app/app/assets/config/manifest.js b/Sources/SIS/sis-app/app/assets/config/manifest.js new file mode 100644 index 0000000..b16e53d --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/config/manifest.js @@ -0,0 +1,3 @@ +//= link_tree ../images +//= link_directory ../javascripts .js +//= link_directory ../stylesheets .css diff --git a/Sources/SIS/sis-app/app/assets/javascripts/application.js b/Sources/SIS/sis-app/app/assets/javascripts/application.js new file mode 100644 index 0000000..b12018d --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/javascripts/application.js @@ -0,0 +1,16 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. JavaScript code in this file should be added after the last require_* statement. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require jquery +//= require jquery_ujs +//= require turbolinks +//= require_tree . diff --git a/Sources/SIS/sis-app/app/assets/javascripts/cable.js b/Sources/SIS/sis-app/app/assets/javascripts/cable.js new file mode 100644 index 0000000..71ee1e6 --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/javascripts/cable.js @@ -0,0 +1,13 @@ +// Action Cable provides the framework to deal with WebSockets in Rails. +// You can generate new channels where WebSocket features live using the rails generate channel command. +// +//= require action_cable +//= require_self +//= require_tree ./channels + +(function() { + this.App || (this.App = {}); + + App.cable = ActionCable.createConsumer(); + +}).call(this); diff --git a/Sources/SIS/sis-app/app/assets/javascripts/courses.coffee b/Sources/SIS/sis-app/app/assets/javascripts/courses.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/javascripts/courses.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/Sources/SIS/sis-app/app/assets/javascripts/users.coffee b/Sources/SIS/sis-app/app/assets/javascripts/users.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/javascripts/users.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/Sources/SIS/sis-app/app/assets/stylesheets/application.css b/Sources/SIS/sis-app/app/assets/stylesheets/application.css new file mode 100644 index 0000000..2692437 --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/stylesheets/application.css @@ -0,0 +1,13 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS + * files in this directory. Styles in this file should be added after the last require_* statement. + * It is generally better to create a new file per style scope. + */ + diff --git a/Sources/SIS/sis-app/app/assets/stylesheets/courses.scss b/Sources/SIS/sis-app/app/assets/stylesheets/courses.scss new file mode 100644 index 0000000..0cae8cc --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/stylesheets/courses.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the courses controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/Sources/SIS/sis-app/app/assets/stylesheets/scaffolds.scss b/Sources/SIS/sis-app/app/assets/stylesheets/scaffolds.scss new file mode 100644 index 0000000..4ce4266 --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/stylesheets/scaffolds.scss @@ -0,0 +1,89 @@ +body { + background-color: #fff; + color: #333; + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; + margin: 33px; +} + +p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; + margin: 33px; +} + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; +} + +a { + color: #000; + + &:visited { + color: #666; + } + + &:hover { + color: #fff; + background-color: #000; + } +} + +th { + padding-bottom: 5px; +} + +td { + padding-bottom: 7px; + padding-left: 5px; + padding-right: 5px; +} + +div { + &.field, &.actions { + margin-bottom: 10px; + } +} + +#notice { + color: green; +} + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; +} + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px; + padding-bottom: 0; + margin-bottom: 20px; + background-color: #f0f0f0; + + h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + margin-bottom: 0; + background-color: #c00; + color: #fff; + } + + ul li { + font-size: 12px; + list-style: square; + } +} + +label { + display: block; +} diff --git a/Sources/SIS/sis-app/app/assets/stylesheets/users.scss b/Sources/SIS/sis-app/app/assets/stylesheets/users.scss new file mode 100644 index 0000000..1efc835 --- /dev/null +++ b/Sources/SIS/sis-app/app/assets/stylesheets/users.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the users controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/Sources/SIS/sis-app/app/channels/application_cable/channel.rb b/Sources/SIS/sis-app/app/channels/application_cable/channel.rb new file mode 100644 index 0000000..d672697 --- /dev/null +++ b/Sources/SIS/sis-app/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/Sources/SIS/sis-app/app/channels/application_cable/connection.rb b/Sources/SIS/sis-app/app/channels/application_cable/connection.rb new file mode 100644 index 0000000..0ff5442 --- /dev/null +++ b/Sources/SIS/sis-app/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/Sources/SIS/sis-app/app/controllers/application_controller.rb b/Sources/SIS/sis-app/app/controllers/application_controller.rb new file mode 100644 index 0000000..1c07694 --- /dev/null +++ b/Sources/SIS/sis-app/app/controllers/application_controller.rb @@ -0,0 +1,3 @@ +class ApplicationController < ActionController::Base + protect_from_forgery with: :exception +end diff --git a/Sources/SIS/sis-app/app/controllers/courses_controller.rb b/Sources/SIS/sis-app/app/controllers/courses_controller.rb new file mode 100644 index 0000000..c3c8bc5 --- /dev/null +++ b/Sources/SIS/sis-app/app/controllers/courses_controller.rb @@ -0,0 +1,76 @@ +class CoursesController < ApplicationController + before_action :set_course, only: [:show, :edit, :update, :destroy] + + # GET /courses + # GET /courses.json + def index + @courses = Course.all + end + + # GET /courses/1 + # GET /courses/1.json + def show + end + + # GET /courses/new + def new + @course = Course.new + @users = User.all + end + + # GET /courses/1/edit + def edit + @users = User.all + end + + # POST /courses + # POST /courses.json + def create + @course = Course.new(course_params) + + respond_to do |format| + if @course.save + format.html { redirect_to @course, notice: 'Course was successfully created.' } + format.json { render :show, status: :created, location: @course } + else + format.html { render :new } + format.json { render json: @course.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /courses/1 + # PATCH/PUT /courses/1.json + def update + respond_to do |format| + if @course.update(course_params) + format.html { redirect_to @course, notice: 'Course was successfully updated.' } + format.json { render :show, status: :ok, location: @course } + else + format.html { render :edit } + format.json { render json: @course.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /courses/1 + # DELETE /courses/1.json + def destroy + @course.destroy + respond_to do |format| + format.html { redirect_to courses_url, notice: 'Course was successfully destroyed.' } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_course + @course = Course.find(params[:id]) + end + + # Never trust parameters from the scary internet, only allow the white list through. + def course_params + params.require(:course).permit(:course_name, :course_number, :user_ids => []) + end +end diff --git a/Sources/SIS/sis-app/app/controllers/users_controller.rb b/Sources/SIS/sis-app/app/controllers/users_controller.rb new file mode 100644 index 0000000..936b0cf --- /dev/null +++ b/Sources/SIS/sis-app/app/controllers/users_controller.rb @@ -0,0 +1,77 @@ +class UsersController < ApplicationController + before_action :set_user, only: [:show, :edit, :update, :destroy] + + # GET /users + # GET /users.json + def index + @users = User.all + end + + # GET /users/1 + # GET /users/1.json + def show + end + + # GET /users/new + def new + @user = User.new + @courses = Course.all + end + + # GET /users/1/edit + def edit + @courses = Course.all + end + + # POST /users + # POST /users.json + def create + @user = User.new(user_params) + @user.write_to_ldap + + respond_to do |format| + if @user.save + format.html { redirect_to @user, notice: 'User was successfully created.' } + format.json { render :show, status: :created, location: @user } + else + format.html { render :new } + format.json { render json: @user.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /users/1 + # PATCH/PUT /users/1.json + def update + respond_to do |format| + if @user.update(user_params) + format.html { redirect_to @user, notice: 'User was successfully updated.' } + format.json { render :show, status: :ok, location: @user } + else + format.html { render :edit } + format.json { render json: @user.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /users/1 + # DELETE /users/1.json + def destroy + @user.destroy + respond_to do |format| + format.html { redirect_to users_url, notice: 'User was successfully destroyed.' } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_user + @user = User.find(params[:id]) + end + + # Never trust parameters from the scary internet, only allow the white list through. + def user_params + params.require(:user).permit(:uid, :givenname, :surname, :fullName, :description, :email, :password, :course_ids => []) + end +end diff --git a/Sources/SIS/sis-app/app/helpers/application_helper.rb b/Sources/SIS/sis-app/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/Sources/SIS/sis-app/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/Sources/SIS/sis-app/app/helpers/courses_helper.rb b/Sources/SIS/sis-app/app/helpers/courses_helper.rb new file mode 100644 index 0000000..c159f1e --- /dev/null +++ b/Sources/SIS/sis-app/app/helpers/courses_helper.rb @@ -0,0 +1,2 @@ +module CoursesHelper +end diff --git a/Sources/SIS/sis-app/app/helpers/users_helper.rb b/Sources/SIS/sis-app/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/Sources/SIS/sis-app/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/Sources/SIS/sis-app/app/jobs/application_job.rb b/Sources/SIS/sis-app/app/jobs/application_job.rb new file mode 100644 index 0000000..a009ace --- /dev/null +++ b/Sources/SIS/sis-app/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/Sources/SIS/sis-app/app/mailers/application_mailer.rb b/Sources/SIS/sis-app/app/mailers/application_mailer.rb new file mode 100644 index 0000000..286b223 --- /dev/null +++ b/Sources/SIS/sis-app/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' +end diff --git a/Sources/SIS/sis-app/app/models/application_record.rb b/Sources/SIS/sis-app/app/models/application_record.rb new file mode 100644 index 0000000..10a4cba --- /dev/null +++ b/Sources/SIS/sis-app/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/Sources/SIS/sis-app/app/models/course.rb b/Sources/SIS/sis-app/app/models/course.rb new file mode 100644 index 0000000..fd93fb7 --- /dev/null +++ b/Sources/SIS/sis-app/app/models/course.rb @@ -0,0 +1,3 @@ +class Course < ActiveRecord::Base + has_and_belongs_to_many :users +end diff --git a/Sources/SIS/sis-app/app/models/user.rb b/Sources/SIS/sis-app/app/models/user.rb new file mode 100644 index 0000000..b0935ab --- /dev/null +++ b/Sources/SIS/sis-app/app/models/user.rb @@ -0,0 +1,38 @@ +require 'net/ldap' + +class User < ApplicationRecord + has_and_belongs_to_many :courses + + def name + return givenname + " " + surname + end + + def write_to_ldap + ldap_host = LDAP_CONFIG['host'] + ldap_port = LDAP_CONFIG['port'] + ldap_base = LDAP_CONFIG['base'] + ldap_user = LDAP_CONFIG['admin'] + ldap_pass = LDAP_CONFIG['pass'] + + # create the DN for the object + dn = "uid="+uid+","+ldap_base + + # create the list of attributes for the object + attr = { + :cn => fullName, + :objectclass => ['organizationalperson','person','top','inetOrgPerson','eduPerson'], + :givenName => givenname, + :sn => surname, + :uid => uid, + :userPassword => password + } + + # connect and add the entry + Net::LDAP.open( :host => ldap_host, :port => ldap_port, :base => ldap_base, :auth => { :method => :simple, :username => ldap_user, :password => ldap_pass }) do |ldap| + ldap.add( :dn => dn, :attributes => attr) + end + end + + + +end diff --git a/Sources/SIS/sis-app/app/views/courses/_course.json.jbuilder b/Sources/SIS/sis-app/app/views/courses/_course.json.jbuilder new file mode 100644 index 0000000..d786f98 --- /dev/null +++ b/Sources/SIS/sis-app/app/views/courses/_course.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! course, :id, :course_name, :course_number, :created_at, :updated_at +json.url course_url(course, format: :json) diff --git a/Sources/SIS/sis-app/app/views/courses/_form.html.erb b/Sources/SIS/sis-app/app/views/courses/_form.html.erb new file mode 100644 index 0000000..46472a1 --- /dev/null +++ b/Sources/SIS/sis-app/app/views/courses/_form.html.erb @@ -0,0 +1,31 @@ +<%= form_for(course) do |f| %> + <% if course.errors.any? %> +
<%= notice %>
+ +| Course name | +Course number | +Students | ++ | ||
|---|---|---|---|---|---|
| <%= course.course_name %> | +<%= course.course_number %> | +<%= course.users.map {|k| k.name}.join(', ') %> | +<%= link_to 'Show', course %> | +<%= link_to 'Edit', edit_course_path(course) %> | +<%= link_to 'Destroy', course, method: :delete, data: { confirm: 'Are you sure?' } %> | +
<%= notice %>
+ ++ Course name: + <%= @course.course_name %> +
+ ++ Course number: + <%= @course.course_number %> +
+ ++ Students: + <%= @course.users.map {|k| k.name}.join(', ') %> +
+ +<%= link_to 'Edit', edit_course_path(@course) %> | +<%= link_to 'Back', courses_path %> diff --git a/Sources/SIS/sis-app/app/views/courses/show.json.jbuilder b/Sources/SIS/sis-app/app/views/courses/show.json.jbuilder new file mode 100644 index 0000000..a85c000 --- /dev/null +++ b/Sources/SIS/sis-app/app/views/courses/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "courses/course", course: @course diff --git a/Sources/SIS/sis-app/app/views/layouts/application.html.erb b/Sources/SIS/sis-app/app/views/layouts/application.html.erb new file mode 100644 index 0000000..48241f7 --- /dev/null +++ b/Sources/SIS/sis-app/app/views/layouts/application.html.erb @@ -0,0 +1,14 @@ + + + +<%= notice %>
+ +| Uid | +Givenname | +Surname | +Fullname | +Description | +Password | ++ | |||
|---|---|---|---|---|---|---|---|---|---|
| <%= user.uid %> | +<%= user.givenname %> | +<%= user.surname %> | +<%= user.fullName %> | +<%= user.description %> | +<%= user.email %> | +<%= user.password %> | +<%= link_to 'Show', user %> | +<%= link_to 'Edit', edit_user_path(user) %> | +<%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %> | +
<%= notice %>
+ ++ Uid: + <%= @user.uid %> +
+ ++ Givenname: + <%= @user.givenname %> +
+ ++ Surname: + <%= @user.surname %> +
+ ++ Fullname: + <%= @user.fullName %> +
+ ++ Description: + <%= @user.description %> +
+ ++ Email: + <%= @user.email %> +
+ ++ Password: + <%= @user.password %> +
+ ++ Courses: + <%= @user.courses.map {|c| c.course_name}.join(', ') %> +
+ +<%= link_to 'Edit', edit_user_path(@user) %> | +<%= link_to 'Back', users_path %> diff --git a/Sources/SIS/sis-app/app/views/users/show.json.jbuilder b/Sources/SIS/sis-app/app/views/users/show.json.jbuilder new file mode 100644 index 0000000..ff40bb9 --- /dev/null +++ b/Sources/SIS/sis-app/app/views/users/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "users/user", user: @user diff --git a/Sources/SIS/sis-app/bin/bundle b/Sources/SIS/sis-app/bin/bundle new file mode 100644 index 0000000..66e9889 --- /dev/null +++ b/Sources/SIS/sis-app/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/Sources/SIS/sis-app/bin/rails b/Sources/SIS/sis-app/bin/rails new file mode 100644 index 0000000..5badb2f --- /dev/null +++ b/Sources/SIS/sis-app/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/Sources/SIS/sis-app/bin/rake b/Sources/SIS/sis-app/bin/rake new file mode 100644 index 0000000..d87d5f5 --- /dev/null +++ b/Sources/SIS/sis-app/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/Sources/SIS/sis-app/bin/setup b/Sources/SIS/sis-app/bin/setup new file mode 100644 index 0000000..e620b4d --- /dev/null +++ b/Sources/SIS/sis-app/bin/setup @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:setup' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/Sources/SIS/sis-app/bin/spring b/Sources/SIS/sis-app/bin/spring new file mode 100644 index 0000000..fb2ec2e --- /dev/null +++ b/Sources/SIS/sis-app/bin/spring @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) + spring = lockfile.specs.detect { |spec| spec.name == "spring" } + if spring + Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path + gem 'spring', spring.version + require 'spring/binstub' + end +end diff --git a/Sources/SIS/sis-app/bin/update b/Sources/SIS/sis-app/bin/update new file mode 100644 index 0000000..a8e4462 --- /dev/null +++ b/Sources/SIS/sis-app/bin/update @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end