fredit 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,62 +1,86 @@
1
- require 'shellwords'
1
+ require 'git'
2
2
 
3
3
  class FreditController < ::ApplicationController
4
4
 
5
- layout false
5
+ layout 'fredit'
6
+
7
+ before_filter :load_git
6
8
 
7
9
  CSS_DIR = Rails.root + 'public/stylesheets/**/*.css'
8
10
  JS_DIR = Rails.root + 'public/javascripts/**/*.js'
9
11
 
10
- def index
11
- @path ||= secure_path(params[:file] || params[:new_path] || Fredit.editables[:views].first)
12
- if !File.size?(@path)
13
- File.open(@path, 'w') {|f| f.write("REPLACE WITH CONTENT")}
14
- end
12
+ def show
13
+ @path ||= secure_path(params[:file] || Fredit.editables[:views].first)
14
+ load_git_log
15
15
  @source = File.read(Rails.root + @path)
16
16
  end
17
17
 
18
18
  def update
19
19
  @path = secure_path params[:file_path]
20
20
 
21
- edit_msg = !params[:edit_message].blank? ? Shellwords.shellescape(params[:edit_message].gsub(/["']/, '')) : "unspecified edit"
21
+ edit_msg = !params[:edit_message].blank? ? params[:edit_message] : "unspecified edit"
22
+ edit_msg_file = Tempfile.new('commit-message')
23
+ t.write(edit_msg) # we write this message to a file to protect against shell injection
24
+ t.cloase
25
+
26
+ session[:commit_author] = (params[:commit_author] || '')
27
+ # cleanup any shell injection attempt characters
28
+ author = session[:commit_author].gsub(/[^\w@<>. ]/, '')
22
29
 
23
- session[:commit_author] = (params[:commit_author] || '').gsub(/['"]/, '')
24
- author = session[:commit_author]
25
30
  if session[:commit_author].blank?
26
31
  flash.now[:notice] = "Edited By must not be blank"
27
32
  @source = params[:source]
28
- render :action => 'index'
33
+ render :action => 'show'
29
34
  return
30
35
  end
31
36
 
32
37
  if params[:commit] =~ /delete/i
33
38
  `git rm #@path`
34
39
  flash[:notice] = "#@path deleted"
35
- res = system %Q|git commit --author='#{author}' -m '#{edit_msg}' #{@path}|
40
+ res = system %Q|git commit --author='#{author}' --file '#{edit_msg_file}' #{@path}|
36
41
  @path = nil
37
42
  else
38
43
  n = params[:source].gsub(/\r\n/, "\n")
39
44
  File.open(@path, 'w') {|f| f.write(n)}
40
45
  system %Q|git add #{@path}|
41
46
  flash[:notice] = "#@path updated"
42
- res = system %Q|git commit --author='#{author}' -m '#{edit_msg}' #{@path}|
47
+ res = system %Q|git commit --author='#{author}' --file '#{edit_msg_file}' #{@path}|
43
48
  end
44
49
  if res == false
45
50
  flash[:notice] = "Something went wrong with git. Make sure you changed something and filled in required fields."
46
51
  end
47
- params.delete(:source)
48
-
49
- redirect_to :action => 'index', :file => @path
52
+ redirect_to fredit_path(:file => @path)
50
53
  end
51
54
 
52
55
  def create
53
- @path = secure_path params[:file]
56
+ @path = secure_path params[:new_file]
54
57
  FileUtils::mkdir_p File.dirname(@path)
55
58
  File.open(@path, 'w') {|f| f.write("REPLACE WITH CONTENT")}
59
+ flash[:notice] = "Created new file: #@path"
60
+ redirect_to fredit_path(:file => @path)
61
+ end
62
+
63
+ def revision
64
+ @path = secure_path params[:file]
65
+ load_git_log
66
+ @sha = params[:sha].gsub(/[^0-9a-z]/, '') # shell injection protection
67
+ @git_object = @git.object(@sha)
68
+ @diff = `git show #{@sha}`
56
69
  end
57
70
 
58
71
  private
59
72
 
73
+ def load_git
74
+ @git = Git.init Rails.root.to_s
75
+ end
76
+
77
+ def load_git_log
78
+ @git_log = @git.log(20).object(@path).to_a
79
+ rescue Git::GitExecuteError
80
+ @git_log = []
81
+ flash[:notice] = "You need to initialize a git repository or add this file to the path"
82
+ end
83
+
60
84
  def secure_path(path)
61
85
  path2 = File.expand_path(path.to_s)
62
86
  if path2.index(Rails.root.to_s) != 0
@@ -0,0 +1,36 @@
1
+ <textarea name='source'><%= @diff %></textarea>
2
+
3
+ <table>
4
+ <tr>
5
+ <td>File:</td>
6
+ <td>
7
+ <%= link_to @path, fredit_path(:file => @path) %>
8
+ </td>
9
+ </tr>
10
+ <tr>
11
+ <td>Commit:</td>
12
+ <td>
13
+ <%= @sha %>
14
+ </td>
15
+ </tr>
16
+ <tr>
17
+ <td>Edited By:</td>
18
+ <td>
19
+ <%= @git_object.author.name %>
20
+ </td>
21
+ </tr>
22
+ <tr>
23
+ <td>Date:</td>
24
+ <td>
25
+ <%= @git_object.date %>
26
+ </td>
27
+ </tr>
28
+ <tr>
29
+ <td>Log Message:</td>
30
+ <td>
31
+ <%= @git_object.message %>
32
+ </td>
33
+ </tr>
34
+ </table>
35
+
36
+
@@ -0,0 +1,55 @@
1
+
2
+ <form action="<%= fredit_path %>" method="post">
3
+ <input name="_method" type="hidden" value="put" />
4
+ <input name="utf8" type="hidden" value="&#x2713;" />
5
+ <input type="hidden" name="file" value="<%=@path%>"/>
6
+ <textarea name='source'><%= @source %></textarea>
7
+
8
+ <table>
9
+ <tr>
10
+ <td>File:</td>
11
+ <td>
12
+ <%= @path %>
13
+ </td>
14
+ </tr>
15
+ <tr>
16
+ <td>Edit Message (optional):</td>
17
+ <td>
18
+ <input type="text" name="edit_message" value="" placeholder="Describe the edit " size="50"/>
19
+ </td>
20
+ </tr>
21
+ <tr>
22
+ <td>Edited By (required): </td>
23
+ <td>
24
+ <input type="text" name="commit_author" value="<%=session[:commit_author]%>" placeholder="Your Name <yourname@example.com>" size="50"/>
25
+ </td>
26
+ </tr>
27
+ <tr>
28
+ <td>Action:</td>
29
+ <td>
30
+ <input hidden="text" name="file_path" value="<%=@path%>" />
31
+ <input type="submit" name="commit" value="update this file"/>
32
+ <input id="deleteBtn" type="submit" name="commit" value="delete this file"/>
33
+ </td>
34
+ </tr>
35
+ </table>
36
+ </form>
37
+
38
+ <form id="createFileForm" action="<%= fredit_path %>" method="post">
39
+ <table>
40
+ <tr>
41
+ <td>Create file at path:</td>
42
+ <td>
43
+ <input type="text" name="new_file" value="" placeholder="<%=Fredit.editables[:views].first%>" size="50"/>
44
+ </td>
45
+ </tr>
46
+ <tr>
47
+ <td>Action:</td>
48
+ <td>
49
+ <input type="submit" name="commit" value="create file"/>
50
+ </td>
51
+ </tr>
52
+ </table>
53
+ </form>
54
+
55
+
@@ -0,0 +1,130 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%=@path%></title>
5
+ <%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js' %>
6
+ <style type="text/css">
7
+
8
+ body {
9
+ padding-top:0;
10
+ padding-bottom: 30px;
11
+ font-family: Verdana, Helvetica, sans;
12
+ font-size: 12px;
13
+ margin-left: 40px;
14
+ width: 92%;
15
+ background-color: #EDEDED;
16
+ }
17
+ h1#appName {
18
+ margin:0;
19
+ padding:0;
20
+ display: inline;
21
+ }
22
+ h1#appName em {
23
+ font-size: smaller;
24
+ }
25
+ section#editor {
26
+ float: left;
27
+ width: 74%;
28
+ }
29
+ section#git {
30
+ float: left;
31
+ width: 23%;
32
+ padding-left: 2%;
33
+ }
34
+ section#git h3 {
35
+ margin-top: 0;
36
+ margin-bottom: 0.7em;
37
+ }
38
+ section#git ul {
39
+ padding-left: 0;
40
+ list-style-type: none;
41
+ }
42
+
43
+ textarea {
44
+ width: 100%;
45
+ height: 500px;
46
+ font-family: monospace;
47
+ }
48
+ #notice {
49
+ background-color: yellow;
50
+ }
51
+ input#deleteBtn {
52
+ float:right;
53
+ }
54
+ input[type=text] {
55
+ width: 100%;
56
+ }
57
+ table {
58
+ width: 100%
59
+ }
60
+ form#fileSelector {
61
+ float:right;
62
+ }
63
+ form#createFileForm {
64
+ border-top: 1px solid #CCC;
65
+ margin-top: 10px;
66
+ padding-top: 10px;
67
+ }
68
+
69
+ </style>
70
+ </head>
71
+ <body>
72
+
73
+ <% if flash[:notice] %>
74
+ <div id="notice"><%= flash[:notice] %></div>
75
+ <% end %>
76
+
77
+ <section id="editor">
78
+ <h1 id="appName">fredit <em>front-end edit</em></h1>
79
+ <form id="fileSelector" action="<%=fredit_path%>">
80
+ <select id="fileSelectorDropDown" name="file">
81
+ <% Fredit.editables.each_pair do |k, v| %>
82
+ <optgroup label="<%= k %>">
83
+ <% v.each do |path| %>
84
+ <option value="<%= path %>" <%= @path == path ? 'selected=\"selected\"' : nil %>><%= Fredit.link(path)%></li>
85
+ <% end %>
86
+ </optgroup>
87
+ <% end %>
88
+ </select>
89
+ <input type="submit" id="changeFileBtn" value="change file"/>
90
+ </form>
91
+ <script>
92
+ $(document).ready(function() {
93
+ $('#fileSelectorDropDown').bind('change', function() {
94
+ $('#fileSelector').submit();
95
+ });
96
+ $('#changeFileBtn').hide();
97
+ });
98
+ </script>
99
+
100
+ <%= yield %>
101
+ </section>
102
+
103
+ <section id="git">
104
+ <nav>
105
+ <h3>git</h3>
106
+ <div id="currentBranch">
107
+ Current branch:
108
+ <strong><%= @git.current_branch %></strong>
109
+ </div>
110
+
111
+ <h4>Recent edits</h4>
112
+
113
+ <ul>
114
+ <% @git_log.each do |commit| %>
115
+ <li>
116
+ <%= link_to "#{commit.date.strftime('%m-%d-%y')}",
117
+ fredit_revision_path(:sha => commit.sha, :file => @path),
118
+ :title => commit.message %>
119
+ <%= commit.author && commit.author.name %>:
120
+ <%= truncate(commit.message, :length => 15) %>
121
+ </li>
122
+ <% end %>
123
+ </ul>
124
+
125
+ </nav>
126
+ </section>
127
+
128
+ </body>
129
+ </html>
130
+
data/config/routes.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  Rails.application.routes.draw do
2
- get "/fredit" => "fredit#index"
3
- post "/fredit/update" => "fredit#update"
2
+ get 'fredit/revision' => "fredit#revision"
3
+ get 'fredit' => "fredit#show"
4
+ put 'fredit' => "fredit#update"
5
+ post 'fredit' => "fredit#create"
4
6
  end
