22 Commits
hslweb ... ipn

Author SHA1 Message Date
69a57bc63b Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn 2013-08-28 03:19:09 -07:00
c662be6dc0 IPN improvements 2013-08-28 03:18:47 -07:00
ca7808a525 Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn 2013-08-27 23:06:43 -07:00
9fb2507aa1 Updating coin 2013-08-27 23:06:16 -07:00
0be2834a5d Minor status tweak 2013-08-27 00:39:43 -07:00
ef46bf6a98 Adjusting ranking method 2013-08-27 00:09:54 -07:00
45bac6cae4 Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn 2013-08-26 23:40:40 -07:00
4dba2b8c3d Adding status symbols 2013-08-26 23:39:54 -07:00
18bc427eb3 Adding quick-add buttons to user profiles 2013-08-26 23:01:43 -07:00
810ff6b034 De-duplicating cert view 2013-08-26 22:32:08 -07:00
ae031838dc Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn 2013-08-26 22:15:54 -07:00
59b6e3c838 Updating nav 2013-08-26 22:12:45 -07:00
98be42e9f9 Fixing nil errors 2013-08-26 22:11:04 -07:00
b5d9514914 Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn 2013-08-26 22:09:37 -07:00
125ad76a1c Hacks to allow 1.8.7 2013-08-26 22:07:41 -07:00
4067477cd4 Updating icons, fixing user cert nil error 2013-08-26 22:05:53 -07:00
9e4b79a353 Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn 2013-08-26 15:39:18 -07:00
f8f11e3d7e Adjust IPN security 2013-08-26 15:34:10 -07:00
805148ee40 Merge branch 'ipn' of github.com:zyphlar/Open-Source-Access-Control-Web-Interface into ipn 2013-08-24 03:44:00 -07:00
f111769b20 Remove debug, update schema 2013-08-24 03:43:43 -07:00
eb782f11d5 Adding IPN validation 2013-08-24 03:40:34 -07:00
ec4cf4dea9 Adding IPNs 2013-08-24 02:18:37 -07:00
47 changed files with 586 additions and 99 deletions

View File

@@ -1,5 +1,7 @@
source 'https://rubygems.org' source 'https://rubygems.org'
#ruby '1.9.3'
gem 'rails', '3.2.3' gem 'rails', '3.2.3'
# Bundle edge Rails instead: # Bundle edge Rails instead:
@@ -40,7 +42,7 @@ gem 'bcrypt-ruby', '~> 3.0.0'
# gem 'capistrano' # gem 'capistrano'
# To use debugger # To use debugger
# gem 'ruby-debug' #gem 'debugger'
#gem "paperclip", "~> 3.0" #gem "paperclip", "~> 3.0"
gem 'gravtastic' gem 'gravtastic'

View File

