openskip-skip_embedded 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. data/ChangeLog +4 -0
  2. data/README.rdoc +37 -0
  3. data/Rakefile +87 -0
  4. data/generators/skip_embedded/skip_embedded_generator.rb +30 -0
  5. data/generators/skip_embedded/templates/app/views/shared/_flash_message.html.erb +13 -0
  6. data/generators/skip_embedded/templates/app/views/shared/_skip_full_text_search_form.html.erb +24 -0
  7. data/generators/skip_embedded/templates/public/javascripts/dropdown_navigation.js +12 -0
  8. data/generators/skip_embedded/templates/public/javascripts/labeled_text_field.js +21 -0
  9. data/generators/skip_embedded/templates/public/javascripts/skip_fckeditor_config.js +45 -0
  10. data/generators/skip_embedded/templates/public/stylesheets/skip_embedded.css +79 -0
  11. data/lib/skip_embedded/fulltext_search_cache/builder_base.rb +51 -0
  12. data/lib/skip_embedded/fulltext_search_cache/mediator.rb +67 -0
  13. data/lib/skip_embedded/fulltext_search_cache/partial_loader.rb +19 -0
  14. data/lib/skip_embedded/fulltext_search_cache.rb +38 -0
  15. data/lib/skip_embedded/helpers/ui.rb +46 -0
  16. data/lib/skip_embedded/helpers.rb +13 -0
  17. data/lib/skip_embedded/initial_settings.rb +28 -0
  18. data/lib/skip_embedded/op_fixation.rb +43 -0
  19. data/lib/skip_embedded/open_id_sso/authentication.rb +21 -0
  20. data/lib/skip_embedded/open_id_sso/session_management.rb +42 -0
  21. data/lib/skip_embedded/web_service_util/client.rb +75 -0
  22. data/lib/skip_embedded/web_service_util/server.rb +14 -0
  23. data/lib/skip_embedded/web_service_util.rb +26 -0
  24. data/lib/skip_embedded.rb +4 -0
  25. data/rails/init.rb +6 -0
  26. data/spec/skip_embedded/fulltext_search_cache/builder_base_spec.rb +44 -0
  27. data/spec/skip_embedded/fulltext_search_cache/mediator_spec.rb +49 -0
  28. data/spec/skip_embedded/fulltext_search_cache/partial_loader_spec.rb +20 -0
  29. data/spec/skip_embedded/initial_setting_spec.rb +10 -0
  30. data/spec/skip_embedded/op_fixation_spec.rb +57 -0
  31. data/spec/skip_embedded/web_service_util_spec.rb +197 -0
  32. data/spec/spec_helper.rb +16 -0
  33. metadata +114 -0