5
7
 
data/lib/fredit.rb CHANGED
@@ -1,4 +1,8 @@
1
- require 'fredit/erb'
1
+ if Rails.version < '3.1.0'
2
+ require 'fredit/erb'
3
+ else
4
+ require 'fredit/erb31'
5
+ end
2
6
  require 'uri'
3
7
 
4
8
  module Fredit
data/lib/fredit/erb.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  module ActionView
3
2
  class Template
4
3
  module Handlers
@@ -0,0 +1,50 @@
1
+ module ActionView
2
+ class Template
3
+ module Handlers
4
+ class ERB
5
+ def call(template)
6
+ if template.source.encoding_aware?
7
+ # First, convert to BINARY, so in case the encoding is
8
+ # wrong, we can still find an encoding tag
9
+ # (<%# encoding %>) inside the String using a regular
10
+ # expression
11
+ template_source = template.source.dup.force_encoding("BINARY")
12
+
13
+ erb = template_source.gsub(ENCODING_TAG, '')
14
+ encoding = $2
15
+
16
+ erb.force_encoding valid_encoding(template.source.dup, encoding)
17
+
18
+ # Always make sure we return a String in the default_internal
19
+ erb.encode!
20
+ else
21
+ erb = template.source.dup
22
+ end
23
+
24
+ # begin Fredit patch
25
+
26
+ if Fredit.template_editable?(template)
27
+ source_file = Fredit.rel_path template.identifier
28
+ edit_link = "<div style='color:red'>#{Fredit.link(source_file)}</div> "
29
+ if erb =~ /^\s*<!DOCTYPE/ && erb =~ /<body[^>]*>/
30
+ erb = erb.sub(/<body[^>]*>/, '\&' + edit_link)
31
+ else
32
+ erb = edit_link + erb
33
+ end
34
+ end
35
+
36
+ # end Fredit patch
37
+
38
+
39
+ self.class.erb_implementation.new(
40
+ erb,
41
+ :trim => (self.class.erb_trim_mode == "-")
42
+ ).src
43
+
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
50
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fredit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,18 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
  date: 2011-10-25 00:00:00.000000000Z