@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -12,3 +12,37 @@
*= require_tree . *= require_tree .
*/ */
.caption { display: inline-block; background-color: #eee; border: 1px solid #333; border-radius: 5px; margin-bottom: 1em; } .caption { display: inline-block; background-color: #eee; border: 1px solid #333; border-radius: 5px; margin-bottom: 1em; }
.btn {
display: inline-block;
padding: 4px 10px 4px;
margin-bottom: 0;
font-size: 13px;
line-height: 18px;
color: #333;
text-align: center;
text-decoration: none;
text-shadow: 0 1px 1px rgba(255,255,255,.75);
vertical-align: middle;
background-color: #f5f5f5;
background-image: -moz-linear-gradient(top, #fff, #e6e6e6);
background-image: -ms-linear-gradient(top, #fff, #e6e6e6);
background-image: -webkit-gradient(linear,0 0,0 100%,from( #fff),to( #e6e6e6));
background-image: -webkit-linear-gradient(top, #fff, #e6e6e6);
background-image: -o-linear-gradient(top, #fff, #e6e6e6);
background-image: linear-gradient(top, #fff, #e6e6e6);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
border-color: rgba(0,0,0,.1) rgba(0,0,0,.1) rgba(0,0,0,.25);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
border: 1px solid #ccc;
border-bottom-color: #bbb;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
box-shadow: inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);
cursor: pointer;
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}

View File

@@ -0,0 +1,3 @@
// Place all the styles related to the Ipn controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@@ -0,0 +1,54 @@
class IpnsController < ApplicationController
load_and_authorize_resource :ipn, :except => [:new, :create]
before_filter :authenticate_user!, :except => [:new, :create]
protect_from_forgery :except => [:create]
def index
@ipns = Ipn.all
end
def show
end
def new
end
def create
@ipn = Ipn.new_from_dynamic_params(params)
@ipn.data = params.to_json
@ipn.save
render :nothing => true
#unless @ipn.validate!
# Rails.logger.error "Unable to validate IPN: #{@ipn.inspect}"
#end
end
def import
@ipn = Ipn.new_from_dynamic_params(params)
@ipn.data = params.to_json
@ipn.save
redirect_to ipn_path(@ipn)
#unless @ipn.validate!
# Rails.logger.error "Unable to validate IPN: #{@ipn.inspect}"
#end
end
def validate
if @ipn.validate!
redirect_to ipns_url, :notice => 'Valid!'
else
redirect_to ipns_url, :notice => 'INVALID'
end
end
def link
result = @ipn.link_payment
if result.first
redirect_to ipns_url, :notice => 'Payment was successfully linked.'
else
redirect_to ipns_url, :notice => result.last
end
end
end

View File

@@ -1,5 +1,15 @@
class MacsController < ApplicationController class MacsController < ApplicationController
load_and_authorize_resource :mac, :except => [:index, :scan, :import] rescue_from CanCan::AccessDenied do |exception|
today = Date.today
event = Date.new(2013,9,1)
if today == event
redirect_to main_app.root_url, :alert => "CryptoParty today; no MAC scanning. Sorry, NSA!"
else
redirect_to main_app.root_url, :alert => "Nothing to see here!"
end
end
load_and_authorize_resource :mac
load_and_authorize_resource :user, :through => :mac, :except => [:index, :show, :scan, :import] load_and_authorize_resource :user, :through => :mac, :except => [:index, :show, :scan, :import]
#require "active_record" #require "active_record"

View File

@@ -6,7 +6,7 @@ class UserCertificationsController < ApplicationController
# Load users and certs based on current ability # Load users and certs based on current ability
before_filter :only => [:new, :edit, :create, :update] do before_filter :only => [:new, :edit, :create, :update] do
@users = User.where(:hidden => false).accessible_by(current_ability).sort_by(&:name) @users = User.where(:hidden => [false,nil]).accessible_by(current_ability).sort_by(&:name)
@certifications = Certification.accessible_by(current_ability).sort_by(&:name) @certifications = Certification.accessible_by(current_ability).sort_by(&:name)
end end

View File

@@ -69,7 +69,7 @@ class UsersController < ApplicationController
def create def create
respond_to do |format| respond_to do |format|
if @user.save if @user.save
format.html { redirect_to users_url, :notice => 'User was successfully created.' } format.html { redirect_to @user, :notice => 'User was successfully created.' }
format.json { render :json => @user, :status => :created, :location => @user } format.json { render :json => @user, :status => :created, :location => @user }
else else
format.html { render :action => "new" } format.html { render :action => "new" }
@@ -83,7 +83,7 @@ class UsersController < ApplicationController
def update def update
respond_to do |format| respond_to do |format|
if @user.update_attributes(params[:user]) if @user.update_attributes(params[:user])
format.html { redirect_to users_url, :notice => 'User was successfully updated.' } format.html { redirect_to @user, :notice => 'User was successfully updated.' }
format.json { head :no_content } format.json { head :no_content }
else else
format.html { render :action => "edit" } format.html { render :action => "edit" }

View File

@@ -0,0 +1,2 @@
module IpnHelper
end

View File

@@ -3,14 +3,20 @@ class Ability
def initialize(user) def initialize(user)
# Anonymous can read mac # Anonymous can read mac
today = Date.today
event = Date.new(2013,9,1)
unless today == event
can :read, Mac can :read, Mac
can :scan, Mac # Need anonymous so CRON can scan
end
if !user.nil? if !user.nil?
# By default, users can only see their own stuff # By default, users can only see their own stuff
can :read, Card, :user_id => user.id can :read, Card, :user_id => user.id
can :read, Certification can :read, Certification
can :read_details, Mac can :read_details, Mac unless today == event
can [:update], Mac, :user_id => nil can [:update], Mac, :user_id => nil
can [:create,:update], Mac, :user_id => user.id can [:create,:update], Mac, :user_id => user.id
can :read, User, :id => user.id #TODO: why can users update themselves? can :read, User, :id => user.id #TODO: why can users update themselves?

View File

@@ -2,6 +2,7 @@ class Card < ActiveRecord::Base
require 'open-uri' require 'open-uri'
attr_accessible :id, :user_id, :name, :card_number, :card_permissions attr_accessible :id, :user_id, :name, :card_number, :card_permissions
validates_presence_of :user_id, :card_number, :card_permissions
validates_uniqueness_of :id, :card_number validates_uniqueness_of :id, :card_number
belongs_to :user belongs_to :user

86
app/models/ipn.rb Normal file
View File

@@ -0,0 +1,86 @@
require 'net/http'
class Ipn < ActiveRecord::Base
attr_accessible :data
belongs_to :payment
after_create :create_payment
def self.new_from_dynamic_params(params)
ipn = Ipn.new()
ipn.attributes.each do |c|
unless params[c.first.to_sym].nil?
ipn[c.first.to_sym] = params[c.first.to_sym]
end
end
return ipn
end
# Post back to Paypal to make sure it's valid
def validate!
uri = URI.parse('https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate')
http = Net::HTTP.new(uri.host, uri.port)
http.open_timeout = 60
http.read_timeout = 60
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.use_ssl = true
response = http.post(uri.request_uri, self.data,
'Content-Length' => "#{self.data.size}",
'User-Agent' => "Ruby on Rails"
).body
unless ["VERIFIED", "INVALID"].include?(response)
Rails.logger.error "Faulty paypal result: #{response}"
return false
end
unless response == "VERIFIED"
Rails.logger.error "Invalid IPN: #{response}"
return false
end
return true
end
def link_payment
create_payment
end
private
def create_payment
# find user by email, then by payee
user = User.find_by_email(self.payer_email)
user = User.find_by_payee(self.payer_email) if user.nil? && self.payer_email.present?
# Only create payments if the IPN matches a member
if user.present?
# And is a payment (not a cancellation, etc)
payment_types = ["subscr_payment","send_money"]
if payment_types.include?(self.txn_type)
# And a member level
if User.member_levels[self.payment_gross.to_i].present?
payment = Payment.new
payment.date = Date.strptime(self.payment_date, "%H:%M:%S %b %e, %Y %Z")
payment.user_id = user.id
payment.amount = self.payment_gross
if payment.save
self.payment_id = payment.id
self.save!
else
return [false, "Unable to link payment. Payment error: #{payment.errors.full_messages.first}"]
end
else
return [false, "Unable to link payment. Couldn't find membership level '#{self.payment_gross.to_i}'."]
end
else
return [false, "Unable to link payment. Transaction is a '#{self.txn_type}' instead of '#{payment_types.inspect}'."]
end
else
return [false, "Unable to link payment. Couldn't find user/payee '#{self.payer_email}'."]
end
return [true]
end
end

View File

@@ -1,10 +1,12 @@
class Payment < ActiveRecord::Base class Payment < ActiveRecord::Base
belongs_to :user belongs_to :user
attr_accessible :date, :user_id, :created_by has_one :ipn
attr_accessible :date, :user_id, :created_by, :amount
validates_presence_of :user_id, :date, :created_by validates_presence_of :user_id, :date, :amount # not created_by
validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.' validates_uniqueness_of :date, :scope => :user_id, :message => ' of payment already exists for this user.'
def human_date def human_date
if date.year < DateTime.now.year if date.year < DateTime.now.year
date.strftime("%b %e, %y") date.strftime("%b %e, %y")

View File

@@ -85,72 +85,80 @@ class User < ActiveRecord::Base
end end
end end
def self.member_levels
{25 => "Associate", 50 => "Basic", 75 => "Basic", 100 => "Plus"}
end
def member_status def member_status
case self.member_level.to_i results = member_status_calculation
when 0 return results[:rank]
if self.payments.count > 0 then
2
else
-1
end
when 1
1
when 10..24
10
when 25..999
if self.payments.count > 0 then
if self.payments.last.date < (DateTime.now - 45.days)
3
else
case self.member_level.to_i
when 25..49
25
when 50..99
50
when 100..999
100
end
end
else
return 0
end
end
end end
def member_status_symbol def member_status_symbol
case self.member_level.to_i results = member_status_calculation
when 0 return "<img src='/#{results[:icon]}#{results[:flair]}-coin.png' title='#{results[:message]}' />"
if self.payments.count > 0 then
"<span class='hoverinfo' title='Former Member (#{(DateTime.now - self.payments.last.date).to_i} days ago)'>:(</span>"
else
"<!-- Not a member -->"
end
when 1
"Unable"
when 10..24
"<span class='hoverinfo' title='Volunteer'>&#9684;</span>"
when 25..999
if self.payments.count > 0 then
if self.payments.last.date < (DateTime.now - 45.days)
"<span class='hoverinfo' title='Recently Lapsed (#{(DateTime.now - self.payments.last.date).to_i} days ago)'>&#9676;</span>"
else
case self.member_level.to_i
when 25..49
"<span class='hoverinfo' title='#{member_level_string}'>&#9681;</span>"
when 50..99
"<span class='hoverinfo' title='#{member_level_string}'>&#9685;</span>"
when 100..999
"<span class='hoverinfo' title='#{member_level_string}'>&#9679;</span>"
end
end
else
"<span class='hoverinfo' title='No Payments'>?</span>"
end
end
end end
private private
def member_status_calculation
# Begin output buffer
message = ""
icon = ""
flair = ""
rank = 0
# First status item is level
case self.member_level.to_i
when 0..9
if self.payments.count > 0 then
message = "Former Member (#{(DateTime.now - self.payments.last.date).to_i} days ago)"
icon = :timeout
rank = 1
else
message = "Not a Member"
icon = :no
rank = 0
end
when 10..24
message = "Volunteer"
icon = :heart
rank = 101
when 25..49
message = member_level_string
icon = :copper
rank = 250
when 50..99
message = member_level_string
icon = :silver
rank = 500
when 100..999
message = member_level_string
icon = :gold
rank = 1000
end
# Second status item is payment status
case self.member_level.to_i
when 25..999
# There are payments
if self.payments.count > 0 then
# They're on time
if self.payments.last.date > (DateTime.now - 60.days)
flair = "-paid"
else
message = "Last Payment #{(DateTime.now - self.payments.last.date).to_i/30} months ago"
rank = rank/10
end
else
message = "No Payments Recorded"
rank = rank/10
end
end
return {:message => message, :icon => icon, :flair => flair, :rank => rank}
end
def send_new_user_email def send_new_user_email
Rails.logger.info UserMailer.new_user_email(self).deliver Rails.logger.info UserMailer.new_user_email(self).deliver
end end

View File

@@ -1,16 +1,17 @@
class UserCertification < ActiveRecord::Base class UserCertification < ActiveRecord::Base
attr_accessible :certification_id, :user_id attr_accessible :certification_id, :user_id
validates_presence_of :certification_id, :user_id
validates_uniqueness_of :certification_id, :scope => :user_id, :message => 'already exists for this user.' # Makes sure users don't get certified twice validates_uniqueness_of :certification_id, :scope => :user_id, :message => 'already exists for this user.' # Makes sure users don't get certified twice
belongs_to :user belongs_to :user
belongs_to :certification belongs_to :certification
def user_name def user_name
if user.blank? if self.user.blank?
return "n/a (user ##{user_id} missing)" ""
else else
return self.user.name self.user.name
end end
end end
end end

View File

@@ -11,9 +11,10 @@
</div> </div>
<% end %> <% end %>
<% @card.user_id = params[:user] if params[:user].present? %>
<div class="field"> <div class="field">
<%= f.label :user %><br /> <%= f.label :user %><br />
<%= collection_select(:card, :user_id, User.all.sort_by(&:name), :id, :name) %> <%= collection_select(:card, :user_id, User.all.sort_by(&:name), :id, :name, :include_blank => true) %>
</div> </div>
<div class="field"> <div class="field">
<%= f.label :name, "Card Note" %><br /> <%= f.label :name, "Card Note" %><br />

View File

@@ -8,13 +8,10 @@
<%= simple_format @certification.description %> <%= simple_format @certification.description %>
</p> </p>
<p>
<b>Certified Users:</b> <b>Certified Users:</b>
<ul> <%= link_to "Click Here", user_certifications_path %>
<% @certification_users.each do |user| %> </p>
<li><%= link_to user.name, user %></li>
<% end %>
<% if @certification_users.blank? then %><li>n/a</li><% end %>
</ul>
<% if can? :update, @certification %><%= link_to 'Edit', edit_certification_path(@certification) %> |<% end %> <% if can? :update, @certification %><%= link_to 'Edit', edit_certification_path(@certification) %> |<% end %>
<%= link_to 'Back', certifications_path %> <%= link_to 'Back', certifications_path %>

View File

@@ -0,0 +1,33 @@
<html><body>
<table>
<tr>
<th>Date</th>
<th>Name</th>
<th>Item</th>
<th>Amount</th>
</tr>
<% @ipns.reverse!.each do |ipn| %>
<tr>
<td><%= ipn.payment_date %></td>
<td><%= ipn.first_name %> <%= ipn.last_name %></td>
<td><%= ipn.item_name %></td>
<td>
<% if ipn.payment_gross.blank? %>
<%= ipn.txn_type %>
<% else %>
<%= ipn.payment_gross %>
<% end %>
</td>
<td>
<% if ipn.payment.present? %>
<%= link_to "Linked Payment", ipn.payment %>
<% else %>
<%= link_to "Try to link email '#{ipn.payer_email}' at membership level '#{ipn.payment_gross.to_i}'", link_ipn_path(ipn) %>
<% end %>
</td>
<td><%= link_to "Details", ipn %></td>
<td><%= link_to "Validate", validate_ipn_path(ipn) %></td>
</tr>
<% end %>
</table>
</body></html>

123
app/views/ipns/new.html.erb Normal file
View File

@@ -0,0 +1,123 @@
<%= form_tag('/ipns') do |f| %>
<style type="text/css">
label {
width: 10em;
display: inline-block;}
</style>
<div class="actions">
<%= submit_tag %>
</div>
<div class="field">
<%= label_tag :first_name %>
<%= text_field_tag :first_name, "John" %>
</div>
<div class="field">
<%= label_tag :last_name %>
<%= text_field_tag :last_name, "Smith" %>
</div>
<div class="field">
<%= label_tag :payer_email %>
<%= text_field_tag :payer_email, "jsmith@example.com" %>
</div>
<div class="field">
<%= label_tag :item_name %>
<%= text_field_tag :item_name, "Associate Membership" %>
</div>
<div class="field">
<%= label_tag :payment_gross %>
<%= text_field_tag :payment_gross, "25.00" %>
</div>
<div class="field">
<%= label_tag :transaction_subject %>
<%= text_field_tag :transaction_subject, "" %>
</div>
<div class="field">
<%= label_tag :payment_date %>
<%= text_field_tag :payment_date, "20:46:54 Jun 20, 2013 PDT" %>
</div>
<div class="field">
<%= label_tag :txn_type %>
<%= text_field_tag :txn_type, "subscr_payment" %>
</div>
<div class="field">
<%= label_tag :subscr_id %>
<%= text_field_tag :subscr_id, "I-1234567890" %>
</div>
<div class="field">
<%= label_tag :residence_country %>
<%= text_field_tag :residence_country, "US" %>
</div>
<div class="field">
<%= label_tag :mc_currency %>
<%= text_field_tag :mc_currency, "USD" %>
</div>
<div class="field">
<%= label_tag :business %>
<%= text_field_tag :business, "hslfinances@gmail.com" %>
</div>
<div class="field">
<%= label_tag :payment_type %>
<%= text_field_tag :payment_type, "instant" %>
</div>
<div class="field">
<%= label_tag :protection_eligibility %>
<%= text_field_tag :protection_eligibility, "Ineligible" %>
</div>
<div class="field">
<%= label_tag :verify_sign %>
<%= text_field_tag :verify_sign, "12ru9021j9f21j90fj1290fj2910fj0219fj0" %>
</div>
<div class="field">
<%= label_tag :payer_status %>
<%= text_field_tag :payer_status, "verified" %>
</div>
<div class="field">
<%= label_tag :txn_id %>
<%= text_field_tag :txn_id, "1234567890" %>
</div>
<div class="field">
<%= label_tag :receiver_email %>
<%= text_field_tag :receiver_email, "hslfinances@gmail.com" %>
</div>
<div class="field">
<%= label_tag :payer_id %>
<%= text_field_tag :payer_id, "V812314914" %>
</div>
<div class="field">
<%= label_tag :receiver_id %>
<%= text_field_tag :receiver_id, "V90R1280182" %>
</div>
<div class="field">
<%= label_tag :payment_status %>
<%= text_field_tag :payment_status, "Completed" %>
</div>
<div class="field">
<%= label_tag :payment_fee %>
<%= text_field_tag :payment_fee, "0.85" %>
</div>
<div class="field">
<%= label_tag :mc_fee %>
<%= text_field_tag :mc_fee, "0.85" %>
</div>
<div class="field">
<%= label_tag :mc_gross %>
<%= text_field_tag :mc_gross, "25.00" %>
</div>
<div class="field">
<%= label_tag :charset %>
<%= text_field_tag :charset, "windows-1252" %>
</div>
<div class="field">
<%= label_tag :notify_version %>
<%= text_field_tag :notify_version, "3.7" %>
</div>
<div class="field">
<%= label_tag :ipn_track_id %>
<%= text_field_tag :ipn_track_id, "9d3d032d9070" %>
</div>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>

View File

@@ -0,0 +1,18 @@
<h2>IPN Details</h2>
<% @ipn.attributes.except("data","payment_id").each do |attr| %>
<p>
<b><%= attr.first.to_s %>:</b>
<%= @ipn.attributes[attr.first] %>
</p>
<% end %>
<p>
<% if @ipn.payment.present? %>
<%= link_to "Linked Payment", @ipn.payment %>
<% else %>
<span class="alert">Couldn't link automatically. Please create payment manually or adjust the user account and try again to <%= link_to "link email '#{@ipn.payer_email}' at membership level '#{@ipn.payment_gross.to_i}'", link_ipn_path(@ipn) %>.</span>
<% end %>
</p>
<%= link_to "Back", ipns_path %>

View File

@@ -11,7 +11,7 @@
<a href="/" title="Home"><img src="/assets/logo.png" id="logo" /></a> <a href="/" title="Home"><img src="/assets/logo.png" id="logo" /></a>
<%= link_to 'People', users_path if can? :read, User %> <%= link_to 'People', users_path if can? :read, User %>
<%= link_to 'Access Cards', cards_path if can? :manage, Card %> <%= link_to 'Access Cards', cards_path if can? :manage, Card %>
<% if can? :manage, UserCertification %> <% if can? :create, UserCertification %>
<%= link_to 'Cert Classes', certifications_path if can? :read, Certification %> <%= link_to 'Cert Classes', certifications_path if can? :read, Certification %>
<%= link_to 'User Certs', user_certifications_path if can? :create, UserCertification %> <%= link_to 'User Certs', user_certifications_path if can? :create, UserCertification %>
<% else %> <% else %>

View File

@@ -1,5 +1,7 @@
Scanning... Scanning...
<% @log.each do |log| %> <% if can? :read_details, Mac
@log.each do |log| %>
<%= log.mac %> = <%= log.mac %> =
<%= log.ip %><br/> <%= log.ip %><br/>
<% end %> <% end
end %>

View File

@@ -19,6 +19,10 @@
<%= f.label :date, "Paid for month beginning" %><br /> <%= f.label :date, "Paid for month beginning" %><br />
<%= f.date_select :date, :default => (DateTime.now - 1.month) %> <%= f.date_select :date, :default => (DateTime.now - 1.month) %>
</div> </div>
<div class="field">
<%= f.label :amount %><br />
<%= f.number_field :amount %>
</div>
<div class="actions"> <div class="actions">
<%= f.submit %> <%= f.submit %>
</div> </div>

View File

@@ -6,6 +6,7 @@
<tr> <tr>
<th>User</th> <th>User</th>
<th>Paid for month <br/>beginning</th> <th>Paid for month <br/>beginning</th>
<th>Amount</th>
<th></th> <th></th>
<th></th> <th></th>
<th></th> <th></th>
@@ -15,6 +16,7 @@
<tr> <tr>
<td><%= link_to payment.user.name_with_payee_and_member_level, payment.user unless payment.user.blank? %></td> <td><%= link_to payment.user.name_with_payee_and_member_level, payment.user unless payment.user.blank? %></td>
<td><%= payment.human_date %></td> <td><%= payment.human_date %></td>
<td><%= payment.amount %></td>
<td><%= link_to 'Details', payment %></td> <td><%= link_to 'Details', payment %></td>
<td><%= link_to 'Edit', edit_payment_path(payment) %></td> <td><%= link_to 'Edit', edit_payment_path(payment) %></td>
</tr> </tr>

View File

@@ -1,6 +1,6 @@
<p> <p>
<b>User:</b> <b>User:</b>
<%= @payment.user.name_with_payee_and_member_level unless @payment.user.blank? %> <%= link_to @payment.user.name_with_payee_and_member_level, @payment.user unless @payment.user.blank? %>
</p> </p>
<p> <p>
@@ -8,9 +8,19 @@
<%= @payment.date %> <%= @payment.date %>
</p> </p>
<p>
<b>Amount:</b>
<%= @payment.amount %>
</p>
<p> <p>
<b>Last Modified by:</b> <b>Last Modified by:</b>
<%= user = @users.find{|u| u.id == @payment.created_by}; link_to user.name, user unless user.blank? %> <% user = @users.find{|u| u.id == @payment.created_by} %>
<% if user.blank? %>
n/a
<% else %>
<%= link_to user.name, user %>
<% end %>
</p> </p>
<p> <p>
@@ -23,6 +33,13 @@
<%= @payment.updated_at %> <%= @payment.updated_at %>
</p> </p>
<% if @payment.ipn.present? %>
<p>
<%= link_to "Paid via PayPal", @payment.ipn %>
</p>
<% end %>
<%= link_to 'Edit', edit_payment_path(@payment) %> | <%= link_to 'Edit', edit_payment_path(@payment) %> |
<%= link_to 'Destroy', @payment, :confirm => 'Are you sure you want to destroy this payment?', :method => :delete if can? :destroy, @payment %> | <%= link_to 'Destroy', @payment, :confirm => 'Are you sure you want to destroy this payment?', :method => :delete if can? :destroy, @payment %> |

View File

@@ -11,13 +11,14 @@
</div> </div>
<% end %> <% end %>
<% @user_certification.user_id = params[:user] if params[:user].present? %>
<div class="field"> <div class="field">
<%= f.label :user_id, "User" %><br /> <%= f.label :user_id, "User" %><br />
<%= collection_select(:user_certification, :user_id, @users, :id, :name) %> <%= collection_select(:user_certification, :user_id, @users, :id, :name, :include_blank => true) %>
</div> </div>
<div class="field"> <div class="field">
<%= f.label :certification_id, "Certification" %><br /> <%= f.label :certification_id, "Certification" %><br />
<%= collection_select(:user_certification, :certification_id, @certifications, :id, :name) %> <%= collection_select(:user_certification, :certification_id, @certifications, :id, :name, :include_blank => true) %>
</div> </div>
<div class="actions"> <div class="actions">
<%= f.submit %> <%= f.submit %>

View File

@@ -1,6 +1,6 @@
<p> <p>
<b>User:</b> <b>User:</b>
<%= @user_certification.user_name %> <%= link_to @user_certification.user.name, @user_certification.user %>
</p> </p>
<p> <p>
@@ -14,12 +14,7 @@
</p> </p>
<p> <p>
<b>Updated:</b> by <b>Updated:</b> by <%= link_to @updated_by.name, @updated_by unless @updated_by.blank? %>
<% if @updated_by.blank? %>
#<%= @user_certification.updated_by ||= "nil" %>
<% else %>
<%= link_to @updated_by.name, @updated_by %>
<% end %>
at <%= @user_certification.updated_at %> at <%= @user_certification.updated_at %>
</p> </p>

View File

@@ -74,17 +74,19 @@
</p> </p>
<% end %> <% end %>
<p> <p>
<b>Card:</b> <b>Card: </b><%= link_to "+ Add", (new_card_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, Card %>
<% if current_user.admin? then %> <% if current_user.admin? then %>
<ul>
<% @user.cards.each do |c| %> <% @user.cards.each do |c| %>
<%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %> <li><%= link_to c.card_number, c %><%= "," unless c == @user.cards.last %></li>
<% end %> <% end %>
</ul>
<% else %> <% else %>
<%= unless @user.cards.blank? then raw("&#x2713;") end %> <%= unless @user.cards.blank? then raw("&#x2713;") end %>
<% end %> <% end %>
</p> </p>
<b>Certifications:</b> <b>Certifications: </b><%= link_to "+ Add", (new_user_certification_path+"?user="+@user.id.to_s), :class => 'btn' if can? :create, UserCertification %>
<ul> <ul>
<% @user.certifications.each do |certification| %> <% @user.certifications.each do |certification| %>
<li><%= link_to certification.name, certification %></li> <li><%= link_to certification.name, certification %></li>

View File

@@ -1,4 +1,8 @@
Dooraccess::Application.routes.draw do Dooraccess::Application.routes.draw do
match 'ipns/import' => 'ipns#import', :as => :import_ipn
resources :ipns
match 'ipns/:id/link' => 'ipns#link', :as => :link_ipn
match 'ipns/:id/validate' => 'ipns#validate', :as => :validate_ipn
resources :payments resources :payments

View File

@@ -0,0 +1,24 @@
class CreateIpns < ActiveRecord::Migration
def change
create_table :ipns do |t|
t.integer :payment_id
t.text :data
t.string :txn_id
t.string :txn_type
t.string :first_name
t.string :last_name
t.string :payer_business_name
t.string :payer_email
t.string :payer_id
t.string :auth_amount
t.string :payment_date
t.string :payment_fee
t.string :payment_gross
t.string :payment_status
t.string :item_name
t.string :payment_type
t.timestamps
end
end
end

View File

@@ -0,0 +1,5 @@
class AddAmountToPayments < ActiveRecord::Migration
def change
add_column :payments, :amount, :decimal
end
end

View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130212083412) do ActiveRecord::Schema.define(:version => 20130824072157) do
create_table "cards", :force => true do |t| create_table "cards", :force => true do |t|
t.string "card_number" t.string "card_number"
@@ -35,6 +35,27 @@ ActiveRecord::Schema.define(:version => 20130212083412) do
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
end end
create_table "ipns", :force => true do |t|
t.integer "payment_id"
t.text "data"
t.string "txn_id"
t.string "txn_type"
t.string "first_name"
t.string "last_name"
t.string "payer_business_name"
t.string "payer_email"
t.string "payer_id"
t.string "auth_amount"
t.string "payment_date"
t.string "payment_fee"
t.string "payment_gross"
t.string "payment_status"
t.string "item_name"
t.string "payment_type"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "mac_logs", :force => true do |t| create_table "mac_logs", :force => true do |t|
t.string "mac" t.string "mac"
t.string "ip" t.string "ip"
@@ -64,6 +85,7 @@ ActiveRecord::Schema.define(:version => 20130212083412) do
t.datetime "created_at", :null => false t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false t.datetime "updated_at", :null => false
t.integer "created_by" t.integer "created_by"
t.decimal "amount"
end end
add_index "payments", ["user_id"], :name => "index_payments_on_user_id" add_index "payments", ["user_id"], :name => "index_payments_on_user_id"

BIN
public/copper-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
public/copper-paid-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 0 B

After

Width:  |  Height:  |  Size: 661 B

BIN
public/gold-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/gold-paid-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
public/heart-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/no-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/silver-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
public/silver-paid-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
public/timeout-coin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

7
test/fixtures/ipns.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
one:
data: MyText
two:
data: MyText

View File

@@ -0,0 +1,7 @@
require 'test_helper'
class IpnControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

View File

@@ -0,0 +1,4 @@
require 'test_helper'
class IpnHelperTest < ActionView::TestCase
end

7
test/unit/ipn_test.rb Normal file
View File

@@ -0,0 +1,7 @@
require 'test_helper'
class IpnTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end