data/ChangeLog ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.9 / 2009-03-02
2
+
3
+ * initial release
4
+
data/README.rdoc ADDED
@@ -0,0 +1,37 @@
1
+
2
+ = skip_embedded
3
+
4
+ Utilities to collabolate SKIP, opensource buisiness SNS.
5
+
6
+ == Description
7
+
8
+ skip_embedded make to build skip-collaborate apps easy,
9
+ it have the features...
10
+
11
+ - Create SKIP style fulltext search cache.
12
+
13
+ == Installation
14
+
15
+ === Archive Installation
16
+
17
+ rake install
18
+
19
+ === Gem Installation
20
+
21
+ gem install skip_embedded
22
+
23
+
24
+ == Features/Problems
25
+
26
+ lator
27
+
28
+ == Synopsis
29
+
30
+ lator
31
+
32
+ == Copyright
33
+
34
+ Author:: MOROHASHI Kyosuke k-morohashi@esm.co.jp
35
+ Copyright:: Copyright (c) 2009 SonicGraden LLC # FIXME
36
+ License:: GPL v3
37
+
data/Rakefile ADDED
@@ -0,0 +1,87 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/rdoctask'
4
+ require 'rake/packagetask'
5
+ require 'rake/gempackagetask'
6
+ require 'lib/skip_embedded'
7
+
8
+ desc 'Default: run unit tests.'
9
+ task :default => :spec
10
+
11
+ require 'spec/rake/spectask'
12
+
13
+ desc "Run all specs in spec directory"
14
+ Spec::Rake::SpecTask.new(:spec) do |t|
15
+ t.spec_opts = %w[--colour --format progress --loadby --reverse]
16
+ t.spec_files = FileList['spec/**/*_spec.rb']
17
+ end
18
+
19
+ desc 'Generate documentation for the skip_embedded plugin.'
20
+ Rake::RDocTask.new(:rdoc) do |rdoc|
21
+ rdoc.rdoc_dir = 'rdoc'
22
+ rdoc.title = 'SkipEmbedded'
23
+ rdoc.options << '--line-numbers' << '--inline-source'
24
+ rdoc.rdoc_files.include('README')
25
+ rdoc.rdoc_files.include('lib/**/*.rb')
26
+ end
27
+
28
+ NAME = ENV["GEMNAME"] || "skip_embedded"
29
+ AUTHOR = "MOROHASHI Kyosuke"
30
+ EMAIL = "k-morohashi@esm.co.jp"
31
+ DESCRIPTION = "Utilities to collabolate SKIP, opensource buisiness SNS."
32
+ HOMEPATH = "http://github.com/openskip/skip_embedded/tree/master"
33
+ BIN_FILES = %w( )
34
+
35
+ VERS = SkipEmbedded::Version
36
+ REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
37
+ RDOC_OPTS = [
38
+ '--title', "#{NAME} documentation",
39
+ "--charset", "utf-8",
40
+ "--opname", "index.html",
41
+ "--line-numbers",
42
+ "--main", "README.rdoc",
43
+ "--inline-source",
44
+ ]
45
+
46
+ spec = Gem::Specification.new do |s|
47
+ s.name = NAME
48
+ s.version = VERS
49
+ s.platform = Gem::Platform::RUBY
50
+ s.has_rdoc = true
51
+ s.extra_rdoc_files = ["README.rdoc", "ChangeLog"]
52
+ s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
53
+ s.summary = DESCRIPTION
54
+ s.description = DESCRIPTION
55
+ s.author = AUTHOR
56
+ s.email = EMAIL
57
+ s.homepage = HOMEPATH
58
+ s.executables = BIN_FILES
59
+ s.bindir = "bin" unless BIN_FILES.empty?
60
+ s.require_path = "lib"
61
+ s.test_files = Dir["spec/**/*_spec.rb"]
62
+
63
+ s.files = %w(README.rdoc ChangeLog Rakefile) +
64
+ Dir.glob("{bin,doc,test,lib,templates,generators,extras,website,script}/**/*") +
65
+ Dir.glob("spec/**/*.rb") +
66
+ Dir.glob("ext/**/*.{h,c,rb}") +
67
+ Dir.glob("examples/**/*.rb") +
68
+ Dir.glob("tools/*.rb") +
69
+ Dir.glob("rails/*.rb")
70
+
71
+ s.extensions = FileList["ext/**/extconf.rb"].to_a
72
+ end
73
+
74
+ Rake::GemPackageTask.new(spec) do |p|
75
+ p.need_tar = true
76
+ p.gem_spec = spec
77
+ end
78
+
79
+ desc 'Show information about the gem.'
80
+ task :debug_gem do
81
+ puts spec.to_ruby
82
+ end
83
+
84
+ desc 'Update gem spec'
85
+ task :gemspec do
86
+ open("#{NAME}.gemspec", 'w').write spec.to_ruby
87
+ end
@@ -0,0 +1,30 @@
1
+ class SkipEmbeddedGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ assets = %w[
5
+ app/views/shared/_flash_message.html.erb
6
+ app/views/shared/_skip_full_text_search_form.html.erb
7
+ public/javascripts/dropdown_navigation.js
8
+ public/javascripts/labeled_text_field.js
9
+ public/javascripts/skip_fckeditor_config.js
10
+ public/stylesheets/skip_embedded.css
11
+ ]
12
+
13
+ assets.map{|asset| File.dirname(asset) }.uniq.each{|asset| m.directory(asset) }
14
+ assets.each{|asset| m.file asset, asset }
15
+
16
+ insert_helper(m) unless options[:pretend]
17
+ end
18
+ end
19
+
20
+ private
21
+ def insert_helper(manifest, text = "\n include SkipEmbedded::Helpers", helper = "app/helpers/application_helper.rb")
22
+ logger.edit_helper(helper)
23
+ case options[:command]
24
+ when :create
25
+ manifest.gsub_file(helper, /^module ApplicationHelper$/){|head| head + text }
26
+ when :destroy
27
+ manifest.gsub_file(helper, text, '')
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ <div id="flash_message">
2
+ <%= render_flash(:error) %>
3
+ <%= render_flash(:warn) %>
4
+ <%= render_flash(:notice) %>
5
+ </div>
6
+
7
+ <%- javascript_tag do %>
8
+ jQuery(document).ready(function(){
9
+ $("#flash_message div").click(function(){$(this).fadeOut("slow")});
10
+ setTimeout(function(){ $("#flash_message div.notice").trigger("click"); }, 2*1000);
11
+ setTimeout(function(){ $("#flash_message div.warn").trigger("click"); }, 5*1000);
12
+ });
13
+ <% end %>
@@ -0,0 +1,24 @@
1
+ <%
2
+ config = SkipEmbedded::InitialSettings["skip_collaboration"]["fulltext_search"]
3
+ endpoint = config["endpoint"]
4
+ query_name = config["full_text_query"]
5
+ search_label = _("Input keyword to search")
6
+
7
+ unless endpoint =~ /\Ahttp(s)?:\/\//
8
+ endpoint = SkipEmbedded::InitialSettings["skip_collaboration"]["skip_url"] + endpoint
9
+ end
10
+ %>
11
+
12
+ <div id="search">
13
+ <% form_tag(endpoint, :method => 'get', :class => 'skip_fulltext_search') do -%>
14
+ <%= text_field_tag(query_name, search_label, :class => "labeled-field", :size => 40) %>
15
+ <%= submit_tag _('Search') %>
16
+ <% end -%>
17
+
18
+ <% javascript_tag do %>
19
+ jQuery(function(){
20
+ jQuery("#search input.labeled-field").labeledTextField(<%= {:message => search_label}.to_json %>);
21
+ });
22
+ <% end %>
23
+ </div>
24
+
@@ -0,0 +1,12 @@
1
+ (function() {
2
+ jQuery.fn.dropdownNavigation = function(config){
3
+ function navigate(){
4
+ var loc = jQuery(this).val();
5
+ if("" != loc){ document.location = loc };
6
+ return false;
7
+ };
8
+
9
+ return jQuery(this).change(navigate);
10
+ }
11
+ })(jQuery);
12
+
@@ -0,0 +1,21 @@
1
+ (function() {
2
+ jQuery.fn.labeledTextField = function(config){
3
+ var target = jQuery(this);
4
+ var focusClass = config["focusClass"] || "focus";
5
+ var message = config["message"];
6
+
7
+ target.parents("form").get(0).reset();
8
+ if(target.val() != message){ target.addClass(focusClass); };
9
+
10
+ target.focus(function(){
11
+ target.addClass(focusClass);
12
+ if(target.val() == message){ target.val("") };
13
+ });
14
+ target.blur(function(){
15
+ if(target.val() == ""){
16
+ target.removeClass(focusClass).val(message);
17
+ };
18
+ });
19
+ };
20
+ })(jQuery);
21
+
@@ -0,0 +1,45 @@
1
+
2
+ FCKConfig.EditorAreaCSS = FCKConfig.BasePath + '../../../stylesheets/application.css' ;
3
+
4
+ FCKConfig.Plugins.Add( 'autogrow' ) ;
5
+ FCKConfig.Plugins.Add( 'dragresizetable' );
6
+ FCKConfig.AutoGrowMax = 1000 ;
7
+
8
+ FCKConfig.BodyId = 'fckedit' ;
9
+ FCKConfig.BodyClass = 'rich_style' ;
10
+
11
+ FCKConfig.DefaultLanguage = 'ja' ;
12
+ FCKConfig.SkinPath = FCKConfig.BasePath + 'skins/silver/';
13
+
14
+ FCKConfig.ToolbarSets["Normal"] = [
15
+ ['Cut','Copy','Paste','PasteText','PasteWord'],
16
+ ['Undo','Redo','RemoveFormat'],
17
+ ['Bold','Italic','Underline','StrikeThrough'],
18
+ ['OrderedList','UnorderedList'],
19
+ ['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
20
+ ['TextColor','BGColor'],
21
+ ['Table','Rule','Smiley'],
22
+ '/',
23
+ ['FontName','FontFormat','FontSize'],
24
+ ['Link','Unlink'],
25
+ ['Source','Preview'],
26
+ ['FitWindow','ShowBlocks','-','About'] // No comma for the last row.
27
+ ] ;
28
+
29
+ FCKConfig.ToolbarSets["Light"] = [
30
+ ['Undo','Redo'],
31
+ ['Bold','Italic','Underline','StrikeThrough','RemoveFormat'],
32
+ ['TextColor','BGColor','Smiley'],
33
+ '/',
34
+ ['FontName','FontFormat','FontSize'] // No comma for the last row.
35
+ ] ;
36
+
37
+ FCKConfig.LinkBrowser = false ;
38
+ FCKConfig.ImageBrowser = false ;
39
+ FCKConfig.FlashBrowser = false ;
40
+ FCKConfig.LinkUpload = false ;
41
+ FCKConfig.ImageUpload = false ;
42
+ FCKConfig.FlashUpload = false ;
43
+
44
+ FCKConfig.FontNames = "'MS Pゴシック';'MS P明朝';'MS ゴシック';'MS 明朝';MS UI Gothic;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana" ;
45
+
@@ -0,0 +1,79 @@
1
+ #flash_message {
2
+ position: absolute;
3
+ top: 3px;
4
+ left: 15%;
5
+ right: 15%;
6
+ width: 70%;
7
+ z-index: 1; }
8
+ #flash_message div {
9
+ width: 100%;
10
+ text-align: center;
11
+ font-size: 12px;
12
+ border-width: 2px;
13
+ border-style: solid; }
14
+ #flash_message div h3 {
15
+ width: 100%; }
16
+ #flash_message div h3 span {
17
+ position: static;
18
+ font-size: 10px;
19
+ margin-left: 20px;
20
+ right: 15px;
21
+ top: 15px; }
22
+ #flash_message div.warn {
23
+ border-color: orange;
24
+ background-color: yellow; }
25
+ #flash_message div.notice {
26
+ border-color: limegreen;
27
+ background-color: palegreen; }
28
+ #flash_message div.error {
29
+ border-color: red;
30
+ background-color: pink; }
31
+
32
+ div#header div#search {
33
+ position: absolute;
34
+ top: 25px;
35
+ right: 5px;
36
+ }
37
+
38
+ div#header div#search form {
39
+ margin:0;
40
+ padding:0;
41
+ }
42
+
43
+ div#header div#serach input {
44
+ font-family:Verdana,Arial,Sans-serif;
45
+ font-size:12px;
46
+ margin:0;
47
+ padding:2px;
48
+ }
49
+
50
+ div#header div#menu {
51
+ background-color:#D0E0F0;
52
+ border:medium none;
53
+ font-size:12px;
54
+ padding:1px 5px;
55
+ position:absolute;
56
+ right:0;
57
+ text-align:right;
58
+ top:0;
59
+ }
60
+
61
+ div#header div#menu .item {
62
+ float:left;
63
+ font-weight:bold;
64
+ padding:3px 10px 1px;
65
+ }
66
+
67
+ div#header div#menu .item a {
68
+ color:blue;
69
+ text-decoration:none;
70
+ }
71
+
72
+ .labeled-field {
73
+ border: 1px solid silver;
74
+ color: rgb(153, 153, 153);
75
+ font-size: 13px; }
76
+
77
+ .labeled-field.focus {
78
+ color: #000000; }
79
+
@@ -0,0 +1,51 @@
1
+
2
+ module SkipEmbedded
3
+ module FulltextSearchCache
4
+ class BuilderBase
5
+ include ActionController::UrlWriter
6
+ class_inheritable_accessor :entity_name
7
+
8
+ def initialize(entity)
9
+ @entity = entity
10
+ end
11
+
12
+ def filename
13
+ "#{entity_name}/#{@entity.id}.html"
14
+ end
15
+
16
+ def write_cache(mediator)
17
+ File.open(mediator.cache_path(self), "wb"){|f| f.write to_cache }
18
+ end
19
+
20
+ def to_cache
21
+ ERB.new(<<-HTML).result(binding)
22
+ <html>
23
+ <head>
24
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
25
+ <title>#{title}</title>
26
+ </head>
27
+ <body>#{body}</body>
28
+ </html>
29
+ HTML
30
+ end
31
+
32
+ def write_meta(mediator)
33
+ File.open(mediator.meta_path(self), "wb"){|f| f.write to_meta.to_yaml }
34
+ end
35
+
36
+ def to_meta; raise NotImplementedError, "ovverride me" end
37
+ def title; raise NotImplementedError, "ovverride me" end
38
+ def body; raise NotImplementedError, "ovverride me" end
39
+
40
+ def icon_url(icon_filename = entity_name + ".gif")
41
+ root_url + "images/icons/" + icon_filename
42
+ end
43
+
44
+ private
45
+ def method_missing(m, *args, &block)
46
+ return @entity if m.to_sym == entity_name.to_sym
47
+ super
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,67 @@
1
+ require 'skip_embedded/fulltext_search_cache'
2
+ require "skip_embedded/fulltext_search_cache/partial_loader"
3
+
4
+ module SkipEmbedded
5
+ module FulltextSearchCache
6
+ class Mediator
7
+
8
+ attr_reader :cache_dir, :built
9
+ def initialize(options = {})
10
+ @options = SkipEmbedded::FulltextSearchCache::DEFAULT_OPTIONS.merge(options)
11
+ @cache_dir = @options[:cache_dir]
12
+ @built = []
13
+
14
+ if since = @options[:since]
15
+ @since = Integer(since).minutes.ago
16
+ end
17
+ end
18
+
19
+ def finish
20
+ if built.empty?
21
+ @options[:logger].info{ "[FULLTEXT_SEARCH_CACHE] no model to built cache" }
22
+ else
23
+ @options[:logger].info{ "[FULLTEXT_SEARCH_CACHE] built for #{built.join(", ")}" }
24
+ end
25
+ end
26
+
27
+ def build(model, builder)
28
+ prepare_dir(model.name.underscore)
29
+
30
+ if @since
31
+ model = model.scoped(:conditions => ["#{model.quoted_table_name}.updated_at > ?", @since])
32
+ end
33
+
34
+ loader(model).each do |obj|
35
+ b = builder.new(obj)
36
+ b.write_cache(self)
37
+ b.write_meta(self)
38
+ built << "#{obj.class.name}:#{obj.id}"
39
+ end
40
+ end
41
+
42
+ def loader(model)
43
+ PartialLoader.new(model, @options[:limit])
44
+ end
45
+
46
+ def cache_path(builder)
47
+ File.expand_path(builder.filename, cache_dir)
48
+ end
49
+
50
+ def meta_path(builder)
51
+ File.expand_path(builder.filename, meta_dir)
52
+ end
53
+
54
+ def meta_dir
55
+ dir, base = File.split(cache_dir)
56
+ File.expand_path(base + "_meta", dir)
57
+ end
58
+
59
+ def prepare_dir(name)
60
+ [cache_dir, meta_dir].each do |dir|
61
+ d = File.expand_path(File.join(dir, name), cache_dir)
62
+ FileUtils.mkdir_p(d) unless File.directory?(d)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,19 @@
1
+ module SkipEmbedded
2
+ module FulltextSearchCache
3
+ class PartialLoader
4
+ def initialize(model_or_scope, limit, finder_options = {})
5
+ @model_or_scope = model_or_scope
6
+ @limit = limit
7
+ @finder_options = finder_options
8
+ end
9
+
10
+ def each
11
+ 0.step(@model_or_scope.count, @limit) do |offset|
12
+ @model_or_scope.find(:all, :limit => @limit, :offset => offset).each do |model|
13
+ yield model
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,38 @@
1
+ require "fileutils"
2
+
3
+ require "config/environment" unless defined? ActionController
4
+
5
+ require "skip_embedded/initial_settings"
6
+ require "skip_embedded/fulltext_search_cache/mediator"
7
+
8
+ module SkipEmbedded
9
+ module FulltextSearchCache
10
+ DEFAULT_OPTIONS = {
11
+ :cache_dir => File.expand_path("fts_cache/app_cache", Dir.pwd),
12
+ :logger => ActionController::Base.logger,
13
+ :limit => 1_000,
14
+ }.freeze
15
+
16
+ def self.build(model_and_builders, options = {})
17
+ if skip_url = (InitialSettings[:skip_collaboration] && InitialSettings[:skip_collaboration]["skip_url"])
18
+ set_default_url_options(skip_url)
19
+ else
20
+ $stderr.puts "set skip_collaboration -> skip_url in config/initial_settings.yml"
21
+ exit 1
22
+ end
23
+
24
+ mediator = Mediator.new(options)
25
+ model_and_builders.each{|m, b| mediator.build(m, b) }
26
+
27
+ mediator.finish
28
+ end
29
+
30
+ def self.set_default_url_options(url)
31
+ u = URI(url)
32
+ url_opt = { :host => u.host, :protocol => u.scheme }
33
+ url_opt[:port] = u.port unless (u.scheme == "http" && u.port == 80) || (u.scheme == "https" && u.port == 443)
34
+ ActionController::UrlWriter.default_url_options = url_opt
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,46 @@
1
+ module SkipEmbedded
2
+ module Helpers
3
+ module Ui
4
+ # From. http://github.com/mojombo/clippy/tree/master
5
+ def clippy(copy_text, bgcolor='#FFFFFF')
6
+ html = <<-EOF
7
+ <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
8
+ width="110"
9
+ height="14"
10
+ id="clippy" >
11
+ <param name="movie" value="#{flash_path("clippy")}"/>
12
+ <param name="allowScriptAccess" value="always" />
13
+ <param name="quality" value="high" />
14
+ <param name="scale" value="noscale" />
15
+ <param NAME="FlashVars" value="text=#{copy_text}">
16
+ <param name="bgcolor" value="#{bgcolor}">
17
+ <embed src="#{flash_path("clippy")}"
18
+ width="110"
19
+ height="14"
20
+ name="clippy"
21
+ quality="high"
22
+ allowScriptAccess="always"
23
+ type="application/x-shockwave-flash"
24
+ pluginspage="http://www.macromedia.com/go/getflashplayer"
25
+ FlashVars="text=#{copy_text}"
26
+ bgcolor="#{bgcolor}"
27
+ />
28
+ </object>
29
+ EOF
30
+ end
31
+
32
+ def render_flash(type)
33
+ if message = flash[type]
34
+ content_tag("div", :class => type.to_s) do
35
+ content_tag("h3", h(message) + content_tag("span", _("[Click to hide]")))
36
+ end
37
+ end
38
+ end
39
+
40
+ def flash_path(source, suffix="swf")
41
+ compute_public_path(source, "flash", suffix)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,13 @@
1
+ module SkipEmbedded
2
+ module Helpers
3
+ include Ui
4
+
5
+ def self.included(base)
6
+ ActionView::Helpers::AssetTagHelper.register_javascript_expansion :skip => %w[dropdown_navigation labeled_text_field]
7
+ ActionView::Helpers::AssetTagHelper.register_javascript_expansion :skip_fckeditor => %w[fckeditor/fckeditor skip_fckeditor_config]
8
+
9
+ # TODO skip/style などをどの程度共通化するかを検討、それはではskip_embeddedという別名で
10
+ ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :skip_embedded => %w[skip_embedded]
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,28 @@
1
+ require 'singleton'
2
+
3
+ module SkipEmbedded
4
+ class InitialSettings
5
+ include Singleton
6
+ def self.config=(abs_path)
7
+ @config_path = abs_path
8
+ end
9
+
10
+ def self.config
11
+ @config_path ||= File.expand_path("config/initial_settings.yml", Rails.root)
12
+ end
13
+
14
+ def self.[](key)
15
+ instance[key]
16
+ end
17
+
18
+ def initialize
19
+ env = defined?(RAILS_ENV) ? RAILS_ENV : "development"
20
+ @config = YAML.load_file(self.class.config)[env].freeze
21
+ end
22
+
23
+ def [](key)
24
+ @config[key.to_s]
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,43 @@
1
+ require 'openid'
2
+ require 'skip_embedded/initial_settings'
3
+
4
+ module SkipEmbedded
5
+ class OpFixation
6
+ cattr_accessor :servers, :sso_openid_provider_url
7
+
8
+ def self.accept?(claimed_url)
9
+ servers.empty? || new(*servers).accept?(claimed_url)
10
+ end
11
+
12
+ def self.sso_enabled?
13
+ @@config && !@@config["disabled"]
14
+ end
15
+
16
+ def self.sso_openid_logout_url
17
+ URI.join(sso_openid_provider_url + "logout").to_s if sso_openid_provider_url
18
+ end
19
+
20
+ @@config = InitialSettings['skip_collaboration']['fixed_op']
21
+ if sso_enabled?
22
+ @@servers = @@config["acceptable_op_urls"]
23
+ @@sso_openid_provider_url = @@config["fixed_openid_server_url"]
24
+ else
25
+ @@servers, @@sso_openid_provider_url = [], nil
26
+ end
27
+
28
+ def initialize(*allowed)
29
+ @available_servers = allowed
30
+ end
31
+
32
+ def accept?(claimed_url)
33
+ begin
34
+ _, services = OpenID.discover claimed_url
35
+ services.any?{|s| @available_servers.include?(s.server_url) }
36
+ rescue OpenID::DiscoveryFailure => why
37
+ ::OpenID::Util.logger.error "FixedOp discovery failed: #{why.message}"
38
+ false
39
+ end
40
+ end
41
+ end
42
+ end
43
+