From 745790244ac6207ed31bcf42b5d6e16b46538dc3 Mon Sep 17 00:00:00 2001 From: Saurabh Bhatia Date: Fri, 9 May 2014 14:03:55 +0800 Subject: [PATCH] Reset password, member roles --- app/assets/javascripts/admin/roles.js.coffee | 3 + app/assets/javascripts/password.js.coffee | 3 + app/assets/stylesheets/admin/roles.css.scss | 3 + app/assets/stylesheets/password.css.scss | 3 + app/controllers/admin/members_controller.rb | 67 ++++++++-- app/controllers/admin/roles_controller.rb | 68 ++++++++++ app/controllers/passwords_controller.rb | 42 ++++++ app/controllers/sessions_controller.rb | 2 +- app/controllers/users_controller.rb | 19 ++- app/helpers/admin/roles_helper.rb | 2 + app/helpers/application_helper.rb | 26 ++++ app/helpers/password_helper.rb | 2 + app/mailers/confirm_user_mailer.rb | 9 ++ app/mailers/reset_password_mailer.rb | 10 ++ app/models/i18n_variable.rb | 24 ++++ app/models/member_profile.rb | 3 + app/models/role.rb | 11 ++ app/models/role_field.rb | 9 ++ app/models/user.rb | 64 +++++++++ app/views/admin/members/_form.html.erb | 0 .../admin/members/_index_paginator.html.erb | 13 ++ app/views/admin/members/_js_and_css.html.erb | 12 ++ .../admin/members/_member_basic.html.erb | 125 ++++++++++++++++++ .../members/_member_for_listing.html.erb | 8 +- app/views/admin/members/_side_bar.html.erb | 20 ++- app/views/admin/members/edit.html.erb | 40 ++++++ app/views/admin/members/index.html.erb | 6 +- app/views/admin/members/show.html.erb | 44 ++++++ app/views/admin/roles/_edit.html.erb | 10 ++ app/views/admin/roles/_form.html.erb | 9 ++ app/views/admin/roles/_index.html.erb | 12 ++ app/views/admin/roles/_new.html.erb | 10 ++ app/views/admin/roles/_role.html.erb | 26 ++++ app/views/admin/roles/create.js.erb | 2 + app/views/admin/roles/destroy.js.erb | 1 + app/views/admin/roles/edit.html.erb | 1 + app/views/admin/roles/edit.js.erb | 1 + app/views/admin/roles/index.html.erb | 20 +++ app/views/admin/roles/index.js.erb | 4 + app/views/admin/roles/new.html.erb | 1 + app/views/admin/roles/new.js.erb | 1 + app/views/admin/roles/update.js.erb | 4 + .../user_confirmation_email.html.erb | 4 + app/views/layouts/member.html.erb | 2 - app/views/passwords/edit.html.erb | 31 +++++ app/views/passwords/new.html.erb | 30 +++++ .../reset_user_password.html.erb | 4 + config/environments/development.rb | 3 + config/routes.rb | 14 +- lib/orbit_app/plugin/registration.rb | 99 ++++++++++++++ lib/orbit_app/register_module.rb | 2 + .../admin/roles_controller_test.rb | 9 ++ test/controllers/password_controller_test.rb | 9 ++ test/fixtures/role_fields.yml | 9 ++ test/helpers/admin/roles_helper_test.rb | 4 + test/helpers/password_helper_test.rb | 4 + test/mailers/confirm_user_mailer_test.rb | 7 + .../previews/confirm_user_mailer_preview.rb | 4 + .../previews/reset_password_mailer_preview.rb | 4 + test/mailers/reset_password_mailer_test.rb | 7 + test/models/role_field_test.rb | 7 + 61 files changed, 960 insertions(+), 33 deletions(-) create mode 100644 app/assets/javascripts/admin/roles.js.coffee create mode 100644 app/assets/javascripts/password.js.coffee create mode 100644 app/assets/stylesheets/admin/roles.css.scss create mode 100644 app/assets/stylesheets/password.css.scss create mode 100644 app/controllers/admin/roles_controller.rb create mode 100644 app/controllers/passwords_controller.rb create mode 100644 app/helpers/admin/roles_helper.rb create mode 100644 app/helpers/password_helper.rb create mode 100644 app/mailers/confirm_user_mailer.rb create mode 100644 app/mailers/reset_password_mailer.rb create mode 100644 app/models/i18n_variable.rb create mode 100644 app/models/role_field.rb create mode 100644 app/views/admin/members/_form.html.erb create mode 100644 app/views/admin/members/_index_paginator.html.erb create mode 100644 app/views/admin/members/_js_and_css.html.erb create mode 100644 app/views/admin/members/_member_basic.html.erb create mode 100644 app/views/admin/members/edit.html.erb create mode 100644 app/views/admin/members/show.html.erb create mode 100644 app/views/admin/roles/_edit.html.erb create mode 100644 app/views/admin/roles/_form.html.erb create mode 100644 app/views/admin/roles/_index.html.erb create mode 100644 app/views/admin/roles/_new.html.erb create mode 100644 app/views/admin/roles/_role.html.erb create mode 100644 app/views/admin/roles/create.js.erb create mode 100644 app/views/admin/roles/destroy.js.erb create mode 100644 app/views/admin/roles/edit.html.erb create mode 100644 app/views/admin/roles/edit.js.erb create mode 100644 app/views/admin/roles/index.html.erb create mode 100644 app/views/admin/roles/index.js.erb create mode 100644 app/views/admin/roles/new.html.erb create mode 100644 app/views/admin/roles/new.js.erb create mode 100644 app/views/admin/roles/update.js.erb create mode 100644 app/views/confirm_user_mailer/user_confirmation_email.html.erb create mode 100644 app/views/passwords/edit.html.erb create mode 100644 app/views/passwords/new.html.erb create mode 100644 app/views/reset_password_mailer/reset_user_password.html.erb create mode 100644 lib/orbit_app/plugin/registration.rb create mode 100644 test/controllers/admin/roles_controller_test.rb create mode 100644 test/controllers/password_controller_test.rb create mode 100644 test/fixtures/role_fields.yml create mode 100644 test/helpers/admin/roles_helper_test.rb create mode 100644 test/helpers/password_helper_test.rb create mode 100644 test/mailers/confirm_user_mailer_test.rb create mode 100644 test/mailers/previews/confirm_user_mailer_preview.rb create mode 100644 test/mailers/previews/reset_password_mailer_preview.rb create mode 100644 test/mailers/reset_password_mailer_test.rb create mode 100644 test/models/role_field_test.rb diff --git a/app/assets/javascripts/admin/roles.js.coffee b/app/assets/javascripts/admin/roles.js.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/admin/roles.js.coffee @@ -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://coffeescript.org/ diff --git a/app/assets/javascripts/password.js.coffee b/app/assets/javascripts/password.js.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/password.js.coffee @@ -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://coffeescript.org/ diff --git a/app/assets/stylesheets/admin/roles.css.scss b/app/assets/stylesheets/admin/roles.css.scss new file mode 100644 index 0000000..f82db8f --- /dev/null +++ b/app/assets/stylesheets/admin/roles.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the admin/roles controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/password.css.scss b/app/assets/stylesheets/password.css.scss new file mode 100644 index 0000000..ba53dc4 --- /dev/null +++ b/app/assets/stylesheets/password.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the password controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/admin/members_controller.rb b/app/controllers/admin/members_controller.rb index 26b341f..147fe8c 100644 --- a/app/controllers/admin/members_controller.rb +++ b/app/controllers/admin/members_controller.rb @@ -1,6 +1,9 @@ class Admin::MembersController < OrbitMemberController + before_action :set_member_profile, only: [:show, :edit, :update, :create] + def index @roles = Role.all + page_num = params[:page] || 1 @filter = params[:filter] @mq = params[:mq] @@ -24,13 +27,13 @@ class Admin::MembersController < OrbitMemberController render case params[:at] when 'summary' - @users=User.all.desc("_id") + @members=User.all.page(page_num).per(12).desc("_id") "index_summary" when 'thumbnail' - @users=User.all.desc("_id") + @members=User.all.page(page_num).per(36).desc("_id") "index_thumbnail" else - @users=User.all.desc("_id") + @members=User.all.page(page_num).per(10).desc("_id") "index" end @@ -38,13 +41,13 @@ class Admin::MembersController < OrbitMemberController render case params[:at] when 'summary' - @users=User.all.any_of({:user_id => /#{@mq}/i}, {:first_name => /#{@mq}/i}, {:last_name => /#{@mq}/i}, {:email => /#{@mq}/i}, {:office_tel => /#{@mq}/i}).desc("_id") + @members=User.all.any_of({:user_id => /#{@mq}/i}, {:first_name => /#{@mq}/i}, {:last_name => /#{@mq}/i}, {:email => /#{@mq}/i}, {:office_tel => /#{@mq}/i}).desc("_id") "index_summary" when 'thumbnail' - @users=User.all.any_of({:user_id => /#{@mq}/i}, {:first_name => /#{@mq}/i}, {:last_name => /#{@mq}/i}, {:email => /#{@mq}/i}, {:office_tel => /#{@mq}/i}).desc("_id") + @members=User.all.any_of({:user_id => /#{@mq}/i}, {:first_name => /#{@mq}/i}, {:last_name => /#{@mq}/i}, {:email => /#{@mq}/i}, {:office_tel => /#{@mq}/i}).desc("_id") "index_thumbnail" else - @users=User.all.any_of({:user_id => /#{@mq}/i}, {:first_name => /#{@mq}/i}, {:last_name => /#{@mq}/i}, {:email => /#{@mq}/i}, {:office_tel => /#{@mq}/i}).desc("_id") + @members=User.all.any_of({:user_id => /#{@mq}/i}, {:first_name => /#{@mq}/i}, {:last_name => /#{@mq}/i}, {:email => /#{@mq}/i}, {:office_tel => /#{@mq}/i}).desc("_id") "index" end @@ -52,13 +55,13 @@ class Admin::MembersController < OrbitMemberController render case params[:at] when 'summary' - @users=User.all.any_in(:role_ids=>@filter['role']).desc("_id") + @members=User.all.any_in(:role_ids=>@filter['role']).page(page_num).per(12).desc("_id") "index_summary" when 'thumbnail' - @users=User.all.any_in(:role_ids=>@filter['role']).desc("_id") + @members=User.all.any_in(:role_ids=>@filter['role']).page(page_num).per(36).desc("_id") "index_thumbnail" else - @users=User.all.any_in(:role_ids=>@filter['role']).desc("_id") + @members=User.all.any_in(:role_ids=>@filter['role']).page(page_num).per(10).desc("_id") "index" end @@ -66,8 +69,10 @@ class Admin::MembersController < OrbitMemberController end + def show + end + def new - @member = MemberProfile.new end def edit @@ -77,5 +82,47 @@ class Admin::MembersController < OrbitMemberController end def update + respond_to do |format| + if @member.update(member_profile_params) + + format.html { redirect_to admin_members_path, notice: 'Successfully Updated the User' } + format.json { head :no_content } + else + format.html { render action: 'edit' } + format.json { render json: @member.errors, status: :unprocessable_entity } + end + end end + + def destroy + if params[:id].eql?(current_user.id.to_s) + flash[:error] = t(:cant_delete_self) + else + @user = User.find(params[:id]) + @user.member_profile.delete + @user.delete + end + + render action: "index" + end + + private + + # Use callbacks to share common setup or constraints between actions. + def set_member_profile + @member = MemberProfile.find(params[:id]) + end + + # Never trust parameters from the scary internet, only allow the white list through. + def member_profile_params + params.require(:member_profile).permit! + end + + + protected + + def set_attribute + @class = 'users' + end + end diff --git a/app/controllers/admin/roles_controller.rb b/app/controllers/admin/roles_controller.rb new file mode 100644 index 0000000..3a432fa --- /dev/null +++ b/app/controllers/admin/roles_controller.rb @@ -0,0 +1,68 @@ +class Admin::RolesController < OrbitMemberController + before_action :set_role, only: [:show, :edit , :update, :destroy] + + def index + @roles = Role.all.asc("_id").entries + end + + def show + end + + def new + @role = Role.new + render layout: false + end + + def edit + render layout: false + end + + def create + @role = Role.new(role_params) + if @role.save + redirect_to admin_roles_url + else + @role = Role.new(role_params) + flash.now[:error] = t('create.error.category') + render action: :new + end + end + + def update + if @role.update_attributes(role_params) + @role.role_fields.each{|t| t.destroy if t["to_delete"] == true} + redirect_to admin_roles_url + else + flash.now[:error] = t('update.error.category') + render action: :edit + end + end + + def destroy + @role.destroy + respond_to do |format| + format.html { redirect_to admin_roles_url } + format.js { render 'admin/roles/destroy' } + end + end + + def toggle + @role = Role.find(params[:role_id]) + @role.disabled = @role.disabled ? false : true + @role.save! + redirect_to action: :index + end + + + private + # Use callbacks to share common setup or constraints between actions. + def set_role + @role = Role.find(params[:id]) + end + + # Never trust parameters from the scary internet, only allow the white list through. + def role_params + params.require(:role).permit! + end + +end diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb new file mode 100644 index 0000000..d629d48 --- /dev/null +++ b/app/controllers/passwords_controller.rb @@ -0,0 +1,42 @@ +class PasswordsController < ApplicationController + layout "authentication" + + def new + end + + def create + @user = User.find_by(email: params[:email]) rescue nil + if @user.present? + @user.send_password_reset_email + redirect_to new_password_path, :notice => "Reset Instructions Sent" + else + redirect_to new_password_path, :notice => "User Not Found" + end + end + + def edit + if params[:token] + check_token = User.check_password_token(params[:token]) + if check_token + @user = User.find_by(reset_token: params[:token]) + else + redirect_to new_password_path, :notice => "Invalid Token for Reset" + end + else + redirect_to new_password_path, :notice => "Cannot Reset without a valid token" + end + end + + def update + @user = User.find_by(reset_token: password_attributes[:reset_token]) + @user.update_password(password_attributes[:password], password_attributes[:password_confirmation]) + redirect_to root_path + end + + private + + def password_attributes + params.require(:user).permit! + end + +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 9a0bbf5..5d447ee 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -6,7 +6,7 @@ class SessionsController < ApplicationController def create user = User.find_by(user_name: params[:user_name]) rescue nil - if user && user.authenticate(params[:password]) + if (user && user.authenticate(params[:password]) && user.is_confirmed?.eql?(true)) session[:user_id] = user.id redirect_to admin_dashboards_path, :notice => "Logged in!" else diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 592a509..2e7522e 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -7,16 +7,31 @@ class UsersController < ApplicationController def create @user = User.new(user_params) if @user.save - redirect_to root_url, :notice => "Signed Up Successfully!" + redirect_to root_url, :notice => "Signed Up Successfully, Please Check your email for confirmation!" + @user.send_confirmation_email else render "new" end end + def confirm_user + user = User.confirm_email(params[:token]) + + redirect_to post_confirmation_users_path + if user[:success].eql?("true") + flash[:notice] = "You have confirmed successfully" + else + flash[:notice] = "Error in confirmation please try again." + end + end + + def post_confirmation + end + private # Never trust parameters from the scary internet, only allow the white list through. def user_params - params.require(:user).permit(:email, :password, :password_confirmation, :user_name) + params.require(:user).permit(:email, :password, :password_confirmation, :user_name) end end diff --git a/app/helpers/admin/roles_helper.rb b/app/helpers/admin/roles_helper.rb new file mode 100644 index 0000000..d3b0282 --- /dev/null +++ b/app/helpers/admin/roles_helper.rb @@ -0,0 +1,2 @@ +module Admin::RolesHelper +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b232553..bc13a1d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -189,4 +189,30 @@ module ApplicationHelper ((controller.controller_name.eql?(controller_name) || request.fullpath.eql?(controller_name)) && controller.action_name.eql?(action_name)) ? 'active' : nil end + def link_back(custom_class=nil) + case custom_class + when nil + link_to t('back'), get_go_back, :class => 'nav' + else + link_to t('back'), get_go_back, :class => custom_class + end + end + + # Clean the link back + def get_go_back + begin + if request.url.include?('locale=') + session[:last_page] + else + session[:last_page] = remove_locale(request.referer) + end + rescue + eval(params[:controller].split('/').join('_') << '_url') + end + end + + def show_avatar(user) + image_tag(user.avatar.thumb.url) + end + end diff --git a/app/helpers/password_helper.rb b/app/helpers/password_helper.rb new file mode 100644 index 0000000..56beaa2 --- /dev/null +++ b/app/helpers/password_helper.rb @@ -0,0 +1,2 @@ +module PasswordHelper +end diff --git a/app/mailers/confirm_user_mailer.rb b/app/mailers/confirm_user_mailer.rb new file mode 100644 index 0000000..0c47f5c --- /dev/null +++ b/app/mailers/confirm_user_mailer.rb @@ -0,0 +1,9 @@ +class ConfirmUserMailer < ActionMailer::Base + default from: "noreply@rulingcom.com" + + def user_confirmation_email(user) + email = user.email + @confirmation_token = user.confirmation_token + mail(:to => email, :subject => "User Confirmation instructions") + end +end diff --git a/app/mailers/reset_password_mailer.rb b/app/mailers/reset_password_mailer.rb new file mode 100644 index 0000000..19bd45b --- /dev/null +++ b/app/mailers/reset_password_mailer.rb @@ -0,0 +1,10 @@ +class ResetPasswordMailer < ActionMailer::Base + default from: "noreply@rulingcom.com" + + def reset_user_password(user) + email = user.email + @reset_token = user.reset_token + @user_id = user.id + mail(:to => email, :subject => "Reset Password Instructions") + end +end diff --git a/app/models/i18n_variable.rb b/app/models/i18n_variable.rb new file mode 100644 index 0000000..ab9e83d --- /dev/null +++ b/app/models/i18n_variable.rb @@ -0,0 +1,24 @@ +class I18nVariable + + include Mongoid::Document + include Mongoid::Timestamps + + field :key + field :document_class, type: String + field :parent_id, type: BSON::ObjectId + + belongs_to :language_value, polymorphic: true + + def method_missing(*field) + if field.size > 1 + self.write_attribute(field[0].to_s.delete('=').to_sym, field[1]) + else + self[field[0]] + end + end + + def self.from_locale(locale) + I18nVariable.find_by(:key => locale)[I18n.locale] + end + +end diff --git a/app/models/member_profile.rb b/app/models/member_profile.rb index 0113887..eccc1a1 100644 --- a/app/models/member_profile.rb +++ b/app/models/member_profile.rb @@ -3,11 +3,14 @@ class MemberProfile field :first_name, type: String, localize: true field :last_name, type: String, localize: true field :gender + field :sid + field :office_tel has_one :user has_and_belongs_to_many :roles mount_uploader :avatar, AvatarUploader + paginates_per 10 def name "#{self.first_name} #{self.last_name}" diff --git a/app/models/role.rb b/app/models/role.rb index 99bd231..c209791 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -2,7 +2,18 @@ class Role include Mongoid::Document field :key, type: String field :title, type: String, localize: true + field :built_in, type: Boolean, :default => false + field :disabled, :type => Boolean, :default => false has_and_belongs_to_many :member_profiles has_many :authorizations + embeds_many :role_fields + + def is_built_in? + self.built_in + end + + def is_disabled? + self.disabled + end end diff --git a/app/models/role_field.rb b/app/models/role_field.rb new file mode 100644 index 0000000..f7e4e1b --- /dev/null +++ b/app/models/role_field.rb @@ -0,0 +1,9 @@ +class RoleField + include Mongoid::Document + include Mongoid::Timestamps + + field :key, type: String + field :title, type: String, localize: true + + embedded_in :role +end diff --git a/app/models/user.rb b/app/models/user.rb index 5b9c649..8ed34c4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,6 +7,10 @@ class User field :user_name, type: String field :email, type: String field :password_digest, type: String + field :confirmation_token, type: String + field :reset_token, type: String + + index({ confirmation_token: 1}, { unique: true }) has_secure_password @@ -20,6 +24,66 @@ class User validates :password, presence: true, :on => :create, length: {:in => 8..20} validates :email, presence: true, uniqueness: true, format: { with: VALID_EMAIL_FORMAT } + def generate_confirmation_token + self.confirmation_token = SecureRandom.hex(5) + self.save + end + + def send_confirmation_email + self.generate_confirmation_token + ConfirmUserMailer.user_confirmation_email(self).deliver + end + + def self.confirm_email(confirmation_token = nil) + if confirmation_token + user = self.find_by(confirmation_token: confirmation_token) rescue nil + token_status = user.present? + case token_status + when true + user.confirmation_token = nil + user.save + return {:success => "true", :id => user.id.to_s} + when false + return {:success => "false"} + end + else + return {:success => "false"} + end + end + + def generate_reset_token + self.reset_token = SecureRandom.hex(5) + self.save + end + + def send_password_reset_email + self.generate_reset_token + ResetPasswordMailer.reset_user_password(self).deliver + end + + def self.check_password_token(reset_token = nil) + user = self.find_by(reset_token: reset_token) rescue nil + token_status = user.present? + if token_status + true + else + false + end + end + + def update_password(password, password_confirmation) + self.update_attributes(password: password, password_confirmation: password_confirmation, reset_token: nil) + self.save + end + + def is_confirmed? + if self.confirmation_token.present? + false + else + true + end + end + def is_admin? if (self.workgroup.present? && self.workgroup.key.eql?("admin")) true diff --git a/app/views/admin/members/_form.html.erb b/app/views/admin/members/_form.html.erb new file mode 100644 index 0000000..e69de29 diff --git a/app/views/admin/members/_index_paginator.html.erb b/app/views/admin/members/_index_paginator.html.erb new file mode 100644 index 0000000..9c9355d --- /dev/null +++ b/app/views/admin/members/_index_paginator.html.erb @@ -0,0 +1,13 @@ +
+
+ <% if current_user.is_admin? %> + <%= link_to t(:edit_order),new_admin_member_path ,:class => "btn btn-primary" %> + <%= link_to(new_admin_member_path,:class=> "btn btn-primary") do %> + <%= t(:add) %> + <% end -%> + <% end -%> +
+ +
diff --git a/app/views/admin/members/_js_and_css.html.erb b/app/views/admin/members/_js_and_css.html.erb new file mode 100644 index 0000000..aa39e28 --- /dev/null +++ b/app/views/admin/members/_js_and_css.html.erb @@ -0,0 +1,12 @@ +<% content_for :page_specific_css do -%> + + <%= stylesheet_link_tag "lib/wrap-nav" %> + <%= stylesheet_link_tag "lib/main-list" %> + <%= stylesheet_link_tag "lib/filter" %> + <%= stylesheet_link_tag "lib/member" %> + +<% end -%> +<% content_for :page_specific_javascript do -%> + <%= javascript_include_tag "lib/jquery.lite.image.resize.js" %> + <%= javascript_include_tag "lib/member/list-view.js" %> +<% end -%> \ No newline at end of file diff --git a/app/views/admin/members/_member_basic.html.erb b/app/views/admin/members/_member_basic.html.erb new file mode 100644 index 0000000..a9f30ad --- /dev/null +++ b/app/views/admin/members/_member_basic.html.erb @@ -0,0 +1,125 @@ + <%#= devise_error_messages! %> + +
+
+

