Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
initial commit
  • Loading branch information
mkristian committed Sep 5, 2011
0 parents commit 93c4226
Show file tree
Hide file tree
Showing 39 changed files with 1,192 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
target
*.pom
*~
20 changes: 20 additions & 0 deletions MIT-LICENSE
@@ -0,0 +1,20 @@
Copyright (c) 2008 Kristian Meier

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64 changes: 64 additions & 0 deletions README.md
@@ -0,0 +1,64 @@
# Ixtlan #

this gem adds more security related headers to the response for a rails3 application. mainly inspired by
[google-gets-a-1-for-browser-security](http://www.barracudalabs.com/wordpress/index.php/2011/07/21/google-gets-a-1-for-browser-security-3/)
and
[HttpCaching](http://code.google.com/p/doctype/wiki/ArticleHttpCaching).
and
[Clickjacking](http://www.owasp.org/index.php/Clickjacking)

the extra headers are

* x-frame headers
* x-content-type headers
* x-xss-protection headers
* caching headers

the main idea is to set the default as strict as possible and the application might relax the setup here and there.

## rails configuration ##

in _config/application.rb_ or in one of the _config/environments/*rb_ files or in an initializer. all three x-headers can be configured here, for example

config.x_content_type_headers = :nosniff

## controller configuration ##

just add in your controller something like

x_xss_protection :block

## option for each *render*, *send\_file*, *send\_data* methods

an example for an inline render

render :inline => 'behappy', :x_frame_headers => :deny

## possible values ##

* x\_frame\_headers : `:deny, :sameorigin, :off` default `:deny`

* x\_content\_type\_headers : `:nosniff, :off` default `:nosniff`

* x\_xss\_protection\_headers : `:block, :disabled, :off` default `:block`

## cache headers

the cache headers needs to have a **current\_user**, i.e. the current\_user method of the controller needs to return a non-nil value. further the the method needs to `:get` and the response status an "ok" status,

then you can use the controller configuration or the options with *render*, *send\_file* and *send\_data*.

## possible values ##

* `:private` : which tells not to cache or store any data except the browser memory: [no caching](http://code.google.com/p/doctype/wiki/ArticleHttpCaching#No_caching)

* `:protected` : no caching but the browser: [Only the end user's browser is allowed to cache](http://code.google.com/p/doctype/wiki/ArticleHttpCaching#Only_the_end_user%27s_browser_is_allowed_to_cache)

* `:public` : caching is allowed: [Both browser and proxy allowed to cache](http://code.google.com/p/doctype/wiki/ArticleHttpCaching#Both_browser_and_proxy_allowed_to_cache)

* `:my_headers` : custom header method like

> def my_headers
no_store = false
no_caching(no_store)
end
9 changes: 9 additions & 0 deletions TODO
@@ -0,0 +1,9 @@
* singleton unit tests

* singleton erb templates are not found

* plural attributes are singular in Model.java - have them plural as well

* production.yml => password.yml and see taperoom how to deal with default - maybe

* attr_accessors in model - mass-assignments
6 changes: 6 additions & 0 deletions features/generators.feature
@@ -0,0 +1,6 @@
Feature: Generators for Ixtlan

Scenario: Create a rails application and adding 'ixtlan-generators' gem will provide the ixtlan generators
Given I create new rails application with template "generators.template"
And I execute "rails generate"
Then the output should contain "ixtlan:setup" and "ixtlan:configuration_model" and "ixtlan:configuration_scaffold"
170 changes: 170 additions & 0 deletions features/step_definitions/ruby_maven.rb
@@ -0,0 +1,170 @@
require 'fileutils'

module Maven
class RubyMaven

# make the command line for the goals of the jruby-maven-plugins nicer
PLUGINS = {
:rake => [:rake],
:ruby => [:jruby, :compile],
:gem => [:package, :install, :push, :exec, :pom, :initialize, :irb],
:gemify => [:gemify, :versions],
:rails2 => [:new, :generate, :rake, :server, :console],
:rails3 => [:new, :generate, :rake, :server, :console, :dbconsole, :pom, :initialize],
:cucumber => [:test],
:rspec => [:test],
:runit => [:test],
:bundler => [:install]
}
ALIASES = {
:jruby => :ruby,
:spec => :rspec,
:rails => :rails3,
:bundle => :bundler
}

def initialize
@command = "#{ENV['GEM_HOME']}/bin/rmvn"
@jruby = File.read(@command).split("\n")[0].sub(/^#!/, '')
@maven_home = File.expand_path(Dir.glob("#{ENV['GEM_HOME']}/gems/ruby-maven-*-java")[0])
end

def launch_jruby(args)
classpath_array.each do |path|
require path
end

java.lang.System.setProperty("classworlds.conf",
File.join(@maven_home, 'bin', "m2.conf"))

java.lang.System.setProperty("maven.home", @maven_home)

org.codehaus.plexus.classworlds.launcher.Launcher.main(args)
end

def classpath_array
(Dir.glob(File.join(@maven_home, "boot", "*jar")) +
Dir.glob(File.join(@maven_home, "ext", "ruby-tools*jar"))).each do |path|
path
end
end

def launch_java(*args)
"java -cp #{classpath_array.join(':')} -Dmaven.home=#{File.expand_path(@maven_home)} -Dclassworlds.conf=#{File.expand_path(File.join(@maven_home, 'bin', 'm2.conf'))} org.codehaus.plexus.classworlds.launcher.Launcher #{args.join ' '}"
end

def prepare(args)
if args.size > 0
name = args[0].to_sym
name = ALIASES[name] || name
if PLUGINS.member?(name)
start = 1
if args.size > 1
if PLUGINS[name].member? args[1].to_sym
goal = args[1].to_sym
start = 2
else
goal = PLUGINS[name][0]
end
else
goal = PLUGINS[name][0]
end
aa = if index = args.index("--")
args[(index + 1)..-1]
else
[]
end
ruby_args = (args[start, (index || 1000) - start] || []).join(' ')

# determine the version and delete from args if given
version = args.detect do |a|
a =~ /^-Dplugin.version=/
end
if version
aa.delete(version)
version.sub!(/^-Dplugin.version=/, ':')
end
aa << "de.saumya.mojo:#{name}-maven-plugin#{version}:#{goal}"
aa << "-Dargs=#{ruby_args}" if ruby_args.size > 0
args.replace(aa)
else
args.delete("--")
end
end
args
end

def log(args)
log = File.join('log', 'rmvn.log')
if File.exists? File.dirname(log)
File.open(log, 'a') do |f|
f.puts args.join ' '
end
end
end

def maybe_print_help(args)
if args.size == 0 || args[0] == "--help"
puts "usage: rmvn [<plugin name>|<plugin alias> [<args>] [-- <maven options>] | [<maven goal>|<maven phase> <maven options>] | --help"
PLUGINS.each do |name, goals|
puts
print "plugin #{name}"
print " - alias: #{ALIASES[name]}" if ALIASES[name]
puts
if goals.size > 1
print "\tgoals : #{goals.join(',')}"
puts
end
print "\tdefault goal: #{goals[0]}"
puts
end
puts
["--help"]
else
args
end
end

def options
@options ||= {}
end

def options_string
options_array.join ' '
end

def options_array
options.collect do |k,v|
if k =~ /^-D/
v = "=#{v}" if v
else
v = " #{v}" if v
end
"#{k}#{v}"
end
end

def command_line(args)
args = prepare(args)
args = maybe_print_help(args)
args
end

def exec(*args)
a = command_line(args.dup.flatten)
a << options_array
a.flatten!
#puts a.join ' '
#launch_jruby(a)
args_line = args.join ' '
full = "#{@jruby} #{@command} #{args_line} #{args_line =~ / -- / ? '' : '--'} #{options_string}"
system full
end

def exec_in(launchdirectory, *args)
FileUtils.cd(launchdirectory) do
exec(args)
end
end
end
end
82 changes: 82 additions & 0 deletions features/step_definitions/simple_steps.rb
@@ -0,0 +1,82 @@
require 'fileutils'
require File.join(File.dirname(__FILE__), 'ruby_maven')

def rmvn
@rmvn ||= Maven::RubyMaven.new
end

def copy_tests(tests)
FileUtils.mkdir_p(@app_directory)
FileUtils.cp_r(File.join('templates', "tests-#{tests}", "."),
File.join(@app_directory, 'test'))
end

def copy_specs(specs)
FileUtils.mkdir_p(@app_directory)
FileUtils.cp_r(File.join('templates', "specs-#{specs}", "."),
File.join(@app_directory, 'spec'))
end

def create_rails_application(template)
name = template.sub(/.template$/, '')
@app_directory = File.join('target', name)

# rails version from gemspec
gemspec = File.read(Dir.glob("*.gemspec")[0])
rails_version = gemspec.split("\n").detect { |l| l =~ /development_dep.*rails/ }.sub(/'$/, '').sub(/.*'/, '')

rmvn.options['-Dplugin.version'] = '0.28.4-SNAPSHOT'
rmvn.options['-Drails.version'] = rails_version
rmvn.options['-Dgem.home'] = ENV['GEM_HOME']
rmvn.options['-Dgem.path'] = ENV['GEM_PATH']
rmvn.options['-o'] = nil

FileUtils.rm_rf(@app_directory)

rmvn.exec("rails", "new", @app_directory, "-f")

# TODO that should be done via the rails new task !!!
rmvn.exec_in(@app_directory, "rails", "rake", "rails:template LOCATION=" + File.expand_path("templates/#{template}"))
end

Given /^I create new rails application with template "(.*)"$/ do |template|
create_rails_application(template)
end

Given /^I create new rails application with template "(.*)" and "(.*)" tests$/ do |template, tests|
create_rails_application(template)
copy_tests(tests)
end

Given /^I create new rails application with template "(.*)" and "(.*)" specs$/ do |template, specs|
create_rails_application(template)
copy_specs(specs)
end

Given /^me an existing rails application "(.*)"$/ do |name|
@app_directory = File.join('target', name)
end

Given /^me an existing rails application "(.*)" and "(.*)" tests$/ do |name, tests|
@app_directory = File.join('target', name)
copy_tests(tests)
end

Given /^me an existing rails application "(.*)" and "(.*)" specs$/ do |name, specs|
@app_directory = File.join('target', name)
copy_specs(specs)
end

And /^I execute \"(.*)\"$/ do |args|
rmvn.options['-l'] = "output.log"
rmvn.exec_in(@app_directory, args)
end

Then /^the output should contain \"(.*)\"$/ do |expected|
result = File.read(File.join(@app_directory, "output.log"))
expected.split(/\"?\s+and\s+\"?/).each do |exp|
puts exp
(result =~ /.*#{exp}.*/).should_not be_nil
end
end

31 changes: 31 additions & 0 deletions ixtlan-generators.gemspec
@@ -0,0 +1,31 @@
# -*- mode: ruby -*-
Gem::Specification.new do |s|
s.name = 'ixtlan-generators'
s.version = '0.1.0'

s.summary = 'rails generator templates for ixtlan gems'
s.description = s.summary
s.homepage = 'http://github.com/mkristian/ixtlan-generators'

s.authors = ['mkristian']
s.email = ['m.kristian@web.de']

s.files = Dir['MIT-LICENSE']
s.licenses << 'MIT-LICENSE'
# s.files += Dir['History.txt']
s.files += Dir['README.md']
s.files += Dir['lib/**/*']
s.files += Dir['spec/**/*']
s.files += Dir['features/**/*rb']
s.files += Dir['features/**/*feature']
s.test_files += Dir['spec/**/*_spec.rb']
s.test_files += Dir['features/*.feature']
s.test_files += Dir['features/step_definitions/*.rb']
s.add_development_dependency 'ixtlan-core', '~>0.5'
s.add_development_dependency 'rails', '3.0.9'
s.add_development_dependency 'rspec', '2.6.0'
s.add_development_dependency 'cucumber', '0.9.4'
s.add_development_dependency 'ruby-maven', '0.8.3.0.3.0.28.3'
end

# vim: syntax=Ruby
1 change: 1 addition & 0 deletions ixtlan-generators.gemspec.files
@@ -0,0 +1 @@
ixtlan-generators.gemspec

0 comments on commit 93c4226

Please sign in to comment.