redsafe 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
@@ -0,0 +1,74 @@
1
+ = RedSafe Gemcutter Setup
2
+
3
+ Gem Cutter set up was more time consuming than I had anticipated. Realized that I needed: task "default" => ["test"] inside the Rakefile to have rake command work for me. Additionally, I needed to use: gem cert before I could upload to Gemcutter.
4
+
5
+ == Notes on the Red Safe Gem Creation
6
+
7
+ * 1) rake
8
+ (Needed to set a default for the task.)
9
+
10
+ Added default task to Rakefile
11
+ task "default" => ["test"]
12
+
13
+ * 2) rake gemspec
14
+ (Worked for me first time.)
15
+
16
+ Generated: redsafe.gemspec
17
+ redsafe.gemspec is valid.
18
+
19
+ * 3) rdoc
20
+ (Created documentation for the redsafe project.)
21
+
22
+ redsafe.rb: mm.m.......c...
23
+ sl_user.rb: c.....cc....
24
+ sl_aah.rb: m.m.....m..
25
+ scarlet_letters.rb: c........
26
+ version.rb: cm
27
+ Generating HTML...
28
+
29
+ Files: 5
30
+ Classes: 6
31
+ Modules: 7
32
+ Methods: 36
33
+ Elapsed: 0.593s
34
+
35
+ * 4) gem build redsafe.gemspec
36
+ (Was able to build after I took author name "Ruby Shot" from an array structure and turned it into a string by removing the brackets, [ ].
37
+
38
+ # gem build redsafe.gemspec
39
+ ERROR: While executing gem ... (Gem::InvalidSpecificationException)
40
+ authors must be Array of Strings
41
+
42
+
43
+ * 5) gem push redsafe.gem
44
+ (As mentioned above, the gem certification was not set. Thus, I couldn't get an upload to Gemcutter.)
45
+
46
+ Your api key has been stored in ~/.gem/credentials
47
+ Pushing gem to Gemcutter...
48
+ ERROR: While executing gem ... (Errno::ENOENT)
49
+ No such file or directory - redsafe.gem
50
+
51
+
52
+ * 6) gem cert --build you@yourmail.com
53
+ (Use this command to create the certification for Gemcutter. I used my email address. I also moved the Public Cert and the Private Key to a safer location.)
54
+
55
+ Public Cert: gem-public_cert.pem
56
+ Private Key: gem-private_key.pem
57
+ Don't forget to move the key file to somewhere private...
58
+
59
+
60
+ * 7)gem push redsafe-0.1.1.gem
61
+ (I was successful when I used the above command. Used the Gemcutter search and verified that redsafe was being hosted on Gemcutter. Didn't test it, but left it in place.)
62
+
63
+ Pushing gem to Gemcutter...
64
+ Successfully registered gem: redsafe (0.1.1)
65
+
66
+ == Copyright
67
+
68
+ Copyright (c) 2010 Ruby Shot. See LICENSE for details.
69
+
70
+
71
+
72
+
73
+
74
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Ruby Shot
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,13 @@
1
+ = RedSafe
2
+
3
+ The Red Safe Project deals with the creation of a gem. The gem's function is to streamline access to various websites through a connection consolidation of procedures.
4
+
5
+ == Notes on the Red Safe Project
6
+ * This Project's focus is learning based.
7
+ * It is designed to function with the appengine jruby.
8
+ * Clone it for your learning needs.
9
+ * git clone git@github.com:rubyshot/redsafe.git
10
+
11
+ == Copyright
12
+
13
+ Copyright (c) 2010 Ruby Shot. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ task "default" => ["test"]
4
+ begin
5
+ require 'jeweler'
6
+ require 'lib/redsafe/version'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "redsafe"
9
+ gem.version = Redsafe::Version::STRING
10
+ gem.description = "Red Safe is a conveyor belt to get your web-based project on a fast roll."
11
+ gem.summary = "This is a gem tool which simplifies signup functionality using various web services for connection credentials."
12
+ gem.homepage = "http://github.com/rubyshot/redsafe"
13
+ gem.author = "Ruby Shot"
14
+ gem.email = "domochoice(at)yahoo:com"
15
+ gem.add_development_dependency "sinatra"
16
+ gem.add_development_dependency "dm-core"
17
+ gem.add_development_dependency "dm-validations"
18
+ gem.add_development_dependency "dm-timestamps"
19
+ gem.add_development_dependency "date"
20
+ gem.add_development_dependency "time"
21
+ end
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
24
+ end
25
+
26
+
27
+
28
+
29
+
30
+
@@ -0,0 +1,90 @@
1
+ if Object.const_defined?("DataMapper")
2
+ #require 'dm-core'
3
+ require 'dm-timestamps'
4
+ require 'dm-validations'
5
+ require 'date'
6
+ require 'time'
7
+
8
+ require Pathname(__FILE__).dirname.expand_path + "sl_user.rb"
9
+ require Pathname(__FILE__).dirname.expand_path + "sl_aah.rb"
10
+
11
+ end
12
+
13
+ class User
14
+ if Object.const_defined?("DataMapper")
15
+ include SlAah
16
+ else
17
+ throw "'dm-core' required for red safe "
18
+ end
19
+
20
+ def initialize(interfacing_class_instance)
21
+ @instance = interfacing_class_instance
22
+ end
23
+
24
+ def id
25
+ @instance.id
26
+ end
27
+
28
+ def self.authenticate(email, pass)
29
+ current_user = get(:email => email)
30
+ return nil if current_user.nil?
31
+ return current_user if User.encrypt(pass, current_user.salt) == current_user.hashed_password
32
+ nil
33
+ end
34
+
35
+ protected
36
+
37
+ def self.encrypt(pass, salt)
38
+ Digest::SHA1.hexdigest(pass+salt)
39
+ end
40
+
41
+ def self.random_string(len)
42
+ #generate a random password consisting of strings and digits
43
+ chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
44
+ newpass = ""
45
+ 1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
46
+ return newpass
47
+ end
48
+
49
+ #Created 3 actions and terminology thereof:
50
+ #1. sist: generates a string
51
+ #2. desist: receives the sist from an authorized server and breaks it apart
52
+ #3. resist: receives the desist string and reviews its integrity
53
+
54
+ def self.sist
55
+ const_set(TIME_FMT, '%Y-%m-%dT%H:%M:%SZ')
56
+ junk = self.random_string(6)
57
+ t = Time.now.getutc
58
+ time_str = t.strftime(TIME_FMT)
59
+ the_sist_str = time_str + junk
60
+ return the_sist_str
61
+ end
62
+
63
+ def self.desist( the_sist_str )
64
+ #"0000-00-00T00:00:00Z"
65
+ const_set(TIME_STR_LEN, 20 )
66
+ const_set(TIME_VALIDATOR,"/\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ/")
67
+ timestamp_str = the_sist_str[0...TIME_STR_LEN]
68
+ raise ArgumentError if timestamp_str.size < TIME_STR_LEN
69
+ raise ArgumentError unless timestamp_str.match(TIME_VALIDATOR)
70
+ timestamp = Time.parse(timestamp_str).to_i
71
+ raise ArgumentError if ts < 0
72
+ return timestamp, the_sist_str[20..-1]
73
+ end
74
+
75
+ def self.resist(the_sist_str)
76
+ const_set(TIME_RANGE, 60*60*5)
77
+ timestamp, junk = self.desist(the_sist_str)
78
+ now = Time.now.to_i
79
+ start = now - TIME_RANGE
80
+ finish = now + TIME_RANGE
81
+ return true if (start <= timestamp and timestamp <= finish)
82
+ return false
83
+ end
84
+
85
+
86
+
87
+ end
88
+
89
+
90
+
@@ -0,0 +1,50 @@
1
+ module SlAah
2
+ def self.included(base)
3
+ base.extend ClassMethods
4
+ base.class_eval { include SlAah::InstanceMethods }
5
+ end
6
+
7
+ module ClassMethods
8
+ def all
9
+ result = SlUser.all
10
+ result.collect {|instance| self.new instance}
11
+ end
12
+
13
+ def get(hash)
14
+ if user = SlUser.first(hash)
15
+ self.new user
16
+ else
17
+ nil
18
+ end
19
+ end
20
+
21
+ def set(attributes)
22
+ user = SlUser.new attributes
23
+ user.save
24
+ user
25
+ end
26
+
27
+ def set!(attributes)
28
+ user = SlUser.new attributes
29
+ user.save!
30
+ user
31
+ end
32
+
33
+ def delete(pk)
34
+ user = User.first(:id => pk)
35
+ user.destroy
36
+ end
37
+ end
38
+
39
+ module InstanceMethods
40
+ def update(attributes)
41
+ @instance.update_attributes attributes
42
+ @instance.save
43
+ end
44
+
45
+ def method_missing(meth, *args, &block)
46
+ #cool I just found out * on an array turns the array into a list of args for a function
47
+ @instance.send(meth, *args, &block)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,119 @@
1
+ class SlUser
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :email, String, :length => (5..40), :unique => true, :format => :email_address
6
+ property :hashed_password, String
7
+ property :salt, String
8
+ property :created_at, DateTime
9
+ property :permission_level, Integer, :default => 1
10
+ property :nickname, String, :length => 255
11
+ property :identifier, String, :length => 255
12
+ property :photo_url, String, :length => 255
13
+
14
+ has n, :oohs
15
+ has n, :direct_messages, :model => "Ooh"
16
+ has n, :relationships
17
+ has n, :followers, :through => :relationships, :model => "SlUser", :child_key => [:SlUser_id]
18
+ has n, :follows, :through => :relationships, :model => "SlUser", :remote_name => :SlUser, :child_key => [:follower_id]
19
+ if Sinatra.const_defined?('FacebookObject')
20
+ property :fb_uid, String
21
+ end
22
+
23
+ attr_accessor :password, :password_confirmation
24
+ #protected equievelant? :protected => true doesn't exist in dm 0.10.0
25
+ #protected :id, :salt
26
+ #doesn't behave correctly, I'm not even sure why I did this.
27
+
28
+ validates_present :password_confirmation, :unless => Proc.new { |t| t.hashed_password }
29
+ validates_present :password, :unless => Proc.new { |t| t.hashed_password }
30
+ validates_is_confirmed :password
31
+
32
+ def password=(pass)
33
+ @password = pass
34
+ self.salt = SlUser.random_string(10) if !self.salt
35
+ self.hashed_password = SlUser.encrypt(@password, self.salt)
36
+ end
37
+
38
+ def admin?
39
+ self.permission_level == -1 || self.id == 1
40
+ end
41
+
42
+ def site_admin?
43
+ self.id == 1
44
+ end
45
+
46
+ def displayed_oohs
47
+ oohs = []
48
+ oohs += self.oohs.all(:recipient_id => nil, :limit => 10, :order => [:created_at.desc]) # don't show direct messsages
49
+ self.follows.each do |follows| oohs += follows.oohs.all(:recipient_id => nil, :limit => 10, :order => [:created_at.desc]) end if @myself == @user
50
+ oohs.sort! { |x,y| y.created_at <=> x.created_at }
51
+ oohs[0..10]
52
+ end
53
+
54
+ protected
55
+
56
+ def method_missing(m, *args)
57
+ return false
58
+ end
59
+ end
60
+ class Relationship
61
+ include DataMapper::Resource
62
+
63
+ property :SlUser_id, Integer, :key => true
64
+ property :follower_id, Integer, :key => true
65
+ belongs_to :SlUser, :child_key => [:SlUser_id]
66
+ belongs_to :follower, :model => "SlUser", :child_key => [:follower_id]
67
+ end
68
+
69
+ class Ooh
70
+ include DataMapper::Resource
71
+
72
+ property :id, Serial
73
+ property :text, String, :length => 140
74
+ property :created_at, DateTime
75
+ belongs_to :recipient, :model => "SlUser", :child_key => [:recipient_id]
76
+ belongs_to :SlUser
77
+
78
+ before :save do
79
+ case
80
+ when starts_with?('dm ')
81
+ process_dm
82
+ when starts_with?('follow ')
83
+ process_follow
84
+ else
85
+ process
86
+ end
87
+ end
88
+
89
+ # general scrubbing of an ooh
90
+ def process
91
+ # process url
92
+ urls = self.text.scan(URL_REGEXP)
93
+ urls.each { |url|
94
+ tiny_url = open("http://tinyurl.com/api-create.php?url=#{url[0]}") {|s| s.read}
95
+ self.text.sub!(url[0], "<a href='#{tiny_url}'>#{tiny_url}</a>")
96
+ }
97
+ # process @
98
+ ats = self.text.scan(AT_REGEXP)
99
+ ats.each { |at| self.text.sub!(at, "<a href='/#{at[2,at.length]}'>#{at}</a>") }
100
+ end
101
+
102
+ # process direct messages
103
+ def process_dm
104
+ self.recipient = SlUser.first(:email => self.text.split[1])
105
+ self.text = self.text.split[2..self.text.split.size].join(' ') # remove the first 2 words
106
+ process
107
+ end
108
+
109
+ # process follow commands
110
+ def process_follow
111
+ Relationship.create(:SlUser => SlUser.first(:email => self.text.split[1]), :follower => self.SlUser)
112
+ throw :halt # don't save
113
+ end
114
+
115
+ def starts_with?(prefix)
116
+ prefix = prefix.to_s
117
+ self.text[0, prefix.length] == prefix
118
+ end
119
+ end
@@ -0,0 +1,9 @@
1
+ class Redsafe
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ PATCH = 5
6
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
+ end
8
+ end
9
+
data/lib/redsafe.rb ADDED
@@ -0,0 +1,268 @@
1
+ require 'sinatra/base'
2
+ require 'pathname'
3
+ require Pathname(__FILE__).dirname.expand_path + "models/scarlet_letters"
4
+
5
+ module Sinatra
6
+ module RedSlash
7
+ def self.registered(app)
8
+ #INVESTIGATE
9
+ #the possibility of sinatra having an array of view_paths to load from
10
+ #PROBLEM
11
+ #sinatra 9.1.1 doesn't have multiple view capability anywhere
12
+ #so to get around I have to do it totally manually by
13
+ #loading the view from this path into a string and rendering it
14
+ set :red_slash_view_path, Pathname(__FILE__).dirname.expand_path + "views/"
15
+
16
+ get '/users' do
17
+ login_required
18
+ redirect "/" unless current_user.admin?
19
+
20
+ @users = User.all
21
+ if @users != []
22
+ haml get_view_as_string("index.haml"), :layout => use_layout?
23
+ else
24
+ redirect '/signup'
25
+ end
26
+ end
27
+
28
+ get '/users/:id' do
29
+ login_required
30
+
31
+ @user = User.get(:id => params[:id])
32
+ haml get_view_as_string("show.haml"), :layout => use_layout?
33
+ end
34
+
35
+ #convenience for ajax but maybe entirely stupid and unnecesary
36
+ get '/logged_in' do
37
+ if session[:user]
38
+ "true"
39
+ else
40
+ "false"
41
+ end
42
+ end
43
+
44
+ get '/login' do
45
+ haml get_view_as_string("login.haml"), :layout => use_layout?
46
+ end
47
+
48
+ post '/login' do
49
+ if user = User.authenticate(params[:email], params[:password])
50
+ session[:user] = user.id
51
+ if session[:return_to]
52
+ redirect_url = session[:return_to]
53
+ session[:return_to] = false
54
+ redirect redirect_url
55
+ else
56
+ redirect '/'
57
+ end
58
+ else
59
+ redirect '/login'
60
+ end
61
+ end
62
+
63
+ get '/logout' do
64
+ session[:user] = nil
65
+ @message = "in case it weren't obvious, you've logged out"
66
+ redirect '/'
67
+ end
68
+
69
+ get '/signup' do
70
+ haml get_view_as_string("signup.haml"), :layout => use_layout?
71
+ end
72
+
73
+ post '/signup' do
74
+ @user = User.set(params[:user])
75
+ if @user
76
+ session[:user] = @user.id
77
+ redirect '/'
78
+ else
79
+ session[:flash] = "failure!"
80
+ redirect '/'
81
+ end
82
+ end
83
+
84
+ get '/users/:id/edit' do
85
+ login_required
86
+ redirect "/users" unless current_user.admin? || current_user.id.to_s == params[:id]
87
+
88
+ @user = User.get(:id => params[:id])
89
+ haml get_view_as_string("edit.haml"), :layout => use_layout?
90
+ end
91
+
92
+ post '/users/:id/edit' do
93
+ login_required
94
+ redirect "/users" unless current_user.admin? || current_user.id.to_s == params[:id]
95
+
96
+ user = User.get(:id => params[:id])
97
+ user_attributes = params[:user]
98
+ if params[:user][:password] == ""
99
+ user_attributes.delete("password")
100
+ user_attributes.delete("password_confirmation")
101
+ end
102
+
103
+ if user.update(user_attributes)
104
+ redirect '/'
105
+ else
106
+ session[:notice] = 'whoops, looks like there were some problems with your updates'
107
+ redirect "/users/#{user.id}/edit"
108
+ end
109
+ end
110
+
111
+ get '/users/:id/delete' do
112
+ login_required
113
+ redirect "/users" unless current_user.admin? || current_user.id.to_s == params[:id]
114
+
115
+ if User.delete(params[:id])
116
+ session[:flash] = "way to go, you deleted a user"
117
+ else
118
+ session[:flash] = "deletion failed, for whatever reason"
119
+ end
120
+ redirect '/'
121
+ end
122
+
123
+
124
+ if Sinatra.const_defined?('FacebookObject')
125
+ get '/connect' do
126
+ if fb[:user]
127
+ if current_user.class != GuestUser
128
+ user = current_user
129
+ else
130
+ user = User.get(:fb_uid => fb[:user])
131
+ end
132
+
133
+ if user
134
+ if !user.fb_uid || user.fb_uid != fb[:user]
135
+ user.update :fb_uid => fb[:user]
136
+ end
137
+ session[:user] = user.id
138
+ else
139
+ user = User.set!(:fb_uid => fb[:user])
140
+ session[:user] = user.id
141
+ end
142
+ end
143
+ redirect '/'
144
+ end
145
+
146
+ get '/receiver' do
147
+ %[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
148
+ <html xmlns="http://www.w3.org/1999/xhtml" >
149
+ <body>
150
+ <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.js" type="text/javascript"></script>
151
+ </body>
152
+ </html>]
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ module Helpers
159
+ def login_required
160
+ #not as efficient as checking the session. but this inits the fb_user if they are logged in
161
+ if current_user.class != GuestUser
162
+ return true
163
+ else
164
+ session[:return_to] = request.fullpath
165
+ redirect '/login'
166
+ return false
167
+ end
168
+ end
169
+
170
+ def current_user
171
+ if session[:user]
172
+ User.get(:id => session[:user])
173
+ else
174
+ GuestUser.new
175
+ end
176
+ end
177
+
178
+ def logged_in?
179
+ !!session[:user]
180
+ end
181
+
182
+ def use_layout?
183
+ !request.xhr?
184
+ end
185
+
186
+ #BECAUSE sinatra 9.1.1 can't load views from different paths properly
187
+ def get_view_as_string(filename)
188
+ view = options.red_slash_view_path + filename
189
+ data = ""
190
+ f = File.open(view, "r")
191
+ f.each_line do |line|
192
+ data += line
193
+ end
194
+ return data
195
+ end
196
+
197
+ def render_login_logout(html_attributes = {:class => ""})
198
+ css_classes = html_attributes.delete(:class)
199
+ parameters = ''
200
+ html_attributes.each_pair do |attribute, value|
201
+ parameters += "#{attribute}=\"#{value}\" "
202
+ end
203
+
204
+ result = "<div id='sinatra-authentication-login-logout' >"
205
+ if logged_in?
206
+ logout_parameters = html_attributes
207
+ # a tad janky?
208
+ logout_parameters.delete(:rel)
209
+ result += "<a href='/users/#{current_user.id}/edit' class='#{css_classes} sinatra-authentication-edit' #{parameters}>Edit account</a> "
210
+ if Sinatra.const_defined?('FacebookObject')
211
+ if fb[:user]
212
+ result += "<a href='javascript:FB.Connect.logoutAndRedirect(\"/logout\");' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>Logout</a>"
213
+ else
214
+ result += "<a href='/logout' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>Logout</a>"
215
+ end
216
+ else
217
+ result += "<a href='/logout' class='#{css_classes} sinatra-authentication-logout' #{logout_parameters}>Logout</a>"
218
+ end
219
+ else
220
+ result += "<a href='/signup' class='#{css_classes} sinatra-authentication-signup' #{parameters}>Signup</a> "
221
+ result += "<a href='/login' class='#{css_classes} sinatra-authentication-login' #{parameters}>Login</a>"
222
+ end
223
+
224
+ result += "</div>"
225
+ end
226
+
227
+ if Sinatra.const_defined?('FacebookObject')
228
+ def render_facebook_connect_link(text = 'Login using facebook', options = {:size => 'small'})
229
+ if options[:size] == 'small'
230
+ size = 'Small'
231
+ elsif options[:size] == 'medium'
232
+ size = 'Medium'
233
+ elsif options[:size] == 'large'
234
+ size = 'Large'
235
+ elsif options[:size] == 'xlarge'
236
+ size = 'BigPun'
237
+ else
238
+ size = 'Small'
239
+ end
240
+
241
+ %[<a href="#" onclick="FB.Connect.requireSession(function(){document.location = '/connect';}); return false;" class="fbconnect_login_button FBConnectButton FBConnectButton_#{size}">
242
+ <span id="RES_ID_fb_login_text" class="FBConnectButton_Text">
243
+ #{text}
244
+ </span>
245
+ </a>]
246
+ end
247
+ end
248
+ end
249
+
250
+ register RedSlash
251
+ end
252
+
253
+ class GuestUser
254
+ def guest?
255
+ true
256
+ end
257
+
258
+ def permission_level
259
+ 0
260
+ end
261
+
262
+ # current_user.admin? returns false. current_user.has_a_baby? returns false.
263
+ # (which is a bit of an assumption I suppose)
264
+ def method_missing(m, *args)
265
+ return false
266
+ end
267
+ end
268
+
@@ -0,0 +1,42 @@
1
+ #redsafe
2
+ %h1
3
+ Edit
4
+ - if @user.id == current_user.id
5
+ account
6
+ - else
7
+ - if @user.email
8
+ = @user.email
9
+ - elsif @user.fb_uid
10
+ <fb:name uid=#{@user.fb_uid} linked='false' />
11
+ - else
12
+ account
13
+ %form{:action => "/users/#{@user.id}/edit", :method => "post"}
14
+ .field
15
+ .label
16
+ %label{:for => "user_email"} Email
17
+ %input{ :id => "user_email", :name => "user[email]", :size => 30, :type => "text", :value => @user.email }
18
+ .field
19
+ .label
20
+ %label{:for => "user_password"} New password
21
+ %input{ :id => "user_password", :name => "user[password]", :size => 30, :type => "password" }
22
+ .field
23
+ .label
24
+ %label{:for => "user_password_confirmation"} Confirm
25
+ %input{ :id => "user_password_confirmation", :name => "user[password_confirmation]", :size => 30, :type => "password" }
26
+ -# don't render permission field if admin and editing yourself so you don't shoot yourself in the foot
27
+ - if current_user.admin? && current_user.id != @user.id
28
+ .field
29
+ .label
30
+ %label{:for => 'permission_level'} Permission level
31
+ %select{ :id => "permission_level", :name => "user[permission_level]" }
32
+ %option{:value => -1, :selected => @user.admin?}
33
+ Admin
34
+ %option{:value => 1, :selected => @user.permission_level == 1}
35
+ Authenticated user
36
+ .buttons
37
+ %input{ :value => "Update", :type => "submit" }
38
+ - if Sinatra.const_defined?('FacebookObject')
39
+ - unless @user.fb_uid
40
+ |
41
+ = render_facebook_connect_link('Link account with Facebook')
42
+
@@ -0,0 +1,30 @@
1
+ #redsafe
2
+ %h1.page_title Users
3
+ %table
4
+ %tr
5
+ %th
6
+ - if current_user.admin?
7
+ %th permission level
8
+ - @users.each do |user|
9
+ %tr
10
+ %td
11
+ - if user.email
12
+ = user.email
13
+ - elsif user.fb_uid
14
+ <fb:name uid=#{user.fb_uid} />
15
+ - else
16
+ "user #{user.id}"
17
+ - if current_user.admin?
18
+ %td= user.permission_level
19
+ %td
20
+ %a{:href => "/users/#{user.id}"} show
21
+ - if current_user.admin?
22
+ %td
23
+ %a{:href => "/users/#{user.id}/edit"} edit
24
+ %td
25
+ -# this doesn't work for tk
26
+ - if !user.site_admin?
27
+ %a{:href => "/users/#{user.id}/delete", :onclick => "return confirm('you sure?')"} delete
28
+ - else
29
+ site admin
30
+
@@ -0,0 +1,21 @@
1
+ #redsafe
2
+ %h1.page_title Login
3
+ %form{:action => "/login", :method => "post"}
4
+ .field
5
+ .label
6
+ %label{:for => "user_email'"} Email
7
+ %input{:id => "user_email", :name => "email", :size => 30, :type => "text"}
8
+ .field
9
+ .label
10
+ %label{:for => "user_password"} Password
11
+ %input{:id => "user_password", :name => "password", :size => 30, :type => "password"}
12
+ .buttons
13
+ %input{:value => "login", :type => "submit"}
14
+ %a{:href => "/signup", :class => 'sinatra_authentication_link'}
15
+ Signup
16
+ - if Sinatra.const_defined?('FacebookObject')
17
+ .third_party_signup
18
+ %h3.section_title One click login:
19
+ .login_link.facebook_login
20
+ = render_facebook_connect_link('Login using facebook', :size => 'large')
21
+
@@ -0,0 +1,10 @@
1
+ #redsafe
2
+ %h1.page_title
3
+ - if @user.email
4
+ = @user.email
5
+ - elsif @user.fb_uid
6
+ <fb:name uid=#{@user.fb_uid} linked='false' />
7
+ - if current_user.admin?
8
+ %h2 permission level
9
+ = @user.permission_level
10
+
@@ -0,0 +1,25 @@
1
+ #redsafe
2
+ %h1.page_title Signup
3
+ %form{:action => "/signup", :method => "post"}
4
+ .field
5
+ .label
6
+ %label{:for => "user_email"} Email
7
+ %input{ :id => "user_email", :name => "user[email]", :size => 30, :type => "text" }
8
+ .field
9
+ .label
10
+ %label{:for => "user_password"} Password
11
+ %input{ :id => "user_password", :name => "user[password]", :size => 30, :type => "password" }
12
+ .field
13
+ .label
14
+ %label{:for => "user_password_confirmation"} Confirm Password
15
+ %input{ :id => "user_password_confirmation", :name => "user[password_confirmation]", :size => 30, :type => "password" }
16
+ .buttons
17
+ %input{ :value => "Create account", :type => "submit" }
18
+ %a{:href => "/login", :class => 'sinatra_authentication_link'}
19
+ Login
20
+ - if Sinatra.const_defined?('FacebookObject')
21
+ .third_party_signup
22
+ %h3.section_title One click signup:
23
+ .login_link.facebook_login
24
+ = render_facebook_connect_link('Signup using facebook', :size => 'large')
25
+
@@ -0,0 +1,7 @@
1
+ require 'test_helper'
2
+
3
+ class RedsafeTest < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'redsafe'
8
+
9
+ class Test::Unit::TestCase
10
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: redsafe
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ platform: ruby
6
+ authors:
7
+ - Ruby Shot
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-12 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: dm-core
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: dm-validations
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: dm-timestamps
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: date
57
+ type: :development
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: time
67
+ type: :development
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ description: Red Safe is a conveyor belt to get your web-based project on a fast roll.
76
+ email: domochoice(at)yahoo:com
77
+ executables: []
78
+
79
+ extensions: []
80
+
81
+ extra_rdoc_files:
82
+ - LICENSE
83
+ - README.rdoc
84
+ files:
85
+ - .document
86
+ - .gitignore
87
+ - GemcutterInstructions.rdoc
88
+ - LICENSE
89
+ - README.rdoc
90
+ - Rakefile
91
+ - lib/models/scarlet_letters.rb
92
+ - lib/models/sl_aah.rb
93
+ - lib/models/sl_user.rb
94
+ - lib/redsafe.rb
95
+ - lib/redsafe/version.rb
96
+ - lib/views/edit.haml
97
+ - lib/views/index.haml
98
+ - lib/views/login.haml
99
+ - lib/views/show.haml
100
+ - lib/views/signup.haml
101
+ - test/redsafe_test.rb
102
+ - test/test_helper.rb
103
+ has_rdoc: true
104
+ homepage: http://github.com/rubyshot/redsafe
105
+ licenses: []
106
+
107
+ post_install_message:
108
+ rdoc_options:
109
+ - --charset=UTF-8
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: "0"
117
+ version:
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: "0"
123
+ version:
124
+ requirements: []
125
+
126
+ rubyforge_project:
127
+ rubygems_version: 1.3.5
128
+ signing_key:
129
+ specification_version: 3
130
+ summary: This is a gem tool which simplifies signup functionality using various web services for connection credentials.
131
+ test_files:
132
+ - test/redsafe_test.rb
133
+ - test/test_helper.rb