Permalink
Browse files

adds padrino-admin and includes account tests

  • Loading branch information...
achiu committed Jul 12, 2010
1 parent a9bec82 commit 4ebb3c833a7c0cfb89502805c25169fa573b0426
View
@@ -0,0 +1,30 @@
+class Admin < Padrino::Application
+ register Padrino::Mailer
+ register Padrino::Helpers
+ register Padrino::Admin::AccessControl
+
+ ##
+ # Application configuration options
+ #
+ # set :raise_errors, true # Show exceptions (default for development)
+ # set :public, "foo/bar" # Location for static assets (default root/public)
+ # set :reload, false # Reload application files (default in development)
+ # set :default_builder, "foo" # Set a custom form builder (default 'StandardFormBuilder')
+ # set :locale_path, "bar" # Set path for I18n translations (default your_app/locales)
+ # enable :sessions # Disabled by default
+ # disable :flash # Disables rack-flash (enabled by default if sessions)
+ # layout :my_layout # Layout can be in views/layouts/foo.ext or views/foo.ext (default :application)
+ #
+
+ set :login_page, "/admin/sessions/new"
+ disable :store_location
+
+ access_control.roles_for :any do |role|
+ role.protect "/"
+ role.allow "/sessions"
+ end
+
+ access_control.roles_for :admin do |role|
+ role.project_module :accounts, "/accounts"
+ end
+end
@@ -0,0 +1,47 @@
+Admin.controllers :accounts do
+
+ get :index do
+ @accounts = Account.all
+ render 'accounts/index'
+ end
+
+ get :new do
+ @account = Account.new
+ render 'accounts/new'
+ end
+
+ post :create do
+ @account = Account.new(params[:account])
+ if @account.save
+ flash[:notice] = 'Account was successfully created.'
+ redirect url(:accounts, :edit, :id => @account.id)
+ else
+ render 'accounts/new'
+ end
+ end
+
+ get :edit, :with => :id do
+ @account = Account.find(params[:id])
+ render 'accounts/edit'
+ end
+
+ put :update, :with => :id do
+ @account = Account.find(params[:id])
+ if @account.update_attributes(params[:account])
+ flash[:notice] = 'Account was successfully updated.'
+ redirect url(:accounts, :edit, :id => @account.id)
+ else
+ render 'accounts/edit'
+ end
+ end
+
+ delete :destroy, :with => :id do
+ account = Account.find(params[:id])
+ if account != current_account && account.destroy
+ flash[:notice] = 'Account was successfully destroyed.'
+ else
+ flash[:error] = 'Impossible destroy Account!'
+ end
+ redirect url(:accounts, :index)
+ end
+end
@@ -0,0 +1,6 @@
+Admin.controllers :base do
+
+ get :index, :map => "/" do
+ render "base/index"
+ end
+end
@@ -0,0 +1,21 @@
+Admin.controllers :sessions do
+
+ get :new do
+ render "/sessions/new", nil, :layout => false
+ end
+
+ post :create do
+ if account = Account.authenticate(params[:email], params[:password])
+ set_current_account(account)
+ redirect url(:base, :index)
+ else
+ flash[:warning] = "Login or password wrong."
+ redirect url(:sessions, :new)
+ end
+ end
+
+ get :destroy do
+ set_current_account(nil)
+ redirect url(:sessions, :new)
+ end
+end
@@ -0,0 +1,40 @@
+.group
+ =f.label :name
+ =f.error_message_on :name
+ =f.text_field :name, :class => :text_field
+ %span.description Ex: a simple text
+
+.group
+ =f.label :surname
+ =f.error_message_on :surname
+ =f.text_field :surname, :class => :text_field
+ %span.description Ex: a simple text
+
+.group
+ =f.label :email
+ =f.error_message_on :email
+ =f.text_field :email, :class => :text_field
+ %span.description Ex: a simple text
+
+.group
+ =f.label :password
+ =f.error_message_on :password
+ =f.password_field :password, :class => :password_field
+ %span.description Ex: a simple text
+
+.group
+ =f.label :password_confirmation
+ =f.error_message_on :password_confirmation
+ =f.password_field :password_confirmation, :class => :password_field
+ %span.description Ex: a simple text
+
+.group
+ =f.label :role
+ =f.error_message_on :role
+ =f.select :role, :options => access_control.roles
+ %span.description Ex: a simple text
+
+
+.group.navform.wat-cf
+ =f.submit pat(:save), :class => :button
+ =f.submit pat(:cancel), :onclick => "window.location='#{url(:accounts, :index)}';return false", :class => :button
@@ -0,0 +1,15 @@
+.block
+ .secondary-navigation
+ %ul.wat-cf
+ %li.first=link_to pat(:list), url(:accounts, :index)
+ %li=link_to pat(:new), url(:accounts, :new)
+ %li.active=link_to pat(:edit), url(:accounts, :edit, :id => @account.id)
+ .content
+ %h2.title
+ =pat(:edit)
+ =mt(:account)
+ .inner
+ -form_for :account, url(:accounts, :update, :id => @account.id), :method => :put, :class => :form do |f|
+ =partial "accounts/form", :locals => { :f => f }
+
+-content_for :sidebar, partial("base/sidebar")
@@ -0,0 +1,31 @@
+.block
+ .secondary-navigation
+ %ul.wat-cf
+ %li.first.active=link_to pat(:list), url(:accounts, :index)
+ %li=link_to pat(:new), url(:accounts, :new)
+ .content
+ %h2.title
+ =pat(:all)
+ =mt(:account)
+ .inner
+ %table.table
+ %tr
+ %th.first=mat(:account, :id)
+ %th=mat(:account, :name)
+ %th=mat(:account, :surname)
+ %th=mat(:account, :email)
+ %th.last="&nbsp;"
+ -@accounts.each do |account|
+ %tr
+ %td.first=account.id
+ %td=account.name
+ %td=account.surname
+ %td=account.email
+ %td.last
+ =button_to pat(:edit), url(:accounts, :edit, :id => account.id), :method => :get, :class => :button_to
+ ="|"
+ =button_to pat(:delete), url(:accounts, :destroy, :id => account.id), :method => :delete, :class => :button_to
+ .actions-bar.wat-cf
+ .actions="&nbsp;"
+
+-content_for :sidebar, partial("base/sidebar")
@@ -0,0 +1,14 @@
+.block
+ .secondary-navigation
+ %ul.wat-cf
+ %li.first=link_to pat(:list), url(:accounts, :index)
+ %li.active=link_to pat(:new), url(:accounts, :new)
+ .content
+ %h2.title
+ =pat(:new)
+ =mt(:account)
+ .inner
+ -form_for :account, url(:accounts, :create), :class => :form do |f|
+ =partial "accounts/form", :locals => { :f => f }
+
+-content_for :sidebar, partial("base/sidebar")
@@ -0,0 +1,11 @@
+.block
+ %h3 Simple Block
+ .content
+ %p
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+.block
+ %h3 Links
+ %ul.navigation
+ %li=link_to "Link 1"
+ %li=link_to "Link 2"
@@ -0,0 +1,25 @@
+#block-text.block
+ .content
+ %h2.title Dashboard
+ .inner
+ %p.first
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+ %span.hightlight
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+ %p
+ %span.small
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore
+ %p
+ %span.gray
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore
+ %hr
+ %p
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
+ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
+ %span.hightlight
+ Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+-content_for :sidebar, partial("base/sidebar")
@@ -0,0 +1,31 @@
+!!! Strict
+%html{:lang => "en", :xmlns => "http://www.w3.org/1999/xhtml"}
+ %head
+ %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}
+ %title Padrino Admin
+ =stylesheet_link_tag :base, "themes/default/style"
+ %body
+ #container
+ #header
+ %h1=link_to "Padrino Admin", url(:base_index)
+ #user-navigation
+ %ul.wat-cf
+ %li=link_to pat(:profile), url(:accounts, :edit, :id => current_account.id)
+ %li=link_to pat(:logout), url(:sessions, :destroy), :method => :delete
+ #main-navigation
+ %ul.wat-cf
+ -project_modules.each do |project_module|
+ %li{:class => ("active" if request.path_info =~ /^#{project_module.path}/)}
+ =link_to project_module.human_name, project_module.path("/admin")
+ #wrapper.wat-cf
+ .flash=[:error, :warning, :notice].map { |type| flash_tag(type, :class => "message #{type}") }.join
+ #main
+ =yield
+ #footer
+ .block
+ %p
+ Copyright &copy;
+ =Time.now.year
+ Your Site - Powered by
+ =link_to "Padrino v.#{Padrino.version}", "http://padrino.github.com", :target => :_blank
+ #sidebar=yield_content :sidebar
@@ -0,0 +1,25 @@
+!!! Strict
+%html{:lang => "en", :xmlns => "http://www.w3.org/1999/xhtml"}
+ %head
+ %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}
+ %title Padrino Admin
+ =stylesheet_link_tag :base, "themes/default/style"
+ %body
+ #container
+ #box
+ %h1 Padrino Admin
+ #block-login.block
+ %h2 Login Box
+ .content.login
+ .flash=[:error, :warning, :notice].map { |type| flash_tag(type, :class => "message #{type}") }.join
+ -form_tag(url(:sessions, :create), :class => 'form login') do
+ .group.wat-cf
+ .left
+ %label.label.right Login
+ .right=text_field_tag :email, :value => params[:email], :class => :text_field
+ .group.wat-cf
+ .left
+ %label.label.right Password
+ .right=password_field_tag :password, :value => params[:password], :class => :text_field
+ .group.navform.wat-cf
+ .right=submit_tag('Sign In', :class => :button)
View
@@ -0,0 +1,59 @@
+require 'digest/sha1'
+
+class Account
+ include MongoMapper::Document
+ attr_accessor :password
+
+ # Keys
+ key :first_name, String
+ key :last_name, String
+ key :username, String
+ key :email, String
+ key :crypted_password, String
+ key :salt, String
+ key :role, String
+
+ # Validations
+ validates_presence_of :email, :role, :username
+ validates_presence_of :password, :if => :password_required
+ validates_presence_of :password_confirmation, :if => :password_required
+ validates_length_of :password, :within => 4..40, :if => :password_required
+ validates_confirmation_of :password, :if => :password_required
+ validates_length_of :email, :within => 3..40
+ validates_length_of :username, :within => 3..40
+ validates_length_of :first_name, :within => 3..40
+ validates_length_of :last_name, :within => 3..40
+ validates_uniqueness_of :email, :case_sensitive => false
+ validates_uniqueness_of :username, :case_sensitive => false
+ validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
+ validates_format_of :role, :with => /[A-Za-z]/
+
+ # Callbacks
+ before_save :generate_password
+
+ ##
+ # This method is for authentication purpose
+ #
+ def self.authenticate(email, password)
+ account = first(:email => email) if email.present?
+ account && account.password_clean == password ? account : nil
+ end
+
+ ##
+ # This method is used to retrieve the original password.
+ #
+ def password_clean
+ crypted_password.decrypt(salt)
+ end
+
+ private
+ def generate_password
+ return if password.blank?
+ self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{email}--") if new_record?
+ self.crypted_password = password.encrypt(self.salt)
+ end
+
+ def password_required
+ crypted_password.blank? || !password.blank?
+ end
+end
View
@@ -22,4 +22,5 @@
#
# Mounts the core application for this project
-Padrino.mount("IdeaGrid").to('/')
+Padrino.mount("IdeaGrid").to('/')
+Padrino.mount("Admin").to("/admin")
Oops, something went wrong.

0 comments on commit 4ebb3c8

Please sign in to comment.