<%=t(:sys_basic_form)%>

+
+
+ + +
+ <%= f.label t("users.avatar"),:class=>"control-label muted" %> +
+ +
+
+ <% if @member.avatar? %> + <%= image_tag(@member.avatar.thumb.url) %> + <% else %> + <%= image_tag "person.png" %> + <% end %> +
+
+ + <%= t(:select_image) %> + <%= t(:change) %> + <%= f.file_field :avatar %> + + <%= t(:cancel) %> +
+ +
+
+
+
+ + +
+ <%= f.label t("users.first_name"),{:class=>"control-label muted", :func=>"field_label"} %> +
+
+
+
+ <% current_site.in_use_locales.each_with_index do |locale, i| %> +
" id="first_name_<%= locale %>"> + <%= f.fields_for :first_name_translations do |f| %> + <%= f.text_field locale, :value => (@member.first_name_translations[locale] rescue nil), :placeholder=>"#{t("users.first_name")}" %> + <% end %> +
+ <% end %> +
+
+ <% current_site.in_use_locales.each_with_index do |locale, i| %> + " href="#first_name_<%= locale %>" data-toggle="tab"><%= I18nVariable.from_locale(locale) %> + <% end %> + +
+
+
+
+
+ + +
+ <%= f.label t("users.last_name"),{:class=>"control-label muted", :func=>"field_label"} %> +
+
+
+
+ <% current_site.in_use_locales.each_with_index do |locale, i| %> +
" id="last_name_<%= locale %>"> + <%= f.fields_for :last_name_translations do |f| %> + <%= f.text_field locale, :value => (@member.last_name_translations[locale] rescue nil), :placeholder=>"#{t("users.last_name")}" %> + <% end %> +
+ <% end %> +
+
+ <% current_site.in_use_locales.each_with_index do |locale, i| %> + " href="#last_name_<%= locale %>" data-toggle="tab"><%= I18nVariable.from_locale(locale) %> + <% end %> + +
+
+
+
+
+ + +
+ <%= f.label t("users.sid"),:class=>"control-label muted" %> +
+ <%= f.text_field :sid %> + <%= t("users.sid_note")%> +
+
+ + +
+ <%= f.label t("users.office_tel"),:class=>"control-label muted" %> +
+ <%= f.text_field :office_tel %> + <%= t("users.office_tel_note")%> +
+
+ + +
+ <%= f.label t("users.sex"),:class=>"control-label muted" %> +
+ + + +
+
+ +
+
\ No newline at end of file diff --git a/app/views/admin/members/_member_for_listing.html.erb b/app/views/admin/members/_member_for_listing.html.erb index f7e3094..93e0274 100644 --- a/app/views/admin/members/_member_for_listing.html.erb +++ b/app/views/admin/members/_member_for_listing.html.erb @@ -18,12 +18,12 @@ <% end %> - <%= link_to (member_for_listing.member_profile.name && member_for_listing.member_profile.name != member_for_listing.email ? member_for_listing.member_profile.name : member_for_listing.id),admin_members_path(member_for_listing) %> + <%= link_to (member_for_listing.member_profile.name && member_for_listing.member_profile.name != member_for_listing.email ? member_for_listing.member_profile.name : member_for_listing.id),admin_member_path(member_for_listing.member_profile) %>
diff --git a/app/views/admin/members/_side_bar.html.erb b/app/views/admin/members/_side_bar.html.erb index f36436b..86388ae 100644 --- a/app/views/admin/members/_side_bar.html.erb +++ b/app/views/admin/members/_side_bar.html.erb @@ -6,7 +6,7 @@ + +<%= render :partial=> "index_paginator" if @mq.blank? %> diff --git a/app/views/admin/members/show.html.erb b/app/views/admin/members/show.html.erb new file mode 100644 index 0000000..56ce349 --- /dev/null +++ b/app/views/admin/members/show.html.erb @@ -0,0 +1,44 @@ +<% content_for :side_bar do %> + <%= render :partial => 'admin/members/side_bar' %> +<% end %> + +<%= render :partial => "js_and_css"%> + +<% content_for :page_specific_javascript do -%> + <%= javascript_include_tag "lib/member/member.js" %> + <%= javascript_include_tag "lib/footable-0.1.js" %> +<% end -%> + +
+ +
+
+ <%= show_avatar(@member) %> +
+
+

