diff options
Diffstat (limited to 'app')
m--------- | app/assets/javascripts/srp | 0 | ||||
-rw-r--r-- | app/assets/javascripts/users.js | 25 | ||||
-rw-r--r-- | app/models/account.rb | 11 | ||||
-rw-r--r-- | app/models/invite_code.rb | 23 | ||||
-rw-r--r-- | app/models/invite_code_validator.rb | 29 | ||||
-rw-r--r-- | app/models/user.rb | 6 | ||||
-rw-r--r-- | app/views/users/new.html.haml | 12 |
7 files changed, 99 insertions, 7 deletions
diff --git a/app/assets/javascripts/srp b/app/assets/javascripts/srp -Subproject 8f33d32d40b1e21ae7fb9a92c78a275422af421 +Subproject 9e1a41733468d4a3f5102b04277b9cd7b52d0a4 diff --git a/app/assets/javascripts/users.js b/app/assets/javascripts/users.js index e0f1c9d..5217942 100644 --- a/app/assets/javascripts/users.js +++ b/app/assets/javascripts/users.js @@ -88,11 +88,34 @@ } }; + var account = { + + // Returns the user's identity + login: function() { + return document.getElementById("srp_username").value; + }, + + // Returns the password currently typed in + password: function() { + return document.getElementById("srp_password").value; + }, + + // The user's id + id: function() { + return document.getElementById("user_param").value; + }, + + // Returns the invite code currently typed in + loginParams: function () { + return { "invite_code": document.getElementById("srp_invite_code").value }; + } + } + // // PUBLIC FUNCTIONS // - srp.session = new srp.Session(); + srp.session = new srp.Session(account); srp.signedUp = function() { return srp.login(); diff --git a/app/models/account.rb b/app/models/account.rb index af470ed..a5cd833 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -1,7 +1,7 @@ # -# The Account model takes care of the livecycle of a user. +# The Account model takes care of the lifecycle of a user. # It composes a User record and it's identity records. -# It also allows for other engines to hook into the livecycle by +# It also allows for other engines to hook into the lifecycle by # monkeypatching the create, update and destroy methods. # There's an ActiveSupport load_hook at the end of this file to # make this more easy. @@ -20,6 +20,7 @@ class Account user = nil user = User.new(attrs) user.save + if !user.tmp? && user.persisted? identity = user.identity identity.user_id = user.id @@ -27,6 +28,12 @@ class Account identity.errors.each do |attr, msg| user.errors.add(attr, msg) end + + if APP_CONFIG[:invite_required] + user_invite_code = InviteCode.find_by_invite_code user.invite_code + user_invite_code.invite_count += 1 + user_invite_code.save + end end rescue StandardError => ex user.errors.add(:base, ex.to_s) if user diff --git a/app/models/invite_code.rb b/app/models/invite_code.rb new file mode 100644 index 0000000..13c3a39 --- /dev/null +++ b/app/models/invite_code.rb @@ -0,0 +1,23 @@ +require 'coupon_code' + +class InviteCode < CouchRest::Model::Base + use_database 'invite_codes' + property :invite_code, String, :read_only => true + property :invite_count, Integer, :default => 0, :accessible => true + property :max_uses, Integer, :default => 1 + + timestamps! + + design do + view :by_invite_code + view :by_invite_count + end + + def initialize(attributes = {}, options = {}) + super(attributes, options) + write_attribute('invite_code', CouponCode.generate) if new? + end + +end + + diff --git a/app/models/invite_code_validator.rb b/app/models/invite_code_validator.rb new file mode 100644 index 0000000..676e4fa --- /dev/null +++ b/app/models/invite_code_validator.rb @@ -0,0 +1,29 @@ +class InviteCodeValidator < ActiveModel::Validator + + def validate(user) + + user_invite_code = InviteCode.find_by_invite_code user.invite_code + + if not_existent?(user_invite_code) + add_error_to_user("This is not a valid code", user) + + elsif has_no_uses_left?(user_invite_code) + add_error_to_user("This code has already been used", user) + end + end + + private + def not_existent?(code) + code == nil + end + + def has_no_uses_left?(code) + code.invite_count >= code.max_uses + end + + def add_error_to_user(error, user) + user.errors[:invite_code] << error + end +end + + diff --git a/app/models/user.rb b/app/models/user.rb index d44df40..3daee0f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -8,7 +8,7 @@ class User < CouchRest::Model::Base property :password_salt, String, :accessible => true property :contact_email, String, :accessible => true property :contact_email_key, String, :accessible => true - + property :invite_code, String, :accessible => true property :enabled, TrueClass, :default => true # these will be null by default but we shouldn't ever pull them directly, but only via the methods that will return the full ServiceLevel @@ -39,6 +39,10 @@ class User < CouchRest::Model::Base :email => true, :mx_with_fallback => true + + validates_with InviteCodeValidator, on: :create, if: -> {APP_CONFIG[:invite_required]} + + timestamps! design do diff --git a/app/views/users/new.html.haml b/app/views/users/new.html.haml index 41a9d55..bc0b1af 100644 --- a/app/views/users/new.html.haml +++ b/app/views/users/new.html.haml @@ -15,7 +15,13 @@ = render :partial => 'warnings' = simple_form_for(@user, form_options) do |f| = f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username } - = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password } - = f.input :password_confirmation, :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation } - = f.button :wrapped, cancel: home_path + = f.input :password, :label => t(:password), :required => false, :validate => true, :input_html => { :id => :srp_password } + = f.input :password_confirmation, :label => t(:password_confirmation), :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation } + + - if APP_CONFIG[:invite_required] + = f.input :invite_code, :label => t(:invite_code), :input_html => { :id => :srp_invite_code } + - else + = f.input :invite_code, :as => "hidden", :input_html => { :value => " ", :id => :srp_invite_code } + = f.button :wrapped, cancel: home_path +-# |