diff --git a/app/controllers/saml_logins_controller.rb b/app/controllers/saml_logins_controller.rb new file mode 100644 index 0000000..8a999cf --- /dev/null +++ b/app/controllers/saml_logins_controller.rb @@ -0,0 +1,34 @@ +class SamlLoginsController < ApplicationController + + require "net/http" + require "uri" + require 'rexml/document' + include REXML + + def index + + if params[:wa] == "wsignoutcleanup1.0" #logout + + redirect_to :root + + else #login + + + @wresult = params[:wresult] + @wctx = params[:wctx] + + @main_url = LIST[:sites][@wctx]['url'] + @main_public_key = LIST[:sites][@wctx]['key'] + + @doc = REXML::Document.new @wresult + + public_key = OpenSSL::PKey::RSA.new(@main_public_key) + encrypted_data = public_key.public_encrypt(@doc.elements["//saml:AttributeValue"].text) + + redirect_to "http://#{@main_url}/user_login?" + { :wresult => encrypted_data }.to_param + + end + + end + +end diff --git a/app/jobs/get_announcement_from_rss.rb b/app/jobs/get_announcement_from_rss.rb new file mode 100644 index 0000000..267c29a --- /dev/null +++ b/app/jobs/get_announcement_from_rss.rb @@ -0,0 +1,7 @@ +class GetAnnouncementFromRss + @queue = :high + + def self.perform() + %x(ruby "#{Rails.root}/lib/rss_ntu_job.rb") + end +end \ No newline at end of file diff --git a/config/list.yml b/config/list.yml index b9722e7..c8962cf 100644 --- a/config/list.yml +++ b/config/list.yml @@ -80,3 +80,48 @@ default_widget_style: - style3 - style4 - style5 + +sites: + www: + url: www.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3fDAM40XvEiM5oG7YbA\nKnhc5Dyv/ZhVDzyrg95QB0ylBPtSs6g5xgkSSQMnIpAUCzdVIMrUd/A6DuH6f+T5\nccshgh3aDj3wISfgYZc9e7WY1csOItq9lOr6YG4HEABSyjVCcX/RrB8kCuuIGcvR\nRnvu/4fFb93vsVYHwGuivTYRJ+8VM8fOtIFCvbCxZsFj6r5cMl4qI4g4vaIn3xf2\ndXUCICebvdIBfMAdW29yaCScEap1oawEfdXtKCD5vYvAaRZ85jLY/FV5dYhbe1dz\n9G7+B1HI7VBm5bKV0MI1ZH2MTRczaqjLGf6ZF0FbMmcMYLx8iEGL1z0/hgOTcNT6\nrQIDAQAB\n-----END PUBLIC KEY-----\n" + ga: + url: www.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3fDAM40XvEiM5oG7YbA\nKnhc5Dyv/ZhVDzyrg95QB0ylBPtSs6g5xgkSSQMnIpAUCzdVIMrUd/A6DuH6f+T5\nccshgh3aDj3wISfgYZc9e7WY1csOItq9lOr6YG4HEABSyjVCcX/RrB8kCuuIGcvR\nRnvu/4fFb93vsVYHwGuivTYRJ+8VM8fOtIFCvbCxZsFj6r5cMl4qI4g4vaIn3xf2\ndXUCICebvdIBfMAdW29yaCScEap1oawEfdXtKCD5vYvAaRZ85jLY/FV5dYhbe1dz\n9G7+B1HI7VBm5bKV0MI1ZH2MTRczaqjLGf6ZF0FbMmcMYLx8iEGL1z0/hgOTcNT6\nrQIDAQAB\n-----END PUBLIC KEY-----\n" + doc: + url: doc.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4aE7R0/49UBf5v4rbNiA\nnaXjPZ9rio9fjkaAZeow62yaZtoGurqf44BVj/cjQVUmLnMU4WDcZMI0osLa15+H\ndXSGCP8Upmvi+eA2UqhhBZts1IQ33rPMAjePAbpSGbNRxous0VpH7cc9BxMffQwh\nsygcbghUCEE3dVWdTFGokvgxkBzaKKTNbiqhmbuc8QIuzOvFFGkZHgqlxFHcaNYZ\n7KZJxqvuKSXsJcxIsQKzDiAPI11J3zgRdIf/CFVQv5g15gl1ieQgFdGc3jplsBcd\nrdLApPZ39+BWr9a/Gj9lgP6Ll5G/cM4Uq18a7TCWJIC9PNGw8bBDJTjnUEqmOu3R\nZQIDAQAB\n-----END PUBLIC KEY-----\n" + cashier: + url: cashier.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9wliL8gFsRn0DVZusd2h\nSoj6aQWkKq1UU6fj3vzcrb1adMy8RnKogTW6z1W9wxrcrI/GfyRz9Wop0+9+XNYx\nDH+QQ+/1po/O/MkPBGZ6WxXpH2BSCncdJdYZ9qLvlJHHRhFtczcSQki693MCDUCy\nMrMDvmL4YOowHExD7A5qrCIaYnbNcUCYMKluSLxR52AUeAuYjCwZbkgEwIQRdZ+M\n3JMgTD/9GFsvZ4c5x6n1cUnKCJNyyUIvI8jThtOnySCU8ZN17nWfKb1Cxavt17Vp\nGSdyIIL2SO9+rjOFW3PrAyX5P3xEgPYoDxA1QsYLYbj189qA0sT17xf9H7KcNzyP\n7wIDAQAB\n-----END PUBLIC KEY-----\n" + general: + url: general.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvyFUUFyaEJgsR+bYhTXx\nOA60kw82ohyHCDzkoHDT/k2xS520RZR0AzxT449qD3XfRr0+7F0c6rMx/2pBG7hS\nlHjgrTX7eQ70wV8H4OApriDIp1UDemm4+fKxcPZ6vhWqzp+3ijPdhJXe7OC9D89I\n9QKdlHPBxKFnUrBJiqn3cHGLpRrYTsKpI/Nl7VW4UJJh0k7R7P1Jqry0e+HalOLB\nBu5kl5z6iYBPy1gJ4psDHWuoNboxIgIsVR1SSLM7Mooebwx2qjm3W4VQuc7eQk0g\nh7KH4B8CrK4bC+K6lAS3ZzmTlA6M1WZPtIKv3XqEYCkyomMnkdTNZQYKbCKKlLBo\ntQIDAQAB\n-----END PUBLIC KEY-----\n" + social: + url: social.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqB8htGdGzDPs3GA76REG\nyjM0eEYdXV6ugi4hPZEViCOBg3POC5RZslA5oTCYYWfTVui8jHC2CPD3AYQLG67Z\n79g2miLHEEyDzG7dp//dc85qp0FYR2JII1y26fJutMVCgn0hth6OpfjPB2QhkgZf\nat+Ico5ppDYIx+4jX8xQr4qqRlUIAmECMAE5ATiAUqfv117GJG/fR3AsKZPYm2U1\nFhSpKT2mvC0AiqstZzxYEm4srl1ZjpJPJ7uU+ewvi/EhRyLWFGPmygP6fvg4IaKS\nG00dx7FGedyLVcSaxJCoCX5Z98hIYEStanCSzuR3FQEL0JaB8ZKKWY8dsB+U1v46\nQwIDAQAB\n-----END PUBLIC KEY-----\n" + property: + url: property.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1bmnJSRmxcehehuKBwSQ\nXiuYhAxzUOmptIk0sgciB1hK8++anXMaHXf3QA6UiXWjNyU+g2ZL1nVfVl0Qd3Ps\nxM2+hSeZRus2sw0g7CQea7NkAqLGQrpicnZ8Fgcb+0qwgClk0RVBXwJzfTDu6V+5\nL9lLEKWnSdHmoGkxkZTPMAtJpXYx9SMLtljPYGkMWKY2C1cBqPdMOl/rKTUZ9dYp\n2eJ13NTXDJJgDJOhDFHevzK/I6kwxdJbetNo4IO1dhQdbPionR5SNkkCNZvfy3k3\n68+xopPKH3xECCIuxorcePx0hyoeXS8vdmJ09VKHVUz08LBYGq2S/36V5LIc1P/6\nSQIDAQAB\n-----END PUBLIC KEY-----\n" + procurement: + url: procurement.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAze/Yr3vrpRBpeu7ohyEP\nboPvZ476dtANbvW+rMuDyKeGD5FfoZYwzF+AbMIK6KfleWizObnMM8ABC0LdBuag\nQ0Brk4FMxyKz0aXlSgG3OZiZXJaaWm2/+gqghgpBLpAPMRFnEmK2y11b/EgCxurV\nl+RZ/MgrIviRGipnU7GXfG4O7Ai21oD4lzKt3WbvuWgBdgtEsYpZMIyddWrhkUki\noM39Vm72mCyKPkysCVYCnYaMwDXVx/SKuTRHiVQZ4GNIv74rwp7BOCkfDZ8HrNLH\nr3ObCB8X0Bh9GqUUj7gYu3cFmx8lXer7qkGtGUq2wNUM0CBc01EODVO9e9RQnulA\n3wIDAQAB\n-----END PUBLIC KEY-----\n" + fss: + url: fss.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzsvi4FfIQokfP2QmiRTs\nzuxjPg7oPK7pLHNQC/AyY35H0vmkXGTc74pVvLbfSuaprLO10WVzE4bGGQmhmls1\nDqeY7EyHg1vs7GHQm1932n+Va+qDToSx7S+Zs1ZOglYAdEzBI3dyhefIcDtNUfty\n0i64RGiEzDH4yV5lecilXo5Q4/7W/HNdtw8Oe//LopOZ2Mj+Eq7Tk70WkGFDV73Z\n/jIBLBn51g2P9nrsid63OLe1X8u0l9+xSGff0fR1VlqbElBRACCrAmPvs9ceOW7H\n+yLw71elR4nMDm+/dx/zimeYUj0WaY2A3/O8xucPhSP22YCRiO1jEsAEvMXkCU9p\n8wIDAQAB\n-----END PUBLIC KEY-----\n" + medicine: + url: medicine.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwx7zQLnde6Azy/03bIxg\nkp5rM0DsKKkBbX8C5vhUADxaC2zVmVJuF0NnTGCWutNSSYsKWRKzFwEoZdzJ+8XS\nr8f9kRdEB0yu3Akv+EhZyHA7yVGyFvNAhPGVuekSmpDlpFFKanAqlhBzrhByku5A\nTqp2fXi3zHMoP6WX8QXb6SpG/y4CBpjXCI1qLCAJRw0Fkt7yMXkJnjO2q7zCKAnU\nnv6DVz5yDuBiZPfYlW09KHVWxSehgk5fvLu9Jb/s1XklPwEw1m5BPhIA1YG0QelR\nXk9Pdvwb7aM59LZx1xQZYcku0KGSqLo9rCDTD8YT47226v921yeM36Az8t8e4egU\nzwIDAQAB\n-----END PUBLIC KEY-----\n" + police: + url: police.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzKawlFWAMzA/uV/kcewd\nmtj8PcqxosmnSh7ZzJ0DumG2ieeP9oDBicqbqIEaeJVvrRzYJD2a+u8x5KKMKB8J\nHbMUpCBFlIpkDMjU/oZVMcYT9pcH51QWNvCgHG7prVykSGFz1JRvjSP6cwuZKBFd\nFFneOViETqoMIO1DbRLXsGfPvMOJY9C1xDwv1dLv0Wbj7M9N6eNz06a50bu3I4gl\nMumxWnZUabXL3G62S/Si4NM7J2jOUnkEOxJWOhcAX/iiqS9T8AHu84um2+mLQpfB\nJJFFIWCIAtU78VnIN5JSWwjFU5TsiSyCFYpGXKxUFD25cFmt3SfG0gwmrFis5Pdn\nhwIDAQAB\n-----END PUBLIC KEY-----\n" + construction: + url: construction.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvxJcKnPUDaNNyhdGpedL\n+h2OI9RDDZUTkHcvX1UvBNvlX2+dvok6sHQh2AhZoNyCUFZTbp2CRSNfIM5jXigD\nfHA3KzpN7cmGG7W7nIdBBkZU/ly4HFvkD7mGoEymB0JYgZkz59CXBx+3Zg6KLSYY\nZDoOw6wikrl643So2zFZvwHJpDkRkmX5oWWYqXOZxaZnkgbhvA3KdcH9+C1aEBYY\npY2K2MJt86k0ahW/CJfVRDb9CWSxAGir1RAPu9bRV9y9WWKKGWekH0/IqhhJPT8q\nl3v6PB1Oc6ltbOyYkS2xHbmvRxjORzGen0Xcbjzo4N8HBEoPe0Uc5iP0Y50GDjEL\nEQIDAQAB\n-----END PUBLIC KEY-----\n" + sec: + url: sec.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApsVKJ8Cvr/A0dmHR+vDS\nAYjVzGqMNJ/4pO7GwMzUZMNSkpq3b9CIjrIGg/QKj7woTHnKM39vczu5gxPXJGYN\nIo+PnWsibMDjcz2Vm8s11XXIPho/Ce+hQkWpWGzxpaH7Z/qLKSwiwHdHhlgN3fWw\njR8jYhreQYfohkRGR70h8A9TTU4YkFY/+8yIdwGns61+5tK981kMbVkm+pcgL0cP\nMN08I7MM+c87COY6IO27jVb/ALPAYpo+QUdAfEp5hlI7BQW95nB7LHOnxAm7lLTD\nhbdETUssieQUicwgDpGa2aD769nH+V3UCp0nA4yPDWyJJyKEWsD5EEK24VAcotql\nkwIDAQAB\n-----END PUBLIC KEY-----\n" + info: + url: info.ga.ntu.edu.tw + key: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5MLcsMcedzVWjw7pd/lr\nf8GdrzV6rubsJgEBJbC2OdrloHc+7uxEwWiYNTfg4j46nY/zCuTqzV/Wcfni5pY8\n0yuOmZdH9LjK0PW5BgXYJwe/bZkQmQcIQhkoSPghR8o+kZlI0a3+3gs4eAkpxB21\nPR5Rg2fvzDkaO3WcHf13HymayIk9wn4i0NdLUXgKSWcz5XNJtVBh6jtMkDq7ioOH\nQZT9OAODFw5CW/TvXBJaAvSEdDHsCNTE4vgJO1h6qowC27mErgjilA7TM81JFp40\nwexOW/gXHc4gCsj9BY39tDTqa56QIbJjKdqx7iyHUr1jMFmII1osS1ZVATco9RrM\naQIDAQAB\n-----END PUBLIC KEY-----\n" + diff --git a/config/resque_schedule.yml b/config/resque_schedule.yml index d6a7e83..c7953d4 100644 --- a/config/resque_schedule.yml +++ b/config/resque_schedule.yml @@ -15,3 +15,9 @@ email_cron: class: EmailCron args: description: EmailCron + +get_announcement_from_rss: + cron: 0 0 [2,12] * * * + class: GetAnnouncementFromRss + args: + description: Loop through the announcement RSS until 24h ago diff --git a/config/routes.rb b/config/routes.rb index cbff1d6..c1eca4b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,6 +14,8 @@ Orbit::Application.routes.draw do match 'user_logout' => 'sessions#destroy' end + match "saml_login" => 'saml_logins#index' + mount Resque::Server, :at => "/admin/resque" mount Rack::GridFS::Endpoint.new(:db => Mongoid.database,:lookup=>:path), :at => "gridfs" diff --git a/lib/rss_ntu_job.rb b/lib/rss_ntu_job.rb new file mode 100644 index 0000000..ae68a2c --- /dev/null +++ b/lib/rss_ntu_job.rb @@ -0,0 +1,157 @@ +# encoding: utf-8 + +require 'rss' +require 'mongo' + +SITES = { "總務處-各單位公告" => "0", + "總務處-文書組" => "1", + "總務處-出納組" => "2", + "總務處-事務組" => "3", + "總務處-保管組" => "5", + "總務處-採購組" => "6", + "總務處-經營管理組" => "7", + "總務處-駐衛警察隊" => "9", + "總務處-營繕組" => "10", + "總務處-總務處" => "11", + "社會科學院-社會科學院總務分處" => "4", + "醫學院-醫學院總務分處" => "8" } + +SITE_KEYS = SITES.keys + +DB_BASE_NAME = "production_new" + +all = {} +continue = true +i = 1 +yesterday = Time.now - 86400 + +while continue do + open("http://ann.cc.ntu.edu.tw/asp/rss.asp?page=#{i}") do |rss| + feed = RSS::Parser.parse(rss.read.encode('utf-8', 'big5', invalid: :replace, undef: :replace, replace: '').gsub('Wes,', 'Wed,').gsub(/(encoding=\"big5\")/, 'encoding="utf-8"')) + feed.items.each do |item| + if item.pubDate > yesterday + if SITE_KEYS.include?(item.author) + author = item.author.strip + category = item.category.to_s.gsub(/\<(\/)*category\>/, '') + if all[author] + all[author][item.link.strip] = {title: item.title.strip, author: author, link: item.link.strip, date: item.pubDate, category: category, description: item.description.gsub("\r\n", '
').strip} + else + all[author] = {item.link.strip => {title: item.title.strip, author: author, link: item.link.strip, date: item.pubDate, category: category, description: item.description.gsub("\r\n", '
').strip}} + end + end + else + continue = false + break + end + end + end + i += 1 +end + +# Get corresponding category_id or create a new one +def get_category_id(category, categories, coll_cat, bulletin_module_id) + if categories.keys.include? "rss_#{category}" + [categories["rss_#{category}"], categories] + else + cat = { + _type: "Category", + module_app_id: bulletin_module_id, + key: "rss_#{category}", + disable: false, + custom: false, + title: {:zh_tw => category}, + created_at: Time.now, + updated_at: Time.now + } + + categories["rss_#{category}"] = result = coll_cat.save(cat) + [result, categories] + end +end + +# Get categories and id based on a given site number +def get_mongo_and_categories(site_number="0") + db = Mongo::Connection.new("localhost", 27017).db("#{DB_BASE_NAME}_#{site_number}") + + bulletin_module_id = db["module_apps"].find(key: "announcement").first + + coll_bulletin = db["bulletins"] + coll_buffer_cat = db["buffer_categories"] + coll_cat = db["categories"] + coll_bulletin_cat = db["categories"].find(module_app_id: bulletin_module_id["_id"]) + + categories = coll_bulletin_cat.find().to_a.inject({}) do |categories, category| + categories[category['key']] = category['_id'] + categories + end + [categories, coll_bulletin, coll_cat, bulletin_module_id["_id"],coll_buffer_cat] +end + +# Get main site (總務處) categories +@main_categories, @main_coll_bulletin, @main_coll_cat, @main_bulletin_module_id, @main_coll_buffer_cat = get_mongo_and_categories +@copy_categories, @copy_coll_bulletin, @copy_coll_cat, @copy_bulletin_module_id, @copy_coll_buffer_cat = get_mongo_and_categories('11') + +all.each do |key, value| # Loop through all the authors + site_number = SITES[key] + categories, coll_bulletin, coll_cat, bulletin_module_id, coll_buffer_cat = get_mongo_and_categories(site_number) # Get current's site categories + value.each_value do |bul| # Loop through all the items + category_id, categories = get_category_id(bul[:category], categories, coll_cat, bulletin_module_id) + unless coll_bulletin.find_one(rss_link: bul[:link]) + bulletin = { _type: "Bulletin", + postdate: bul[:date], + created_at: bul[:date], + updated_at: bul[:date], + public: true, + is_checked: true, + is_pending: false, + is_rejected: false, + category_id: category_id, + title: {:zh_tw => bul[:title]}, + text: {:zh_tw => bul[:description]}, + available_for_en: false, + available_for_zh_tw: true, + rss_link: bul[:link], + is_top: false, + is_hot: false, + is_hidden: false } + bs = coll_bulletin.save(bulletin) + + buffer_cat = { _type: "BufferCategory", + category_id: category_id, + categorizable_type: "Bulletin", + categorizable_id: bs } + coll_buffer_cat.save(buffer_cat) + + unless site_number.eql?("0") || @main_coll_bulletin.find_one(rss_link: bul[:link]) # Copy the item to the main site + + category_id, @main_categories = get_category_id(bul[:category], @main_categories, @main_coll_cat, @main_bulletin_module_id) + main_bulletin = bulletin.clone + main_bulletin['_id'] = BSON::ObjectId.new + main_bulletin[:category_id] = category_id + @main_coll_bulletin.save(main_bulletin) + + main_buffer_cat = { _type: "BufferCategory", + category_id: category_id, + categorizable_type: "Bulletin", + categorizable_id: main_bulletin['_id'] } + @main_coll_buffer_cat.save(main_buffer_cat) + + category_id, @copy_categories = get_category_id(bul[:category], @copy_categories, @copy_coll_cat, @copy_bulletin_module_id) + copy_bulletin = bulletin.clone + copy_bulletin['_id'] = BSON::ObjectId.new + copy_bulletin[:category_id] = category_id + @copy_coll_bulletin.save(copy_bulletin) + + copy_buffer_cat = { _type: "BufferCategory", + category_id: category_id, + categorizable_type: "Bulletin", + categorizable_id: copy_bulletin['_id'] } + @copy_coll_buffer_cat.save(copy_buffer_cat) + + end + end + end +end + + +