<%= @member.name%>

+ <%= @member.user.email %> +
+ <%= link_to(" #{t(:edit)}".html_safe,edit_admin_member_path(@member.id),:class=>"btn btn-mini" ) if current_user.is_admin?%> + <%= link_to(" #{t("users.change_passwd")}".html_safe,:class=>"btn btn-mini" ) if current_user.is_admin? and current_user.id != @member.user.id %> + <%= link_to(" #{t("users.setting_privilege")}".html_safe,:class=>"btn btn-mini" ) if current_user.is_admin? and current_user.id != @member.user.id %> +
+
+ +
+
+ + +
+
+
+ +
+ + + + + +
+ + diff --git a/app/views/admin/roles/_edit.html.erb b/app/views/admin/roles/_edit.html.erb new file mode 100644 index 0000000..493928f --- /dev/null +++ b/app/views/admin/roles/_edit.html.erb @@ -0,0 +1,10 @@ +<%= form_for @role, url: admin_role_path(id: @role.id), remote: true, :html => { :id => 'form_role_filter' } do |f| %> +
+ Edit + <%= render :partial => 'form', :locals => {:f => f} %> +
+
+ <%= t(:cancel) %> + <%= f.submit t(:update_), class: 'btn btn-primary btn-small' %> +
+<% end %> \ No newline at end of file diff --git a/app/views/admin/roles/_form.html.erb b/app/views/admin/roles/_form.html.erb new file mode 100644 index 0000000..a99efb5 --- /dev/null +++ b/app/views/admin/roles/_form.html.erb @@ -0,0 +1,9 @@ +<%= label_tag "key","key", :class=>"muted" %> +<%= f.text_field :key, :value => @role.key,:class=>"input-large", placeholder: t(:key) %> + +<%= f.fields_for :title_translations do |f| %> + <% current_site.in_use_locales.each do |locale| %> + <%= label_tag "name-#{locale}", "#{t(:name)} (#{I18nVariable.from_locale(locale)})" %> + <%= f.text_field locale, :class => 'input-large', :value => (@role.title_translations[locale] rescue ''), placeholder: t(:name) %> + <% end %> +<% end %> diff --git a/app/views/admin/roles/_index.html.erb b/app/views/admin/roles/_index.html.erb new file mode 100644 index 0000000..f3caeea --- /dev/null +++ b/app/views/admin/roles/_index.html.erb @@ -0,0 +1,12 @@ + + + + + + + + + <%= render partial: 'admin/roles/role', collection: @roles %> + + +
<%= t("role") %>
\ No newline at end of file diff --git a/app/views/admin/roles/_new.html.erb b/app/views/admin/roles/_new.html.erb new file mode 100644 index 0000000..8f7364c --- /dev/null +++ b/app/views/admin/roles/_new.html.erb @@ -0,0 +1,10 @@ +<%= form_for @role, url: admin_roles_path(id: @role.id), remote: true, :html => { :id => 'form_role_filter' } do |f| %> +
+ Add + <%= render :partial => 'form', :locals => {:f => f} %> +
+
+ <%= t(:cancel) %> + <%= f.submit t(:create_), class: 'btn btn-primary btn-small' %> +
+<% end %> \ No newline at end of file diff --git a/app/views/admin/roles/_role.html.erb b/app/views/admin/roles/_role.html.erb new file mode 100644 index 0000000..985a60f --- /dev/null +++ b/app/views/admin/roles/_role.html.erb @@ -0,0 +1,26 @@ + + + + <%= role.title %> +
+ +
+ + +
+
+ <%= check_box_tag 'accept', role.disabled ? 'fasle' : 'true', false ,{ :class => 'toggle-check role_filter_checked', :data=>{:deploy=>"right"}, :data=>{:path=> admin_role_toggle_path(role)}, :checked=> role.disabled} %> + +
+
+ <% if !role.is_built_in? %> + <%= link_to (content_tag :i,'',:class=>'icon-trash')+t(:delete_), admin_role_path(role), :type=>"button", :class => 'btn btn-mini btn-danger', :confirm => t('sure?'), :method => :delete, :remote => true %> + <% end %> + + + + diff --git a/app/views/admin/roles/create.js.erb b/app/views/admin/roles/create.js.erb new file mode 100644 index 0000000..ec3bc62 --- /dev/null +++ b/app/views/admin/roles/create.js.erb @@ -0,0 +1,2 @@ +$('<%= j render :partial => 'role', :collection => [@role] %>').appendTo('#role_filters').hide().fadeIn(); +$("#form_role_filter")[0].reset(); \ No newline at end of file diff --git a/app/views/admin/roles/destroy.js.erb b/app/views/admin/roles/destroy.js.erb new file mode 100644 index 0000000..a9bafc7 --- /dev/null +++ b/app/views/admin/roles/destroy.js.erb @@ -0,0 +1 @@ +$("#<%= dom_id @role %>").remove(); \ No newline at end of file diff --git a/app/views/admin/roles/edit.html.erb b/app/views/admin/roles/edit.html.erb new file mode 100644 index 0000000..9e91e9e --- /dev/null +++ b/app/views/admin/roles/edit.html.erb @@ -0,0 +1 @@ +<%= render 'edit' %> \ No newline at end of file diff --git a/app/views/admin/roles/edit.js.erb b/app/views/admin/roles/edit.js.erb new file mode 100644 index 0000000..40061b9 --- /dev/null +++ b/app/views/admin/roles/edit.js.erb @@ -0,0 +1 @@ +$("#form > form").replaceWith("<%= j render "form" %>"); diff --git a/app/views/admin/roles/index.html.erb b/app/views/admin/roles/index.html.erb new file mode 100644 index 0000000..ee2dbb7 --- /dev/null +++ b/app/views/admin/roles/index.html.erb @@ -0,0 +1,20 @@ +<% content_for :side_bar do %> + <%= render :partial => 'admin/members/side_bar' %> +<% end %> + +<% content_for :page_specific_css do -%> + <%= stylesheet_link_tag "lib/wrap-nav.css" %> + <%= stylesheet_link_tag "lib/pageslide.css" %> + <%= stylesheet_link_tag "lib/main-forms.css" %> + <%= stylesheet_link_tag "lib/togglebox.css" %> +<% end -%> + +
+
+ <%= link_to content_tag(:i,t("new.role"),:class=>"icon-plus"),eval("new_admin_role_path"),:class=>"btn btn-primary open-slide"%> +
+
+ +
+<%= render 'admin/roles/index' %> +
diff --git a/app/views/admin/roles/index.js.erb b/app/views/admin/roles/index.js.erb new file mode 100644 index 0000000..dff4053 --- /dev/null +++ b/app/views/admin/roles/index.js.erb @@ -0,0 +1,4 @@ +// $("#role_filters_index").html("<%= j render 'index' %>") +location.reload(); +$.pageslide.close(); +openSlide(); \ No newline at end of file diff --git a/app/views/admin/roles/new.html.erb b/app/views/admin/roles/new.html.erb new file mode 100644 index 0000000..e3355a9 --- /dev/null +++ b/app/views/admin/roles/new.html.erb @@ -0,0 +1 @@ +<%= render 'new' %> \ No newline at end of file diff --git a/app/views/admin/roles/new.js.erb b/app/views/admin/roles/new.js.erb new file mode 100644 index 0000000..40061b9 --- /dev/null +++ b/app/views/admin/roles/new.js.erb @@ -0,0 +1 @@ +$("#form > form").replaceWith("<%= j render "form" %>"); diff --git a/app/views/admin/roles/update.js.erb b/app/views/admin/roles/update.js.erb new file mode 100644 index 0000000..e1889b7 --- /dev/null +++ b/app/views/admin/roles/update.js.erb @@ -0,0 +1,4 @@ +$("#<%= dom_id @role %>").replaceWith("<%= j render :partial => 'role', :collection => [@role] %>"); +<% @role = @types.new(:display => 'List') # reset for new form %> +$("#form_role_filter").replaceWith("<%= j render "form" %>") +$("#form_role_filter")[0].reset(); \ No newline at end of file diff --git a/app/views/confirm_user_mailer/user_confirmation_email.html.erb b/app/views/confirm_user_mailer/user_confirmation_email.html.erb new file mode 100644 index 0000000..40e3f3a --- /dev/null +++ b/app/views/confirm_user_mailer/user_confirmation_email.html.erb @@ -0,0 +1,4 @@ +