13
- dependencies: []
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: git
16
+ requirement: &82978850 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *82978850
14
25
  description: Edit the front end of Rails apps through the browser.
15
26
  email:
16
27
  - dhchoi@gmail.com
@@ -18,10 +29,12 @@ executables: []
18
29
  extensions: []
19
30
  extra_rdoc_files: []
20
31
  files:
21
- - app/views/fredit/index.html.erb
22
- - app/views/fredit/layout.html.erb
32
+ - app/views/layouts/fredit.html.erb
33
+ - app/views/fredit/show.html.erb
34
+ - app/views/fredit/revision.html.erb
23
35
  - app/controllers/fredit_controller.rb
24
36
  - lib/fredit.rb
37
+ - lib/fredit/erb31.rb
25
38
  - lib/fredit/erb.rb
26
39
  - lib/fredit/engine.rb
27
40
  - config/routes.rb
@@ -43,7 +56,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
43
56
  version: '0'
44
57
  segments:
45
58
  - 0
46
- hash: -150563923
59
+ hash: 122408225
47
60
  required_rubygems_version: !ruby/object:Gem::Requirement
48
61
  none: false
49
62
  requirements:
@@ -52,11 +65,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
52
65
  version: '0'
53
66
  segments:
54
67
  - 0
55
- hash: -150563923
68
+ hash: 122408225
56
69
  requirements: []
