rango 0.0.6 → 0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/0.0.3/Array.html +354 -0
- data/doc/0.0.3/AttributeMixin.html +697 -0
- data/doc/0.0.3/Class.html +102 -0
- data/doc/0.0.3/ColoredString.html +476 -0
- data/doc/0.0.3/Enumerable.html +256 -0
- data/doc/0.0.3/File.html +909 -0
- data/doc/0.0.3/Hash.html +1586 -0
- data/doc/0.0.3/Kernel.html +956 -0
- data/doc/0.0.3/OS.html +740 -0
- data/doc/0.0.3/Object.html +466 -0
- data/doc/0.0.3/ObjectSpace.html +184 -0
- data/doc/0.0.3/Path.html +2499 -0
- data/doc/0.0.3/Range.html +190 -0
- data/doc/0.0.3/Rango.html +379 -0
- data/doc/0.0.3/Rango/ApplicationMixin.html +396 -0
- data/doc/0.0.3/Rango/Bundling.html +23 -0
- data/doc/0.0.3/Rango/Bundling/RequireStrategy.html +283 -0
- data/doc/0.0.3/Rango/Bundling/Strategy.html +703 -0
- data/doc/0.0.3/Rango/CLI.html +23 -0
- data/doc/0.0.3/Rango/CLI/Generator.html +762 -0
- data/doc/0.0.3/Rango/CLI/Templater.html +258 -0
- data/doc/0.0.3/Rango/CallableStrategy.html +300 -0
- data/doc/0.0.3/Rango/Chainable.html +181 -0
- data/doc/0.0.3/Rango/Configurable.html +199 -0
- data/doc/0.0.3/Rango/Controller.html +962 -0
- data/doc/0.0.3/Rango/ControllerMixin.html +860 -0
- data/doc/0.0.3/Rango/ControllerStrategy.html +264 -0
- data/doc/0.0.3/Rango/DependencyStrategy.html +116 -0
- data/doc/0.0.3/Rango/Dispatcher.html +305 -0
- data/doc/0.0.3/Rango/Form.html +162 -0
- data/doc/0.0.3/Rango/GemDependencyStrategy.html +210 -0
- data/doc/0.0.3/Rango/Generator.html +93 -0
- data/doc/0.0.3/Rango/GenericViews.html +128 -0
- data/doc/0.0.3/Rango/GitDependencyStrategy.html +224 -0
- data/doc/0.0.3/Rango/GithubDependencyStrategy.html +118 -0
- data/doc/0.0.3/Rango/Handler.html +474 -0
- data/doc/0.0.3/Rango/Helpers.html +1335 -0
- data/doc/0.0.3/Rango/Hookable.html +202 -0
- data/doc/0.0.3/Rango/ImportMixin.html +755 -0
- data/doc/0.0.3/Rango/Logger.html +920 -0
- data/doc/0.0.3/Rango/Mini.html +117 -0
- data/doc/0.0.3/Rango/ModelForm.html +42 -0
- data/doc/0.0.3/Rango/Project.html +516 -0
- data/doc/0.0.3/Rango/RenderMixin.html +23 -0
- data/doc/0.0.3/Rango/Request.html +1177 -0
- data/doc/0.0.3/Rango/Route.html +751 -0
- data/doc/0.0.3/Rango/Router.html +42 -0
- data/doc/0.0.3/Rango/Router/Dispatcher.html +311 -0
- data/doc/0.0.3/Rango/RouterStrategy.html +258 -0
- data/doc/0.0.3/Rango/Session.html +23 -0
- data/doc/0.0.3/Rango/Settings.html +23 -0
- data/doc/0.0.3/Rango/Settings/Erubis.html +23 -0
- data/doc/0.0.3/Rango/Settings/Framework.html +254 -0
- data/doc/0.0.3/Rango/Settings/Haml.html +23 -0
- data/doc/0.0.3/Rango/Settings/Template.html +23 -0
- data/doc/0.0.3/Rango/SimpleTemplate.html +187 -0
- data/doc/0.0.3/Rango/StrategyMixin.html +261 -0
- data/doc/0.0.3/Rango/Tasks.html +219 -0
- data/doc/0.0.3/Rango/Template.html +95 -0
- data/doc/0.0.3/Rango/Template/Adapter.html +90 -0
- data/doc/0.0.3/Rango/Templates.html +116 -0
- data/doc/0.0.3/Rango/Templates/Adapter.html +128 -0
- data/doc/0.0.3/Rango/Templates/Template.html +636 -0
- data/doc/0.0.3/Rango/Templates/TemplateHelpers.html +328 -0
- data/doc/0.0.3/RangoThor.html +205 -0
- data/doc/0.0.3/String.html +307 -0
- data/doc/0.0.3/Time.html +193 -0
- data/doc/0.0.3/TimeDSL.html +601 -0
- data/doc/0.0.3/all-methods.html +1908 -0
- data/doc/0.0.3/all-namespaces.html +114 -0
- data/doc/0.0.3/app.js +18 -0
- data/doc/0.0.3/head/Array.html +354 -0
- data/doc/0.0.3/head/AttributeMixin.html +697 -0
- data/doc/0.0.3/head/Class.html +102 -0
- data/doc/0.0.3/head/ColoredString.html +476 -0
- data/doc/0.0.3/head/Enumerable.html +256 -0
- data/doc/0.0.3/head/File.html +909 -0
- data/doc/0.0.3/head/Hash.html +1586 -0
- data/doc/0.0.3/head/Kernel.html +956 -0
- data/doc/0.0.3/head/OS.html +740 -0
- data/doc/0.0.3/head/Object.html +466 -0
- data/doc/0.0.3/head/ObjectSpace.html +184 -0
- data/doc/0.0.3/head/Path.html +2499 -0
- data/doc/0.0.3/head/Range.html +190 -0
- data/doc/0.0.3/head/Rango.html +379 -0
- data/doc/0.0.3/head/Rango/ApplicationMixin.html +396 -0
- data/doc/0.0.3/head/Rango/Bundling.html +23 -0
- data/doc/0.0.3/head/Rango/Bundling/RequireStrategy.html +283 -0
- data/doc/0.0.3/head/Rango/Bundling/Strategy.html +703 -0
- data/doc/0.0.3/head/Rango/CLI.html +23 -0
- data/doc/0.0.3/head/Rango/CLI/Generator.html +762 -0
- data/doc/0.0.3/head/Rango/CLI/Templater.html +258 -0
- data/doc/0.0.3/head/Rango/CallableStrategy.html +300 -0
- data/doc/0.0.3/head/Rango/Chainable.html +181 -0
- data/doc/0.0.3/head/Rango/Configurable.html +199 -0
- data/doc/0.0.3/head/Rango/Controller.html +962 -0
- data/doc/0.0.3/head/Rango/ControllerMixin.html +860 -0
- data/doc/0.0.3/head/Rango/ControllerStrategy.html +264 -0
- data/doc/0.0.3/head/Rango/DependencyStrategy.html +116 -0
- data/doc/0.0.3/head/Rango/Dispatcher.html +305 -0
- data/doc/0.0.3/head/Rango/Form.html +162 -0
- data/doc/0.0.3/head/Rango/GemDependencyStrategy.html +210 -0
- data/doc/0.0.3/head/Rango/Generator.html +93 -0
- data/doc/0.0.3/head/Rango/GenericViews.html +128 -0
- data/doc/0.0.3/head/Rango/GitDependencyStrategy.html +224 -0
- data/doc/0.0.3/head/Rango/GithubDependencyStrategy.html +118 -0
- data/doc/0.0.3/head/Rango/Handler.html +474 -0
- data/doc/0.0.3/head/Rango/Helpers.html +1335 -0
- data/doc/0.0.3/head/Rango/Hookable.html +202 -0
- data/doc/0.0.3/head/Rango/ImportMixin.html +755 -0
- data/doc/0.0.3/head/Rango/Logger.html +920 -0
- data/doc/0.0.3/head/Rango/Mini.html +117 -0
- data/doc/0.0.3/head/Rango/ModelForm.html +42 -0
- data/doc/0.0.3/head/Rango/Project.html +516 -0
- data/doc/0.0.3/head/Rango/RenderMixin.html +23 -0
- data/doc/0.0.3/head/Rango/Request.html +1177 -0
- data/doc/0.0.3/head/Rango/Route.html +751 -0
- data/doc/0.0.3/head/Rango/Router.html +42 -0
- data/doc/0.0.3/head/Rango/Router/Dispatcher.html +311 -0
- data/doc/0.0.3/head/Rango/RouterStrategy.html +258 -0
- data/doc/0.0.3/head/Rango/Session.html +23 -0
- data/doc/0.0.3/head/Rango/Settings.html +23 -0
- data/doc/0.0.3/head/Rango/Settings/Erubis.html +23 -0
- data/doc/0.0.3/head/Rango/Settings/Framework.html +254 -0
- data/doc/0.0.3/head/Rango/Settings/Haml.html +23 -0
- data/doc/0.0.3/head/Rango/Settings/Template.html +23 -0
- data/doc/0.0.3/head/Rango/SimpleTemplate.html +187 -0
- data/doc/0.0.3/head/Rango/StrategyMixin.html +261 -0
- data/doc/0.0.3/head/Rango/Tasks.html +219 -0
- data/doc/0.0.3/head/Rango/Template.html +95 -0
- data/doc/0.0.3/head/Rango/Template/Adapter.html +90 -0
- data/doc/0.0.3/head/Rango/Templates.html +116 -0
- data/doc/0.0.3/head/Rango/Templates/Adapter.html +128 -0
- data/doc/0.0.3/head/Rango/Templates/Template.html +636 -0
- data/doc/0.0.3/head/Rango/Templates/TemplateHelpers.html +328 -0
- data/doc/0.0.3/head/RangoThor.html +205 -0
- data/doc/0.0.3/head/String.html +307 -0
- data/doc/0.0.3/head/Time.html +193 -0
- data/doc/0.0.3/head/TimeDSL.html +601 -0
- data/doc/0.0.3/head/all-methods.html +1908 -0
- data/doc/0.0.3/head/all-namespaces.html +114 -0
- data/doc/0.0.3/head/app.js +18 -0
- data/doc/0.0.3/head/index.html +18 -0
- data/doc/0.0.3/head/jquery.js +11 -0
- data/doc/0.0.3/head/readme.html +36 -0
- data/doc/0.0.3/head/style.css +68 -0
- data/doc/0.0.3/head/syntax_highlight.css +21 -0
- data/doc/0.0.3/index.html +18 -0
- data/doc/0.0.3/jquery.js +11 -0
- data/doc/0.0.3/readme.html +36 -0
- data/doc/0.0.3/style.css +68 -0
- data/doc/0.0.3/syntax_highlight.css +21 -0
- data/doc/0.0.4/Array.html +354 -0
- data/doc/0.0.4/AttributeMixin.html +697 -0
- data/doc/0.0.4/Class.html +102 -0
- data/doc/0.0.4/ColoredString.html +476 -0
- data/doc/0.0.4/Enumerable.html +256 -0
- data/doc/0.0.4/File.html +909 -0
- data/doc/0.0.4/Hash.html +1586 -0
- data/doc/0.0.4/Kernel.html +956 -0
- data/doc/0.0.4/OS.html +740 -0
- data/doc/0.0.4/Object.html +466 -0
- data/doc/0.0.4/ObjectSpace.html +184 -0
- data/doc/0.0.4/Path.html +2499 -0
- data/doc/0.0.4/Range.html +190 -0
- data/doc/0.0.4/Rango.html +379 -0
- data/doc/0.0.4/Rango/ApplicationMixin.html +396 -0
- data/doc/0.0.4/Rango/Bundling.html +23 -0
- data/doc/0.0.4/Rango/Bundling/RequireStrategy.html +283 -0
- data/doc/0.0.4/Rango/Bundling/Strategy.html +703 -0
- data/doc/0.0.4/Rango/CLI.html +23 -0
- data/doc/0.0.4/Rango/CLI/Generator.html +762 -0
- data/doc/0.0.4/Rango/CLI/Templater.html +258 -0
- data/doc/0.0.4/Rango/CallableStrategy.html +300 -0
- data/doc/0.0.4/Rango/Chainable.html +181 -0
- data/doc/0.0.4/Rango/Configurable.html +199 -0
- data/doc/0.0.4/Rango/Controller.html +962 -0
- data/doc/0.0.4/Rango/ControllerMixin.html +860 -0
- data/doc/0.0.4/Rango/ControllerStrategy.html +264 -0
- data/doc/0.0.4/Rango/DependencyStrategy.html +116 -0
- data/doc/0.0.4/Rango/Dispatcher.html +305 -0
- data/doc/0.0.4/Rango/Form.html +162 -0
- data/doc/0.0.4/Rango/GemDependencyStrategy.html +210 -0
- data/doc/0.0.4/Rango/Generator.html +93 -0
- data/doc/0.0.4/Rango/GenericViews.html +128 -0
- data/doc/0.0.4/Rango/GitDependencyStrategy.html +224 -0
- data/doc/0.0.4/Rango/GithubDependencyStrategy.html +118 -0
- data/doc/0.0.4/Rango/Handler.html +474 -0
- data/doc/0.0.4/Rango/Helpers.html +1335 -0
- data/doc/0.0.4/Rango/Hookable.html +202 -0
- data/doc/0.0.4/Rango/ImportMixin.html +755 -0
- data/doc/0.0.4/Rango/Logger.html +920 -0
- data/doc/0.0.4/Rango/Mini.html +117 -0
- data/doc/0.0.4/Rango/ModelForm.html +42 -0
- data/doc/0.0.4/Rango/Project.html +516 -0
- data/doc/0.0.4/Rango/RenderMixin.html +23 -0
- data/doc/0.0.4/Rango/Request.html +1177 -0
- data/doc/0.0.4/Rango/Route.html +751 -0
- data/doc/0.0.4/Rango/Router.html +42 -0
- data/doc/0.0.4/Rango/Router/Dispatcher.html +311 -0
- data/doc/0.0.4/Rango/RouterStrategy.html +258 -0
- data/doc/0.0.4/Rango/Session.html +23 -0
- data/doc/0.0.4/Rango/Settings.html +23 -0
- data/doc/0.0.4/Rango/Settings/Erubis.html +23 -0
- data/doc/0.0.4/Rango/Settings/Framework.html +254 -0
- data/doc/0.0.4/Rango/Settings/Haml.html +23 -0
- data/doc/0.0.4/Rango/Settings/Template.html +23 -0
- data/doc/0.0.4/Rango/SimpleTemplate.html +187 -0
- data/doc/0.0.4/Rango/StrategyMixin.html +261 -0
- data/doc/0.0.4/Rango/Tasks.html +219 -0
- data/doc/0.0.4/Rango/Template.html +95 -0
- data/doc/0.0.4/Rango/Template/Adapter.html +90 -0
- data/doc/0.0.4/Rango/Templates.html +116 -0
- data/doc/0.0.4/Rango/Templates/Adapter.html +128 -0
- data/doc/0.0.4/Rango/Templates/Template.html +636 -0
- data/doc/0.0.4/Rango/Templates/TemplateHelpers.html +328 -0
- data/doc/0.0.4/RangoThor.html +205 -0
- data/doc/0.0.4/String.html +307 -0
- data/doc/0.0.4/Time.html +193 -0
- data/doc/0.0.4/TimeDSL.html +601 -0
- data/doc/0.0.4/all-methods.html +1908 -0
- data/doc/0.0.4/all-namespaces.html +114 -0
- data/doc/0.0.4/app.js +18 -0
- data/doc/0.0.4/head/Array.html +354 -0
- data/doc/0.0.4/head/AttributeMixin.html +697 -0
- data/doc/0.0.4/head/Class.html +102 -0
- data/doc/0.0.4/head/ColoredString.html +476 -0
- data/doc/0.0.4/head/Enumerable.html +256 -0
- data/doc/0.0.4/head/File.html +909 -0
- data/doc/0.0.4/head/Hash.html +1586 -0
- data/doc/0.0.4/head/Kernel.html +956 -0
- data/doc/0.0.4/head/OS.html +740 -0
- data/doc/0.0.4/head/Object.html +466 -0
- data/doc/0.0.4/head/ObjectSpace.html +184 -0
- data/doc/0.0.4/head/Path.html +2499 -0
- data/doc/0.0.4/head/Range.html +190 -0
- data/doc/0.0.4/head/Rango.html +379 -0
- data/doc/0.0.4/head/Rango/ApplicationMixin.html +396 -0
- data/doc/0.0.4/head/Rango/Bundling.html +23 -0
- data/doc/0.0.4/head/Rango/Bundling/RequireStrategy.html +283 -0
- data/doc/0.0.4/head/Rango/Bundling/Strategy.html +703 -0
- data/doc/0.0.4/head/Rango/CLI.html +23 -0
- data/doc/0.0.4/head/Rango/CLI/Generator.html +762 -0
- data/doc/0.0.4/head/Rango/CLI/Templater.html +258 -0
- data/doc/0.0.4/head/Rango/CallableStrategy.html +300 -0
- data/doc/0.0.4/head/Rango/Chainable.html +181 -0
- data/doc/0.0.4/head/Rango/Configurable.html +199 -0
- data/doc/0.0.4/head/Rango/Controller.html +962 -0
- data/doc/0.0.4/head/Rango/ControllerMixin.html +860 -0
- data/doc/0.0.4/head/Rango/ControllerStrategy.html +264 -0
- data/doc/0.0.4/head/Rango/DependencyStrategy.html +116 -0
- data/doc/0.0.4/head/Rango/Dispatcher.html +305 -0
- data/doc/0.0.4/head/Rango/Form.html +162 -0
- data/doc/0.0.4/head/Rango/GemDependencyStrategy.html +210 -0
- data/doc/0.0.4/head/Rango/Generator.html +93 -0
- data/doc/0.0.4/head/Rango/GenericViews.html +128 -0
- data/doc/0.0.4/head/Rango/GitDependencyStrategy.html +224 -0
- data/doc/0.0.4/head/Rango/GithubDependencyStrategy.html +118 -0
- data/doc/0.0.4/head/Rango/Handler.html +474 -0
- data/doc/0.0.4/head/Rango/Helpers.html +1335 -0
- data/doc/0.0.4/head/Rango/Hookable.html +202 -0
- data/doc/0.0.4/head/Rango/ImportMixin.html +755 -0
- data/doc/0.0.4/head/Rango/Logger.html +920 -0
- data/doc/0.0.4/head/Rango/Mini.html +117 -0
- data/doc/0.0.4/head/Rango/ModelForm.html +42 -0
- data/doc/0.0.4/head/Rango/Project.html +516 -0
- data/doc/0.0.4/head/Rango/RenderMixin.html +23 -0
- data/doc/0.0.4/head/Rango/Request.html +1177 -0
- data/doc/0.0.4/head/Rango/Route.html +751 -0
- data/doc/0.0.4/head/Rango/Router.html +42 -0
- data/doc/0.0.4/head/Rango/Router/Dispatcher.html +311 -0
- data/doc/0.0.4/head/Rango/RouterStrategy.html +258 -0
- data/doc/0.0.4/head/Rango/Session.html +23 -0
- data/doc/0.0.4/head/Rango/Settings.html +23 -0
- data/doc/0.0.4/head/Rango/Settings/Erubis.html +23 -0
- data/doc/0.0.4/head/Rango/Settings/Framework.html +254 -0
- data/doc/0.0.4/head/Rango/Settings/Haml.html +23 -0
- data/doc/0.0.4/head/Rango/Settings/Template.html +23 -0
- data/doc/0.0.4/head/Rango/SimpleTemplate.html +187 -0
- data/doc/0.0.4/head/Rango/StrategyMixin.html +261 -0
- data/doc/0.0.4/head/Rango/Tasks.html +219 -0
- data/doc/0.0.4/head/Rango/Template.html +95 -0
- data/doc/0.0.4/head/Rango/Template/Adapter.html +90 -0
- data/doc/0.0.4/head/Rango/Templates.html +116 -0
- data/doc/0.0.4/head/Rango/Templates/Adapter.html +128 -0
- data/doc/0.0.4/head/Rango/Templates/Template.html +636 -0
- data/doc/0.0.4/head/Rango/Templates/TemplateHelpers.html +328 -0
- data/doc/0.0.4/head/RangoThor.html +205 -0
- data/doc/0.0.4/head/String.html +307 -0
- data/doc/0.0.4/head/Time.html +193 -0
- data/doc/0.0.4/head/TimeDSL.html +601 -0
- data/doc/0.0.4/head/all-methods.html +1908 -0
- data/doc/0.0.4/head/all-namespaces.html +114 -0
- data/doc/0.0.4/head/app.js +18 -0
- data/doc/0.0.4/head/index.html +18 -0
- data/doc/0.0.4/head/jquery.js +11 -0
- data/doc/0.0.4/head/readme.html +36 -0
- data/doc/0.0.4/head/style.css +68 -0
- data/doc/0.0.4/head/syntax_highlight.css +21 -0
- data/doc/0.0.4/index.html +18 -0
- data/doc/0.0.4/jquery.js +11 -0
- data/doc/0.0.4/readme.html +36 -0
- data/doc/0.0.4/style.css +68 -0
- data/doc/0.0.4/syntax_highlight.css +21 -0
- data/doc/0.0.5/Array.html +354 -0
- data/doc/0.0.5/AttributeMixin.html +697 -0
- data/doc/0.0.5/Class.html +102 -0
- data/doc/0.0.5/ColoredString.html +476 -0
- data/doc/0.0.5/Enumerable.html +256 -0
- data/doc/0.0.5/File.html +909 -0
- data/doc/0.0.5/Hash.html +1586 -0
- data/doc/0.0.5/Kernel.html +956 -0
- data/doc/0.0.5/OS.html +740 -0
- data/doc/0.0.5/Object.html +466 -0
- data/doc/0.0.5/ObjectSpace.html +184 -0
- data/doc/0.0.5/Path.html +2499 -0
- data/doc/0.0.5/Range.html +190 -0
- data/doc/0.0.5/Rango.html +379 -0
- data/doc/0.0.5/Rango/ApplicationMixin.html +396 -0
- data/doc/0.0.5/Rango/Bundling.html +23 -0
- data/doc/0.0.5/Rango/Bundling/RequireStrategy.html +283 -0
- data/doc/0.0.5/Rango/Bundling/Strategy.html +703 -0
- data/doc/0.0.5/Rango/CLI.html +23 -0
- data/doc/0.0.5/Rango/CLI/Generator.html +762 -0
- data/doc/0.0.5/Rango/CLI/Templater.html +258 -0
- data/doc/0.0.5/Rango/CallableStrategy.html +300 -0
- data/doc/0.0.5/Rango/Chainable.html +181 -0
- data/doc/0.0.5/Rango/Configurable.html +199 -0
- data/doc/0.0.5/Rango/Controller.html +962 -0
- data/doc/0.0.5/Rango/ControllerMixin.html +860 -0
- data/doc/0.0.5/Rango/ControllerStrategy.html +264 -0
- data/doc/0.0.5/Rango/DependencyStrategy.html +116 -0
- data/doc/0.0.5/Rango/Dispatcher.html +305 -0
- data/doc/0.0.5/Rango/Form.html +162 -0
- data/doc/0.0.5/Rango/GemDependencyStrategy.html +210 -0
- data/doc/0.0.5/Rango/Generator.html +93 -0
- data/doc/0.0.5/Rango/GenericViews.html +128 -0
- data/doc/0.0.5/Rango/GitDependencyStrategy.html +224 -0
- data/doc/0.0.5/Rango/GithubDependencyStrategy.html +118 -0
- data/doc/0.0.5/Rango/Handler.html +474 -0
- data/doc/0.0.5/Rango/Helpers.html +1335 -0
- data/doc/0.0.5/Rango/Hookable.html +202 -0
- data/doc/0.0.5/Rango/ImportMixin.html +755 -0
- data/doc/0.0.5/Rango/Logger.html +920 -0
- data/doc/0.0.5/Rango/Mini.html +117 -0
- data/doc/0.0.5/Rango/ModelForm.html +42 -0
- data/doc/0.0.5/Rango/Project.html +516 -0
- data/doc/0.0.5/Rango/RenderMixin.html +23 -0
- data/doc/0.0.5/Rango/Request.html +1177 -0
- data/doc/0.0.5/Rango/Route.html +751 -0
- data/doc/0.0.5/Rango/Router.html +42 -0
- data/doc/0.0.5/Rango/Router/Dispatcher.html +311 -0
- data/doc/0.0.5/Rango/RouterStrategy.html +258 -0
- data/doc/0.0.5/Rango/Session.html +23 -0
- data/doc/0.0.5/Rango/Settings.html +23 -0
- data/doc/0.0.5/Rango/Settings/Erubis.html +23 -0
- data/doc/0.0.5/Rango/Settings/Framework.html +254 -0
- data/doc/0.0.5/Rango/Settings/Haml.html +23 -0
- data/doc/0.0.5/Rango/Settings/Template.html +23 -0
- data/doc/0.0.5/Rango/SimpleTemplate.html +187 -0
- data/doc/0.0.5/Rango/StrategyMixin.html +261 -0
- data/doc/0.0.5/Rango/Tasks.html +219 -0
- data/doc/0.0.5/Rango/Template.html +95 -0
- data/doc/0.0.5/Rango/Template/Adapter.html +90 -0
- data/doc/0.0.5/Rango/Templates.html +116 -0
- data/doc/0.0.5/Rango/Templates/Adapter.html +128 -0
- data/doc/0.0.5/Rango/Templates/Template.html +636 -0
- data/doc/0.0.5/Rango/Templates/TemplateHelpers.html +328 -0
- data/doc/0.0.5/RangoThor.html +205 -0
- data/doc/0.0.5/String.html +307 -0
- data/doc/0.0.5/Time.html +193 -0
- data/doc/0.0.5/TimeDSL.html +601 -0
- data/doc/0.0.5/all-methods.html +2092 -0
- data/doc/0.0.5/all-namespaces.html +126 -0
- data/doc/0.0.5/app.js +18 -0
- data/doc/0.0.5/index.html +18 -0
- data/doc/0.0.5/jquery.js +11 -0
- data/doc/0.0.5/readme.html +36 -0
- data/doc/0.0.5/style.css +68 -0
- data/doc/0.0.5/syntax_highlight.css +21 -0
- data/doc/head/Array.html +354 -0
- data/doc/head/AttributeMixin.html +697 -0
- data/doc/head/Class.html +102 -0
- data/doc/head/ColoredString.html +476 -0
- data/doc/head/Enumerable.html +256 -0
- data/doc/head/File.html +909 -0
- data/doc/head/Hash.html +1586 -0
- data/doc/head/Kernel.html +956 -0
- data/doc/head/OS.html +740 -0
- data/doc/head/Object.html +466 -0
- data/doc/head/ObjectSpace.html +184 -0
- data/doc/head/Path.html +2499 -0
- data/doc/head/Range.html +190 -0
- data/doc/head/Rango.html +379 -0
- data/doc/head/Rango/ApplicationMixin.html +396 -0
- data/doc/head/Rango/Bundling.html +23 -0
- data/doc/head/Rango/Bundling/RequireStrategy.html +283 -0
- data/doc/head/Rango/Bundling/Strategy.html +703 -0
- data/doc/head/Rango/CLI.html +23 -0
- data/doc/head/Rango/CLI/Generator.html +762 -0
- data/doc/head/Rango/CLI/Templater.html +258 -0
- data/doc/head/Rango/CallableStrategy.html +300 -0
- data/doc/head/Rango/Chainable.html +181 -0
- data/doc/head/Rango/Configurable.html +199 -0
- data/doc/head/Rango/Controller.html +962 -0
- data/doc/head/Rango/ControllerMixin.html +860 -0
- data/doc/head/Rango/ControllerStrategy.html +264 -0
- data/doc/head/Rango/DependencyStrategy.html +116 -0
- data/doc/head/Rango/Dispatcher.html +305 -0
- data/doc/head/Rango/Form.html +162 -0
- data/doc/head/Rango/GemDependencyStrategy.html +210 -0
- data/doc/head/Rango/Generator.html +93 -0
- data/doc/head/Rango/GenericViews.html +128 -0
- data/doc/head/Rango/GitDependencyStrategy.html +224 -0
- data/doc/head/Rango/GithubDependencyStrategy.html +118 -0
- data/doc/head/Rango/Handler.html +474 -0
- data/doc/head/Rango/Helpers.html +1335 -0
- data/doc/head/Rango/Hookable.html +202 -0
- data/doc/head/Rango/ImportMixin.html +755 -0
- data/doc/head/Rango/Logger.html +920 -0
- data/doc/head/Rango/Mini.html +117 -0
- data/doc/head/Rango/ModelForm.html +42 -0
- data/doc/head/Rango/Project.html +516 -0
- data/doc/head/Rango/RenderMixin.html +23 -0
- data/doc/head/Rango/Request.html +1177 -0
- data/doc/head/Rango/Route.html +751 -0
- data/doc/head/Rango/Router.html +42 -0
- data/doc/head/Rango/Router/Dispatcher.html +311 -0
- data/doc/head/Rango/RouterStrategy.html +258 -0
- data/doc/head/Rango/Session.html +23 -0
- data/doc/head/Rango/Settings.html +23 -0
- data/doc/head/Rango/Settings/Erubis.html +23 -0
- data/doc/head/Rango/Settings/Framework.html +254 -0
- data/doc/head/Rango/Settings/Haml.html +23 -0
- data/doc/head/Rango/Settings/Template.html +23 -0
- data/doc/head/Rango/SimpleTemplate.html +187 -0
- data/doc/head/Rango/StrategyMixin.html +261 -0
- data/doc/head/Rango/Tasks.html +219 -0
- data/doc/head/Rango/Template.html +95 -0
- data/doc/head/Rango/Template/Adapter.html +90 -0
- data/doc/head/Rango/Templates.html +116 -0
- data/doc/head/Rango/Templates/Adapter.html +128 -0
- data/doc/head/Rango/Templates/Template.html +636 -0
- data/doc/head/Rango/Templates/TemplateHelpers.html +328 -0
- data/doc/head/RangoThor.html +205 -0
- data/doc/head/String.html +307 -0
- data/doc/head/Time.html +193 -0
- data/doc/head/TimeDSL.html +601 -0
- data/doc/head/all-methods.html +2092 -0
- data/doc/head/all-namespaces.html +126 -0
- data/doc/head/app.js +18 -0
- data/doc/head/index.html +18 -0
- data/doc/head/jquery.js +11 -0
- data/doc/head/readme.html +36 -0
- data/doc/head/style.css +68 -0
- data/doc/head/syntax_highlight.css +21 -0
- data/doc/versions/0.0.1/Rango.html +1025 -0
- data/doc/versions/0.0.1/Rango/CallableStrategy.html +166 -0
- data/doc/versions/0.0.1/Rango/ControllerStrategy.html +180 -0
- data/doc/versions/0.0.1/Rango/Route.html +340 -0
- data/doc/versions/0.0.1/Rango/Router.html +502 -0
- data/doc/versions/0.0.1/Rango/RouterStrategy.html +94 -0
- data/doc/versions/0.0.1/Rango/Template.html +28 -0
- data/doc/versions/0.0.1/Rango/Template/Adapter.html +90 -0
- data/doc/versions/0.0.1/all-methods.html +228 -0
- data/doc/versions/0.0.1/all-namespaces.html +36 -0
- data/doc/versions/0.0.1/app.js +18 -0
- data/doc/versions/0.0.1/index.html +18 -0
- data/doc/versions/0.0.1/jquery.js +11 -0
- data/doc/versions/0.0.1/readme.html +137 -0
- data/doc/versions/0.0.1/style.css +68 -0
- data/doc/versions/0.0.1/syntax_highlight.css +21 -0
- data/lib/rango/contrib/pagination.rb +2 -1
- data/lib/rango/contrib/pagination/_pagination.html.haml +4 -4
- data/lib/rango/contrib/pagination/helpers.rb +0 -10
- data/lib/rango/gv.rb +0 -3
- data/lib/rango/helpers/merb-helpers/form/builder.rb +1 -0
- data/lib/rango/mixins/render.rb +0 -3
- data/lib/rango/orm/tasks/{datamapper.rake → datamapper.thor} +16 -9
- data/lib/rango/orm/tasks/{sequel.rake → sequel.thor} +0 -0
- data/lib/rango/rango.rb +4 -17
- data/lib/rango/router.rb +0 -9
- data/lib/rango/router/adapters/usher.rb +1 -1
- data/lib/rango/settings/erubis.rb +0 -2
- data/lib/rango/settings/haml.rb +0 -6
- data/lib/rango/settings/template.rb +1 -3
- data/lib/rango/templates/adapter.rb +1 -1
- data/lib/rango/templates/erubis.rb +2 -2
- data/lib/rango/templates/template.rb +1 -3
- data/lib/rango/templates/templates.txt +1 -1
- data/lib/rango/{utils.rb → testing.rb} +1 -1
- data/rango-0.0.6.pre.gem +0 -0
- data/rango.gemspec +1 -1
- data/rango.pre.gemspec +48 -0
- data/stubs/app/content/init.rb.rbt +0 -3
- data/stubs/app/content/models.rb.rbt +1 -9
- data/stubs/app/content/views.rb.rbt +4 -13
- data/stubs/app/setup.rb +3 -4
- data/stubs/project/content/{Gemfile.rbt → Gemfile} +4 -55
- data/stubs/project/content/Rakefile +9 -0
- data/stubs/project/content/config.ru.rbt +5 -33
- data/stubs/project/content/init.rb.rbt +3 -29
- data/stubs/project/content/spec/spec_helper.rb +6 -17
- data/stubs/project/content/templates/base.html.haml.rbt +22 -9
- data/stubs/project/postprocess.rb +1 -7
- data/stubs/project/setup.rb +1 -4
- data/vendor/cli/Rakefile +1 -19
- data/vendor/media-path/Rakefile +1 -19
- data/vendor/rack/Rakefile +2 -1
- data/vendor/rack/lib/rack.rb +1 -0
- data/vendor/rack/lib/rack/auth/openid.rb +487 -0
- data/vendor/rack/test/spec_rack_auth_openid.rb +84 -0
- data/vendor/rubyexts/Rakefile +1 -19
- data/vendor/rubyexts/lib/rubyexts/kernel.rb +1 -1
- data/vendor/simple-templater/lib/simple-templater/helpers.rb +1 -1
- metadata +486 -16
- data/lib/rango/router/adapters/rack_mount.rb +0 -17
- data/lib/rango/tasks/spec.rake +0 -7
- data/stubs/project/content/Rakefile.rbt +0 -12
- data/stubs/project/content/spec/%name%/init_spec.rb.rbt +0 -7
- data/stubs/project/content/spec/%name%/models_spec.rb.rbt +0 -10
- data/stubs/project/content/spec/%name%/views_spec.rb.rbt +0 -22
- data/stubs/project/content/spec/spec.opts +0 -5
- data/stubs/project/content/templates/index.html.haml +0 -24
@@ -1,26 +1,15 @@
|
|
1
|
-
|
1
|
+
require_relative "../init"
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require "spec"
|
4
|
+
require "webrat"
|
5
|
+
require "rack/test"
|
6
|
+
require "rango/testing"
|
5
7
|
|
6
|
-
|
7
|
-
RANGO_ENV = "test"
|
8
|
-
require_relative "../init.rb"
|
8
|
+
Rango::Testing.load_rackup
|
9
9
|
|
10
|
-
# load config.ru
|
11
|
-
Rango::Utils.load_rackup
|
12
|
-
|
13
|
-
# webrat
|
14
|
-
Webrat.configure do |config|
|
15
|
-
config.mode = :rack
|
16
|
-
end
|
17
|
-
|
18
|
-
# rspec
|
19
10
|
Spec::Runner.configure do |config|
|
20
11
|
config.include Rack::Test::Methods
|
21
|
-
config.include Webrat::Matchers
|
22
12
|
|
23
|
-
# for rack-test
|
24
13
|
def app
|
25
14
|
Project.router
|
26
15
|
end
|
@@ -1,16 +1,29 @@
|
|
1
1
|
!!! 1.0 Strict
|
2
2
|
%html{html_attrs("en")}
|
3
3
|
%head
|
4
|
-
%title= block(
|
4
|
+
%title= block("title")
|
5
5
|
%meta{"http-equiv" => "content-type", content: "text/html; charset=utf-8"}
|
6
6
|
%meta{"http-equiv" => "content-language", content: "en-us"}
|
7
|
-
%meta{name: "description", content: block(
|
8
|
-
%meta{name: "keywords", content: block(
|
9
|
-
%meta{name: "author", content: "
|
10
|
-
=
|
11
|
-
=
|
12
|
-
=
|
7
|
+
%meta{name: "description", content: block("description", "")}
|
8
|
+
%meta{name: "keywords", content: block("keywords", "")}
|
9
|
+
%meta{name: "author", content: "AUTHOR"}
|
10
|
+
/ = pupu :blueprint, plugins: ["fancy-type"]
|
11
|
+
/ = pupu :flash
|
12
|
+
/ = pupu :autocompleter, type: "request"
|
13
|
+
/ = pupu :mootools#, more: true
|
14
|
+
= javascripts *block("javascripts", Array.new)
|
15
|
+
= stylesheets *block("stylesheets", Array.new)
|
16
|
+
= block "head"
|
13
17
|
%body
|
14
18
|
.container
|
15
|
-
%h1
|
16
|
-
|
19
|
+
%h1 Title
|
20
|
+
%h2.alt subtitle
|
21
|
+
%hr
|
22
|
+
%div.span-16
|
23
|
+
%div.span-14.last= block "content"
|
24
|
+
%h3 Menu
|
25
|
+
%ul
|
26
|
+
%li= link_to "Why Rango?", "/why-rango"
|
27
|
+
%div.span-8
|
28
|
+
%hr
|
29
|
+
== © #{copyright(2009)} AUTHOR, created by <a href="http://101ideas.cz">101Ideas.cz</a>, graphics by <a href="http://josefrichter.com">JosefRichter.com</a>.
|
@@ -8,15 +8,9 @@ require "simple-templater/hooks/postprocess/git_repository"
|
|
8
8
|
|
9
9
|
if RubyExts::Platform.unix?
|
10
10
|
sh "chmod +x init.rb"
|
11
|
-
|
11
|
+
sh "chmod +x config.ru"
|
12
12
|
end
|
13
13
|
|
14
14
|
hook do |generator, context|
|
15
15
|
generator.after(Hooks::GitRepository)
|
16
|
-
# TODO: this is probably not the best way how to do it
|
17
|
-
args = Array.new
|
18
|
-
args.push("--orm=#{context[:orm]}") if context[:orm]
|
19
|
-
args.push("--models=#{context[:models].join(",")}") unless context[:models].empty?
|
20
|
-
args.push("--controllers=#{context[:controllers].join(",")}") unless context[:controllers].empty?
|
21
|
-
sh "rango create app #{context[:name]} #{args.join(" ")}"
|
22
16
|
end
|
data/stubs/project/setup.rb
CHANGED
@@ -4,12 +4,9 @@
|
|
4
4
|
# You can update context hash and register hooks. Don't forget to use merge! instead of merge, because you are
|
5
5
|
# manipulating with one object, rather than returning new one.
|
6
6
|
|
7
|
-
# rango create app blog --models=post,tag --controllers=posts,tags
|
7
|
+
# rango create app blog --models=post,tag --controllers=posts,tags
|
8
8
|
hook do |generator, context|
|
9
9
|
models = context[:models] || Array.new
|
10
10
|
controllers = context[:controllers] || Array.new
|
11
11
|
context.merge!(models: models, controllers: controllers)
|
12
|
-
context[:orm] = "datamapper" unless context[:orm]
|
13
|
-
context[:router] = "usher" unless context[:router]
|
14
|
-
context[:template_engine] = "haml" unless context[:template_engine]
|
15
12
|
end
|
data/vendor/cli/Rakefile
CHANGED
@@ -32,21 +32,6 @@ task :gem do
|
|
32
32
|
sh "gem build cli.gemspec"
|
33
33
|
end
|
34
34
|
|
35
|
-
namespace :gem do
|
36
|
-
task :prerelease do
|
37
|
-
require_relative "lib/cli"
|
38
|
-
gemspec = Dir["*.gemspec"].first
|
39
|
-
content = File.read(gemspec)
|
40
|
-
prename = "#{gemspec.split(".").first}.pre.gemspec"
|
41
|
-
version = CLI::VERSION.sub(/^(\d+)\.(\d+)\.\d+$/) { "#$1.#{$1.to_i + 1}" }
|
42
|
-
File.open(prename, "w") do |file|
|
43
|
-
file.puts(content.gsub(/(\w+::VERSION)/, "'#{version}.pre'"))
|
44
|
-
end
|
45
|
-
sh "gem build #{prename}"
|
46
|
-
rm prename
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
35
|
desc "Release new version of cli"
|
51
36
|
task release: ["release:tag", "release:gemcutter"]
|
52
37
|
|
@@ -61,13 +46,10 @@ namespace :release do
|
|
61
46
|
end
|
62
47
|
|
63
48
|
desc "Push gem to Gemcutter"
|
64
|
-
task :gemcutter do
|
49
|
+
task :gemcutter => :gem do
|
65
50
|
puts "Pushing to Gemcutter ..."
|
66
51
|
sh "gem push #{Dir["*.gem"].last}"
|
67
52
|
end
|
68
|
-
|
69
|
-
desc "Create and push prerelease gem"
|
70
|
-
task :pre => ["gem:prerelease", :gemcutter]
|
71
53
|
end
|
72
54
|
|
73
55
|
desc "Run specs"
|
data/vendor/media-path/Rakefile
CHANGED
@@ -32,21 +32,6 @@ task :gem do
|
|
32
32
|
sh "gem build media-path.gemspec"
|
33
33
|
end
|
34
34
|
|
35
|
-
namespace :gem do
|
36
|
-
task :prerelease do
|
37
|
-
require_relative "lib/media-path"
|
38
|
-
gemspec = Dir["*.gemspec"].first
|
39
|
-
content = File.read(gemspec)
|
40
|
-
prename = "#{gemspec.split(".").first}.pre.gemspec"
|
41
|
-
version = MediaPath::VERSION.sub(/^(\d+)\.(\d+)\.\d+$/) { "#$1.#{$1.to_i + 1}" }
|
42
|
-
File.open(prename, "w") do |file|
|
43
|
-
file.puts(content.gsub(/(\w+::VERSION)/, "'#{version}.pre'"))
|
44
|
-
end
|
45
|
-
sh "gem build #{prename}"
|
46
|
-
rm prename
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
35
|
desc "Release new version of media-path"
|
51
36
|
task release: ["release:tag", "release:gemcutter"]
|
52
37
|
|
@@ -61,13 +46,10 @@ namespace :release do
|
|
61
46
|
end
|
62
47
|
|
63
48
|
desc "Push gem to Gemcutter"
|
64
|
-
task :gemcutter do
|
49
|
+
task :gemcutter => :gem do
|
65
50
|
puts "Pushing to Gemcutter ..."
|
66
51
|
sh "gem push #{Dir["*.gem"].last}"
|
67
52
|
end
|
68
|
-
|
69
|
-
desc "Create and push prerelease gem"
|
70
|
-
task :pre => ["gem:prerelease", :gemcutter]
|
71
53
|
end
|
72
54
|
|
73
55
|
desc "Run specs"
|
data/vendor/rack/Rakefile
CHANGED
@@ -86,7 +86,7 @@ end
|
|
86
86
|
|
87
87
|
desc "Run all the fast tests"
|
88
88
|
task :test do
|
89
|
-
sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS'] || '-t "^(?!Rack::Handler|Rack::Adapter|Rack::Session::Memcache)"'}"
|
89
|
+
sh "specrb -Ilib:test -w #{ENV['TEST'] || '-a'} #{ENV['TESTOPTS'] || '-t "^(?!Rack::Handler|Rack::Adapter|Rack::Session::Memcache|Rack::Auth::OpenID)"'}"
|
90
90
|
end
|
91
91
|
|
92
92
|
desc "Run all the tests"
|
@@ -135,6 +135,7 @@ Also see http://rack.rubyforge.org.
|
|
135
135
|
s.add_development_dependency 'fcgi'
|
136
136
|
s.add_development_dependency 'memcache-client'
|
137
137
|
s.add_development_dependency 'mongrel'
|
138
|
+
s.add_development_dependency 'ruby-openid', '~> 2.0.0'
|
138
139
|
s.add_development_dependency 'thin'
|
139
140
|
end
|
140
141
|
|
data/vendor/rack/lib/rack.rb
CHANGED
@@ -59,6 +59,7 @@ module Rack
|
|
59
59
|
autoload :Basic, "rack/auth/basic"
|
60
60
|
autoload :AbstractRequest, "rack/auth/abstract/request"
|
61
61
|
autoload :AbstractHandler, "rack/auth/abstract/handler"
|
62
|
+
autoload :OpenID, "rack/auth/openid"
|
62
63
|
module Digest
|
63
64
|
autoload :MD5, "rack/auth/digest/md5"
|
64
65
|
autoload :Nonce, "rack/auth/digest/nonce"
|
@@ -0,0 +1,487 @@
|
|
1
|
+
# AUTHOR: Scytrin dai Kinthra <scytrin@gmail.com>; blink#ruby-lang@irc.freenode.net
|
2
|
+
|
3
|
+
gem 'ruby-openid', '~> 2' if defined? Gem
|
4
|
+
require 'rack/request'
|
5
|
+
require 'rack/utils'
|
6
|
+
require 'rack/auth/abstract/handler'
|
7
|
+
|
8
|
+
require 'uri'
|
9
|
+
require 'openid'
|
10
|
+
require 'openid/extension'
|
11
|
+
require 'openid/store/memory'
|
12
|
+
|
13
|
+
module Rack
|
14
|
+
class Request
|
15
|
+
def openid_request
|
16
|
+
@env['rack.auth.openid.request']
|
17
|
+
end
|
18
|
+
|
19
|
+
def openid_response
|
20
|
+
@env['rack.auth.openid.response']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Auth
|
25
|
+
|
26
|
+
# Rack::Auth::OpenID provides a simple method for setting up an OpenID
|
27
|
+
# Consumer. It requires the ruby-openid library from janrain to operate,
|
28
|
+
# as well as a rack method of session management.
|
29
|
+
#
|
30
|
+
# The ruby-openid home page is at http://openidenabled.com/ruby-openid/.
|
31
|
+
#
|
32
|
+
# The OpenID specifications can be found at
|
33
|
+
# http://openid.net/specs/openid-authentication-1_1.html
|
34
|
+
# and
|
35
|
+
# http://openid.net/specs/openid-authentication-2_0.html. Documentation
|
36
|
+
# for published OpenID extensions and related topics can be found at
|
37
|
+
# http://openid.net/developers/specs/.
|
38
|
+
#
|
39
|
+
# It is recommended to read through the OpenID spec, as well as
|
40
|
+
# ruby-openid's documentation, to understand what exactly goes on. However
|
41
|
+
# a setup as simple as the presented examples is enough to provide
|
42
|
+
# Consumer functionality.
|
43
|
+
#
|
44
|
+
# This library strongly intends to utilize the OpenID 2.0 features of the
|
45
|
+
# ruby-openid library, which provides OpenID 1.0 compatiblity.
|
46
|
+
#
|
47
|
+
# NOTE: Due to the amount of data that this library stores in the
|
48
|
+
# session, Rack::Session::Cookie may fault.
|
49
|
+
#
|
50
|
+
# == Examples
|
51
|
+
#
|
52
|
+
# simple_oid = OpenID.new('http://mysite.com/')
|
53
|
+
#
|
54
|
+
# return_oid = OpenID.new('http://mysite.com/', {
|
55
|
+
# :return_to => 'http://mysite.com/openid'
|
56
|
+
# })
|
57
|
+
#
|
58
|
+
# complex_oid = OpenID.new('http://mysite.com/',
|
59
|
+
# :immediate => true,
|
60
|
+
# :extensions => {
|
61
|
+
# ::OpenID::SReg => [['email'],['nickname']]
|
62
|
+
# }
|
63
|
+
# )
|
64
|
+
#
|
65
|
+
# = Advanced
|
66
|
+
#
|
67
|
+
# Most of the functionality of this library is encapsulated such that
|
68
|
+
# expansion and overriding functions isn't difficult nor tricky.
|
69
|
+
# Alternately, to avoid opening up singleton objects or subclassing, a
|
70
|
+
# wrapper rack middleware can be composed to act upon Auth::OpenID's
|
71
|
+
# responses. See #check and #finish for locations of pertinent data.
|
72
|
+
#
|
73
|
+
# == Responses
|
74
|
+
#
|
75
|
+
# To change the responses that Auth::OpenID returns, override the methods
|
76
|
+
# #redirect, #bad_request, #unauthorized, #access_denied, and
|
77
|
+
# #foreign_server_failure.
|
78
|
+
#
|
79
|
+
# Additionally #confirm_post_params is used when the URI would exceed
|
80
|
+
# length limits on a GET request when doing the initial verification
|
81
|
+
# request.
|
82
|
+
#
|
83
|
+
# == Processing
|
84
|
+
#
|
85
|
+
# To change methods of processing completed transactions, override the
|
86
|
+
# methods #success, #setup_needed, #cancel, and #failure. Please ensure
|
87
|
+
# the returned object is a rack compatible response.
|
88
|
+
#
|
89
|
+
# The first argument is an OpenID::Response, the second is a
|
90
|
+
# Rack::Request of the current request, the last is the hash used in
|
91
|
+
# ruby-openid handling, which can be found manually at
|
92
|
+
# env['rack.session'][:openid].
|
93
|
+
#
|
94
|
+
# This is useful if you wanted to expand the processing done, such as
|
95
|
+
# setting up user accounts.
|
96
|
+
#
|
97
|
+
# oid_app = Rack::Auth::OpenID.new realm, :return_to => return_to
|
98
|
+
# def oid_app.success oid, request, session
|
99
|
+
# user = Models::User[oid.identity_url]
|
100
|
+
# user ||= Models::User.create_from_openid oid
|
101
|
+
# request['rack.session'][:user] = user.id
|
102
|
+
# redirect MyApp.site_home
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# site_map['/openid'] = oid_app
|
106
|
+
# map = Rack::URLMap.new site_map
|
107
|
+
# ...
|
108
|
+
|
109
|
+
class OpenID
|
110
|
+
# Raised if an incompatible session is being used.
|
111
|
+
class NoSession < RuntimeError; end
|
112
|
+
# Raised if an extension not matching specifications is provided.
|
113
|
+
class BadExtension < RuntimeError; end
|
114
|
+
# Possible statuses returned from consumer responses. See definitions
|
115
|
+
# in the ruby-openid library.
|
116
|
+
ValidStatus = [
|
117
|
+
::OpenID::Consumer::SUCCESS,
|
118
|
+
::OpenID::Consumer::FAILURE,
|
119
|
+
::OpenID::Consumer::CANCEL,
|
120
|
+
::OpenID::Consumer::SETUP_NEEDED
|
121
|
+
]
|
122
|
+
|
123
|
+
# The first argument is the realm, identifying the site they are trusting
|
124
|
+
# with their identity. This is required, also treated as the trust_root
|
125
|
+
# in OpenID 1.x exchanges.
|
126
|
+
#
|
127
|
+
# The lits of acceptable options include :return_to, :session_key,
|
128
|
+
# :openid_param, :store, :immediate, :extensions.
|
129
|
+
#
|
130
|
+
# <tt>:return_to</tt> defines the url to return to after the client
|
131
|
+
# authenticates with the openid service provider. This url should point
|
132
|
+
# to where Rack::Auth::OpenID is mounted. If unprovided, the url of
|
133
|
+
# the current request is used.
|
134
|
+
#
|
135
|
+
# <tt>:session_key</tt> defines the key to the session hash in the env.
|
136
|
+
# The default is 'rack.session'.
|
137
|
+
#
|
138
|
+
# <tt>:openid_param</tt> defines at what key in the request parameters to
|
139
|
+
# find the identifier to resolve. As per the 2.0 spec, the default is
|
140
|
+
# 'openid_identifier'.
|
141
|
+
#
|
142
|
+
# <tt>:store</tt> defined what OpenID Store to use for persistant
|
143
|
+
# information. By default a Store::Memory is used.
|
144
|
+
#
|
145
|
+
# <tt>:immediate</tt> as true will make initial requests to be of an
|
146
|
+
# immediate type. This is false by default. See OpenID specification
|
147
|
+
# documentation.
|
148
|
+
#
|
149
|
+
# <tt>:extensions</tt> should be a hash of openid extension
|
150
|
+
# implementations. The key should be the extension module, the value
|
151
|
+
# should be an array of arguments for extension::Request.new().
|
152
|
+
# The hash is iterated over and passed to #add_extension for processing.
|
153
|
+
# Please see #add_extension for further documentation.
|
154
|
+
|
155
|
+
def initialize(realm, options={})
|
156
|
+
realm = URI(realm)
|
157
|
+
raise ArgumentError, "Invalid realm: #{realm}" \
|
158
|
+
unless realm.absolute? \
|
159
|
+
and realm.fragment.nil? \
|
160
|
+
and realm.scheme =~ /^https?$/ \
|
161
|
+
and realm.host =~ /^(\*\.)?#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+/
|
162
|
+
realm.path = '/' if realm.path.empty?
|
163
|
+
@realm = realm.to_s
|
164
|
+
|
165
|
+
if ruri = options[:return_to]
|
166
|
+
ruri = URI(ruri)
|
167
|
+
raise ArgumentError, "Invalid return_to: #{ruri}" \
|
168
|
+
unless ruri.absolute? \
|
169
|
+
and ruri.scheme =~ /^https?$/ \
|
170
|
+
and ruri.fragment.nil?
|
171
|
+
raise ArgumentError, "return_to #{ruri} not within realm #{realm}" \
|
172
|
+
unless self.within_realm?(ruri)
|
173
|
+
@return_to = ruri.to_s
|
174
|
+
end
|
175
|
+
|
176
|
+
@session_key = options[:session_key] || 'rack.session'
|
177
|
+
@openid_param = options[:openid_param] || 'openid_identifier'
|
178
|
+
@store = options[:store] || ::OpenID::Store::Memory.new
|
179
|
+
@immediate = !!options[:immediate]
|
180
|
+
|
181
|
+
@extensions = {}
|
182
|
+
if extensions = options[:extensions]
|
183
|
+
extensions.each do |ext, args|
|
184
|
+
add_extension(ext, *args)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Undocumented, semi-experimental
|
189
|
+
@anonymous = !!options[:anonymous]
|
190
|
+
end
|
191
|
+
|
192
|
+
attr_reader :realm, :return_to, :session_key, :openid_param, :store,
|
193
|
+
:immediate, :extensions
|
194
|
+
|
195
|
+
# Sets up and uses session data at <tt>:openid</tt> within the session.
|
196
|
+
# Errors in this setup will raise a NoSession exception.
|
197
|
+
#
|
198
|
+
# If the parameter 'openid.mode' is set, which implies a followup from
|
199
|
+
# the openid server, processing is passed to #finish and the result is
|
200
|
+
# returned. However, if there is no appropriate openid information in the
|
201
|
+
# session, a 400 error is returned.
|
202
|
+
#
|
203
|
+
# If the parameter specified by <tt>options[:openid_param]</tt> is
|
204
|
+
# present, processing is passed to #check and the result is returned.
|
205
|
+
#
|
206
|
+
# If neither of these conditions are met, #bad_request is called.
|
207
|
+
|
208
|
+
def call(env)
|
209
|
+
env['rack.auth.openid'] = self
|
210
|
+
env_session = env[@session_key]
|
211
|
+
unless env_session and env_session.is_a?(Hash)
|
212
|
+
raise NoSession, 'No compatible session.'
|
213
|
+
end
|
214
|
+
# let us work in our own namespace...
|
215
|
+
session = (env_session[:openid] ||= {})
|
216
|
+
unless session and session.is_a?(Hash)
|
217
|
+
raise NoSession, 'Incompatible openid session.'
|
218
|
+
end
|
219
|
+
|
220
|
+
request = Rack::Request.new(env)
|
221
|
+
consumer = ::OpenID::Consumer.new(session, @store)
|
222
|
+
|
223
|
+
if mode = request.GET['openid.mode']
|
224
|
+
finish(consumer, session, request)
|
225
|
+
elsif request.GET[@openid_param]
|
226
|
+
check(consumer, session, request)
|
227
|
+
else
|
228
|
+
bad_request
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
# As the first part of OpenID consumer action, #check retrieves the data
|
233
|
+
# required for completion.
|
234
|
+
#
|
235
|
+
# If all parameters fit within the max length of a URI, a 303 redirect
|
236
|
+
# will be returned. Otherwise #confirm_post_params will be called.
|
237
|
+
#
|
238
|
+
# Any messages from OpenID's request are logged to env['rack.errors']
|
239
|
+
#
|
240
|
+
# <tt>env['rack.auth.openid.request']</tt> is the openid checkid request
|
241
|
+
# instance.
|
242
|
+
#
|
243
|
+
# <tt>session[:openid_param]</tt> is set to the openid identifier
|
244
|
+
# provided by the user.
|
245
|
+
#
|
246
|
+
# <tt>session[:return_to]</tt> is set to the return_to uri given to the
|
247
|
+
# identity provider.
|
248
|
+
|
249
|
+
def check(consumer, session, req)
|
250
|
+
oid = consumer.begin(req.GET[@openid_param], @anonymous)
|
251
|
+
req.env['rack.auth.openid.request'] = oid
|
252
|
+
req.env['rack.errors'].puts(oid.message)
|
253
|
+
p oid if $DEBUG
|
254
|
+
|
255
|
+
## Extension support
|
256
|
+
extensions.each do |ext,args|
|
257
|
+
oid.add_extension(ext::Request.new(*args))
|
258
|
+
end
|
259
|
+
|
260
|
+
session[:openid_param] = req.GET[openid_param]
|
261
|
+
return_to_uri = return_to ? return_to : req.url
|
262
|
+
session[:return_to] = return_to_uri
|
263
|
+
immediate = session.key?(:setup_needed) ? false : immediate
|
264
|
+
|
265
|
+
if oid.send_redirect?(realm, return_to_uri, immediate)
|
266
|
+
redirect(oid.redirect_url(realm, return_to_uri, immediate))
|
267
|
+
else
|
268
|
+
confirm_post_params(oid, realm, return_to_uri, immediate)
|
269
|
+
end
|
270
|
+
rescue ::OpenID::DiscoveryFailure => e
|
271
|
+
# thrown from inside OpenID::Consumer#begin by yadis stuff
|
272
|
+
req.env['rack.errors'].puts( [e.message, *e.backtrace]*"\n" )
|
273
|
+
return foreign_server_failure
|
274
|
+
end
|
275
|
+
|
276
|
+
# This is the final portion of authentication.
|
277
|
+
# If successful, a redirect to the realm is be returned.
|
278
|
+
# Data gathered from extensions are stored in session[:openid] with the
|
279
|
+
# extension's namespace uri as the key.
|
280
|
+
#
|
281
|
+
# Any messages from OpenID's response are logged to env['rack.errors']
|
282
|
+
#
|
283
|
+
# <tt>env['rack.auth.openid.response']</tt> will contain the openid
|
284
|
+
# response.
|
285
|
+
|
286
|
+
def finish(consumer, session, req)
|
287
|
+
oid = consumer.complete(req.GET, req.url)
|
288
|
+
req.env['rack.auth.openid.response'] = oid
|
289
|
+
req.env['rack.errors'].puts(oid.message)
|
290
|
+
p oid if $DEBUG
|
291
|
+
|
292
|
+
if ValidStatus.include?(oid.status)
|
293
|
+
__send__(oid.status, oid, req, session)
|
294
|
+
else
|
295
|
+
invalid_status(oid, req, session)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# The first argument should be the main extension module.
|
300
|
+
# The extension module should contain the constants:
|
301
|
+
# * class Request, should have OpenID::Extension as an ancestor
|
302
|
+
# * class Response, should have OpenID::Extension as an ancestor
|
303
|
+
# * string NS_URI, which defining the namespace of the extension
|
304
|
+
#
|
305
|
+
# All trailing arguments will be passed to extension::Request.new in
|
306
|
+
# #check.
|
307
|
+
# The openid response will be passed to
|
308
|
+
# extension::Response#from_success_response, oid#get_extension_args will
|
309
|
+
# be called on the result to attain the gathered data.
|
310
|
+
#
|
311
|
+
# This method returns the key at which the response data will be found in
|
312
|
+
# the session, which is the namespace uri by default.
|
313
|
+
|
314
|
+
def add_extension(ext, *args)
|
315
|
+
raise BadExtension unless valid_extension?(ext)
|
316
|
+
extensions[ext] = args
|
317
|
+
return ext::NS_URI
|
318
|
+
end
|
319
|
+
|
320
|
+
# Checks the validitity, in the context of usage, of a submitted
|
321
|
+
# extension.
|
322
|
+
|
323
|
+
def valid_extension?(ext)
|
324
|
+
if not %w[NS_URI Request Response].all?{|c| ext.const_defined?(c) }
|
325
|
+
raise ArgumentError, 'Extension is missing constants.'
|
326
|
+
elsif not ext::Response.respond_to?(:from_success_response)
|
327
|
+
raise ArgumentError, 'Response is missing required method.'
|
328
|
+
end
|
329
|
+
return true
|
330
|
+
rescue
|
331
|
+
return false
|
332
|
+
end
|
333
|
+
|
334
|
+
# Checks the provided uri to ensure it'd be considered within the realm.
|
335
|
+
# is currently not compatible with wildcard realms.
|
336
|
+
|
337
|
+
def within_realm? uri
|
338
|
+
uri = URI.parse(uri.to_s)
|
339
|
+
realm = URI.parse(self.realm)
|
340
|
+
return false unless uri.absolute?
|
341
|
+
return false unless uri.path[0, realm.path.size] == realm.path
|
342
|
+
return false unless uri.host == realm.host or realm.host[/^\*\./]
|
343
|
+
# for wildcard support, is awkward with URI limitations
|
344
|
+
realm_match = Regexp.escape(realm.host).
|
345
|
+
sub(/^\*\./,"^#{URI::REGEXP::PATTERN::URIC_NO_SLASH}+.")+'$'
|
346
|
+
return false unless uri.host.match(realm_match)
|
347
|
+
return true
|
348
|
+
end
|
349
|
+
|
350
|
+
alias_method :include?, :within_realm?
|
351
|
+
|
352
|
+
protected
|
353
|
+
|
354
|
+
# Returns an html form page for posting to an Identity Provider if the
|
355
|
+
# GET request would exceed the upper URI length limit.
|
356
|
+
|
357
|
+
def confirm_post_params(oid, realm, return_to, immediate)
|
358
|
+
response = Rack::Response.new '<html>'+
|
359
|
+
'<head><title>Confirm...</title></head>'+
|
360
|
+
'<body>'+oid.form_markup(realm, return_to, immediate)+'</body>'+
|
361
|
+
'</html>'
|
362
|
+
response.finish
|
363
|
+
end
|
364
|
+
|
365
|
+
# Returns a 303 redirect with the destination of that provided by the
|
366
|
+
# argument.
|
367
|
+
|
368
|
+
def redirect(uri)
|
369
|
+
[ 303, {'Content-Type'=>'text/plain', 'Content-Length'=>'0',
|
370
|
+
'Location' => uri},
|
371
|
+
[] ]
|
372
|
+
end
|
373
|
+
|
374
|
+
# Returns an empty 400 response.
|
375
|
+
|
376
|
+
def bad_request
|
377
|
+
[ 400, {'Content-Type'=>'text/plain', 'Content-Length'=>'0'},
|
378
|
+
[''] ]
|
379
|
+
end
|
380
|
+
|
381
|
+
# Returns a basic unauthorized 401 response.
|
382
|
+
|
383
|
+
def unauthorized
|
384
|
+
[ 401, {'Content-Type' => 'text/plain', 'Content-Length' => '13'},
|
385
|
+
['Unauthorized.'] ]
|
386
|
+
end
|
387
|
+
|
388
|
+
# Returns a basic access denied 403 response.
|
389
|
+
|
390
|
+
def access_denied
|
391
|
+
[ 403, {'Content-Type' => 'text/plain', 'Content-Length' => '14'},
|
392
|
+
['Access denied.'] ]
|
393
|
+
end
|
394
|
+
|
395
|
+
# Returns a 503 response to be used if communication with the remote
|
396
|
+
# OpenID server fails.
|
397
|
+
|
398
|
+
def foreign_server_failure
|
399
|
+
[ 503, {'Content-Type'=>'text/plain', 'Content-Length' => '23'},
|
400
|
+
['Foreign server failure.'] ]
|
401
|
+
end
|
402
|
+
|
403
|
+
private
|
404
|
+
|
405
|
+
# Called to complete processing on a successful transaction.
|
406
|
+
# Within the openid session, :openid_identity and :openid_identifier are
|
407
|
+
# set to the user friendly and the standard representation of the
|
408
|
+
# validated identity. All other data in the openid session is cleared.
|
409
|
+
|
410
|
+
def success(oid, request, session)
|
411
|
+
session.clear
|
412
|
+
session[:openid_identity] = oid.display_identifier
|
413
|
+
session[:openid_identifier] = oid.identity_url
|
414
|
+
extensions.keys.each do |ext|
|
415
|
+
label = ext.name[/[^:]+$/].downcase
|
416
|
+
response = ext::Response.from_success_response(oid)
|
417
|
+
session[label] = response.data
|
418
|
+
end
|
419
|
+
redirect(realm)
|
420
|
+
end
|
421
|
+
|
422
|
+
# Called if the Identity Provider indicates further setup by the user is
|
423
|
+
# required.
|
424
|
+
# The identifier is retrived from the openid session at :openid_param.
|
425
|
+
# And :setup_needed is set to true to prevent looping.
|
426
|
+
|
427
|
+
def setup_needed(oid, request, session)
|
428
|
+
identifier = session[:openid_param]
|
429
|
+
session[:setup_needed] = true
|
430
|
+
redirect(req.script_name + '?' + openid_param + '=' + identifier)
|
431
|
+
end
|
432
|
+
|
433
|
+
# Called if the user indicates they wish to cancel identification.
|
434
|
+
# Data within openid session is cleared.
|
435
|
+
|
436
|
+
def cancel(oid, request, session)
|
437
|
+
session.clear
|
438
|
+
access_denied
|
439
|
+
end
|
440
|
+
|
441
|
+
# Called if the Identity Provider indicates the user is unable to confirm
|
442
|
+
# their identity. Data within the openid session is left alone, in case
|
443
|
+
# of swarm auth attacks.
|
444
|
+
|
445
|
+
def failure(oid, request, session)
|
446
|
+
unauthorized
|
447
|
+
end
|
448
|
+
|
449
|
+
# To be called if there is no method for handling the OpenID response
|
450
|
+
# status.
|
451
|
+
|
452
|
+
def invalid_status(oid, request, session)
|
453
|
+
msg = 'Invalid status returned by the OpenID authorization reponse.'
|
454
|
+
[ 500,
|
455
|
+
{'Content-Type'=>'text/plain','Content-Length'=>msg.length.to_s},
|
456
|
+
[msg] ]
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
# A class developed out of the request to use OpenID as an authentication
|
461
|
+
# middleware. The request will be sent to the OpenID instance unless the
|
462
|
+
# block evaluates to true. For example in rackup, you can use it as such:
|
463
|
+
#
|
464
|
+
# use Rack::Session::Pool
|
465
|
+
# use Rack::Auth::OpenIDAuth, realm, openid_options do |env|
|
466
|
+
# env['rack.session'][:authkey] == a_string
|
467
|
+
# end
|
468
|
+
# run RackApp
|
469
|
+
#
|
470
|
+
# Or simply:
|
471
|
+
#
|
472
|
+
# app = Rack::Auth::OpenIDAuth.new app, realm, openid_options, &auth
|
473
|
+
|
474
|
+
class OpenIDAuth < Rack::Auth::AbstractHandler
|
475
|
+
attr_reader :oid
|
476
|
+
def initialize(app, realm, options={}, &auth)
|
477
|
+
@oid = OpenID.new(realm, options)
|
478
|
+
super(app, &auth)
|
479
|
+
end
|
480
|
+
|
481
|
+
def call(env)
|
482
|
+
to = @authenticator.call(env) ? @app : @oid
|
483
|
+
to.call(env)
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|