Thank you for registering your site with Orbit! Please click on the following link and confirm. This is to make sure we could provide you with a spam free experience. Thanks a lot.

+ + +<%= link_to 'Click here to confirm', confirm_user_users_url(:token => @confirmation_token)%> \ No newline at end of file diff --git a/app/views/layouts/member.html.erb b/app/views/layouts/member.html.erb index bddf396..c46ea23 100644 --- a/app/views/layouts/member.html.erb +++ b/app/views/layouts/member.html.erb @@ -5,11 +5,9 @@ <%= render 'shared/meta' %> <%= render 'shared/google_font' %> <%= stylesheet_link_tag "member" %> - <%= stylesheet_link_tag params[:controller] %> <%= yield :page_specific_css %> <%= render 'shared/ie_html5_fix' %> <%= javascript_include_tag "member" %> - <%= javascript_include_tag params[:controller] %> <%= yield :page_specific_javascript %> <%= csrf_meta_tag %> diff --git a/app/views/passwords/edit.html.erb b/app/views/passwords/edit.html.erb new file mode 100644 index 0000000..db828cc --- /dev/null +++ b/app/views/passwords/edit.html.erb @@ -0,0 +1,31 @@ +
+ +
\ No newline at end of file diff --git a/app/views/passwords/new.html.erb b/app/views/passwords/new.html.erb new file mode 100644 index 0000000..868f5c0 --- /dev/null +++ b/app/views/passwords/new.html.erb @@ -0,0 +1,30 @@ +
+ +
\ No newline at end of file diff --git a/app/views/reset_password_mailer/reset_user_password.html.erb b/app/views/reset_password_mailer/reset_user_password.html.erb new file mode 100644 index 0000000..e1993c6 --- /dev/null +++ b/app/views/reset_password_mailer/reset_user_password.html.erb @@ -0,0 +1,4 @@ +