57
70
  rubyforge_project:
58
71
  rubygems_version: 1.8.11
59
72
  signing_key:
60
73
  specification_version: 3
61
- summary: fredit 0.1.0
74
+ summary: fredit 0.1.2
62
75
  test_files: []
@@ -1,121 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title><%=@path%></title>
5
- <style>
6
-
7
- body {
8
- padding-top:0;
9
- padding-bottom: 30px;
10
- font-family: Verdana, Helvetica, sans;
11
- font-size: 12px;
12
- margin-left: 40px;
13
- width: 80%;
14
- background-color: #EDEDED;
15
- }
16
- h1 {
17
- margin:0;
18
- padding:0;
19
- float:left;
20
- }
21
- h1 em {
22
- font-size: smaller;
23
- }
24
- textarea {
25
- width: 100%;
26
- height: 500px;
27
- font-family: monospace;
28
- }
29
- #notice {
30
- background-color: yellow;
31
- }
32
- input#deleteBtn {
33
- float:right;
34
- }
35
- input[type=text] {
36
- width: 100%;
37
- }
38
- table {
39
- width: 100%
40
- }
41
- form#fileSelector {
42
- float:right;
43
- }
44
- form#createFileForm {
45
- border-top: 1px solid #CCC;
46
- margin-top: 10px;
47
- padding-top: 10px;
48
- }
49
-
50
- </style>
51
- </head>
52
- <body>
53
-
54
- <% if flash[:notice] %>
55
- <div id="notice"><%= flash[:notice] %></div>
56
- <% end %>
57
-
58
- <h1>fredit <em>front-end edit</em></h1>
59
-
60
- <form id="fileSelector" action="<%=url_for%>">
61
- <select name="file">
62
- <% Fredit.editables.each_pair do |k, v| %>
63
- <optgroup label="<%= k %>">
64
- <% v.each do |path| %>
65
- <option value="<%= path %>" <%= @path == path ? 'selected=\"selected\"' : nil %>><%= Fredit.link(path)%></li>
66
- <% end %>
67
- </optgroup>
68
- <% end %>
69
- </select>
70
- <input type="submit" value="change file"/>
71
- </form>
72
-
73
- <form action="<%=url_for(:action => :update)%>" method="post">
74
- <input type="hidden" name="file" value="<%=@path%>"/>
75
- <textarea name='source'><%= @source %></textarea>
76
-
77
- <table>
78
- <tr>
79
- <td>Edit Message (optional):</td>
80
- <td>
81
- <input type="text" name="edit_message" value="" placeholder="Describe the edit " size="50"/>
82
- </td>
83
- </tr>
84
- <tr>
85
- <td>Edited By (required): </td>
86
- <td>
87
- <input type="text" name="commit_author" value="<%=session[:commit_author]%>" placeholder="Your Name <yourname@example.com>" size="50"/>
88
- </td>
89
- </tr>
90
- <tr>
91
- <td>Action:</td>
92
- <td>
93
- <input hidden="text" name="file_path" value="<%=@path%>" />
94
- <input type="submit" name="commit" value="update this file"/>
95
- <input id="deleteBtn" type="submit" name="commit" value="delete this file"/>
96
- </td>
97
- </tr>
98
- </table>
99
- </form>
100
-
101
- <form id="createFileForm" action="<%=url_for%>" method="get">
102
- <table>
103
- <tr>
104
- <td>Create file at path:</td>
105
- <td>
106
- <input type="text" name="new_path" value="" placeholder="<%=Fredit.editables[:views].first%>" size="50"/>
107
- </td>
108
- </tr>
109
- <tr>
110
- <td>Action:</td>
111
- <td>
112
- <input type="submit" name="commit" value="create file"/>
113
- </td>
114
- </tr>
115
- </table>
116
- </form>
117
-
118
-
119
-
120
- </body>
121
- </html>
@@ -1,16 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <title>test</title>
5
- <style>
6
-
7
- textarea {
8
- width: 100%;
9
- height: 400px;
10
- }
11
- </style>
12
- </head>
13
- <body>
14
- <%= yield %>
15
- </body>
16
- </html>