Please Reset your password with the following instructions

+ + +<%= link_to 'Click here to confirm', edit_password_url(:token => @reset_token, :id => @user_id)%> \ No newline at end of file diff --git a/config/environments/development.rb b/config/environments/development.rb index 4f2b305..ae34a24 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -24,4 +24,7 @@ Orbit::Application.configure do # This option may cause significant delays in view rendering with a large # number of complex assets. config.assets.debug = true + config.action_mailer.delivery_method = :smtp + config.action_mailer.smtp_settings = { :address => "localhost", :port => 1025 } + config.action_mailer.default_url_options = { host: "localhost:3000", protocol: "http" } end diff --git a/config/routes.rb b/config/routes.rb index d4d6d68..c148ad6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -34,11 +34,23 @@ Orbit::Application.routes.draw do locales = Site.first.in_use_locales rescue I18n.available_locales scope "(:locale)", locale: Regexp.new(locales.join("|")) do - resources :users + resources :users do + collection do + get 'confirm_user' + get 'post_confirmation' + end + end + + resources :passwords namespace :admin do resources :dashboards resources :members + resources :roles do + get 'role_field' + post 'toggle' + end + resources :module_apps get 'authorizations(/:module(/:type(/:id)))' => 'authorizations#index', :as => :authorizations diff --git a/lib/orbit_app/plugin/registration.rb b/lib/orbit_app/plugin/registration.rb new file mode 100644 index 0000000..d549555 --- /dev/null +++ b/lib/orbit_app/plugin/registration.rb @@ -0,0 +1,99 @@ +module OrbitApp + module Plugin + module Registration + Version = "0.5" + + module ClassMethods + self.registrations = [] + + def new( name ,&block) + self.registrations << DataSheet.new(name,&block) + end + + def new_from_module_app(name,key,base_path,*args) + self.registrations << DataSheet.new(name,args,:base_path=>base_path) + end + + def find_by_app_name(name) + self.registrations.each{|t| + return t if t.app_name == name + } + return nil + end + + def find_by_key(key) + self.registrations.each{|t| + return t if t.name == key + } + return nil + end + + def all + return self.registrations + end + end + + extend ClassMethods + def self.included( other ) + other.extend( ClassMethods ) + end + + class DataSheet + attr_reader :name + attr_reader :base_path + + def name + if @name.is_a? Proc + @name.call + else + @name + end + end + + def initialize(name,partial=nil,*args ,&block) + @base_path = args[0][:base_path] + @name = partial[0][:i18n].nil? ? name : lambda{ I18n.t(partial[0][:i18n]) } + @sort_number = partial[0][:sort_number] + @app_name = partial[0][:app_name] + @intro_app_name = partial[0][:intro_app_name] + @partial_path = '' + @front_partial_path = '' + @admin_partial_path = '' + + unless partial.nil? + @partial_path = partial[0][:path] + @front_partial_path = partial[0][:front_path] + @admin_partial_path = partial[0][:admin_path] + end + + block.arity < 1 ? instance_eval(&block) : block.call(self) if block_given? + end + + def sort_number + return @sort_number + end + + def app_name + return @app_name + end + + def intro_app_name + return @intro_app_name + end + + def profile_partial_path + return @partial_path + end + + def front_partial_path + return @front_partial_path + end + + def admin_partial_path + return @admin_partial_path + end + + end + end + end +end \ No newline at end of file diff --git a/lib/orbit_app/register_module.rb b/lib/orbit_app/register_module.rb index 71cec03..6f3a5cf 100644 --- a/lib/orbit_app/register_module.rb +++ b/lib/orbit_app/register_module.rb @@ -4,6 +4,8 @@ module OrbitApp def registration(name,type ={:type=> "ModuleApp"} ,&block) if type[:type].eql?("ModuleApp") Module::Registration.new(name,&block) + elsif type[:type] == "PersonalPlugin" + Plugin::Registration.new(name,&block) end end end diff --git a/test/controllers/admin/roles_controller_test.rb b/test/controllers/admin/roles_controller_test.rb new file mode 100644 index 0000000..48d7fc2 --- /dev/null +++ b/test/controllers/admin/roles_controller_test.rb @@ -0,0 +1,9 @@ +require 'test_helper' + +class Admin::RolesControllerTest < ActionController::TestCase + test "should get index" do + get :index + assert_response :success + end + +end diff --git a/test/controllers/password_controller_test.rb b/test/controllers/password_controller_test.rb new file mode 100644 index 0000000..63cbba1 --- /dev/null +++ b/test/controllers/password_controller_test.rb @@ -0,0 +1,9 @@ +require 'test_helper' + +class PasswordControllerTest < ActionController::TestCase + test "should get forgot_password" do + get :forgot_password + assert_response :success + end + +end diff --git a/test/fixtures/role_fields.yml b/test/fixtures/role_fields.yml new file mode 100644 index 0000000..ddd653b --- /dev/null +++ b/test/fixtures/role_fields.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + key: MyString + title: MyString + +two: + key: MyString + title: MyString diff --git a/test/helpers/admin/roles_helper_test.rb b/test/helpers/admin/roles_helper_test.rb new file mode 100644 index 0000000..7574f79 --- /dev/null +++ b/test/helpers/admin/roles_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class Admin::RolesHelperTest < ActionView::TestCase +end diff --git a/test/helpers/password_helper_test.rb b/test/helpers/password_helper_test.rb new file mode 100644 index 0000000..2582160 --- /dev/null +++ b/test/helpers/password_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class PasswordHelperTest < ActionView::TestCase +end diff --git a/test/mailers/confirm_user_mailer_test.rb b/test/mailers/confirm_user_mailer_test.rb new file mode 100644 index 0000000..38bc225 --- /dev/null +++ b/test/mailers/confirm_user_mailer_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ConfirmUserMailerTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/mailers/previews/confirm_user_mailer_preview.rb b/test/mailers/previews/confirm_user_mailer_preview.rb new file mode 100644 index 0000000..d6ee335 --- /dev/null +++ b/test/mailers/previews/confirm_user_mailer_preview.rb @@ -0,0 +1,4 @@ +# Preview all emails at http://localhost:3000/rails/mailers/confirm_user_mailer +class ConfirmUserMailerPreview < ActionMailer::Preview + +end diff --git a/test/mailers/previews/reset_password_mailer_preview.rb b/test/mailers/previews/reset_password_mailer_preview.rb new file mode 100644 index 0000000..d20ba81 --- /dev/null +++ b/test/mailers/previews/reset_password_mailer_preview.rb @@ -0,0 +1,4 @@ +# Preview all emails at http://localhost:3000/rails/mailers/reset_password_mailer +class ResetPasswordMailerPreview < ActionMailer::Preview + +end diff --git a/test/mailers/reset_password_mailer_test.rb b/test/mailers/reset_password_mailer_test.rb new file mode 100644 index 0000000..c9a093e --- /dev/null +++ b/test/mailers/reset_password_mailer_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ResetPasswordMailerTest < ActionMailer::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/role_field_test.rb b/test/models/role_field_test.rb new file mode 100644 index 0000000..ccc7ea7 --- /dev/null +++ b/test/models/role_field_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class RoleFieldTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end