unsakini 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +34 -0
- data/angular/README.md +31 -0
- data/angular/angular-cli.json +59 -0
- data/angular/karma.conf.js +45 -0
- data/angular/package.json +49 -0
- data/angular/protractor.conf.js +32 -0
- data/angular/src/app/app.component.css +0 -0
- data/angular/src/app/app.component.html +4 -0
- data/angular/src/app/app.component.spec.ts +47 -0
- data/angular/src/app/app.component.ts +10 -0
- data/angular/src/app/app.module.ts +29 -0
- data/angular/src/app/app.routes.module.ts +29 -0
- data/angular/src/app/index.ts +2 -0
- data/angular/src/app/registration/registration.component.css +0 -0
- data/angular/src/app/registration/registration.component.html +14 -0
- data/angular/src/app/registration/registration.component.spec.ts +157 -0
- data/angular/src/app/registration/registration.component.ts +42 -0
- data/angular/src/environments/environment.prod.ts +3 -0
- data/angular/src/environments/environment.ts +8 -0
- data/angular/src/favicon.ico +0 -0
- data/angular/src/index.html +14 -0
- data/angular/src/main.ts +12 -0
- data/angular/src/polyfills.ts +19 -0
- data/angular/src/styles.css +1 -0
- data/angular/src/test.ts +31 -0
- data/angular/src/tsconfig.json +18 -0
- data/angular/src/typings.d.ts +2 -0
- data/angular/tslint.json +114 -0
- data/angular/typings.json +4 -0
- data/app/controllers/api/boards_controller.rb +67 -0
- data/app/controllers/api/comments_controller.rb +51 -0
- data/app/controllers/api/posts_controller.rb +58 -0
- data/app/controllers/api/share_board_controller.rb +118 -0
- data/app/controllers/api/users_controller.rb +27 -0
- data/app/controllers/application_controller.rb +5 -0
- data/app/controllers/concerns/board_owner_controller_concern.rb +38 -0
- data/app/controllers/concerns/comment_owner_controller_concern.rb +33 -0
- data/app/controllers/concerns/logged_in_controller_concern.rb +21 -0
- data/app/controllers/concerns/post_owner_controller_concern.rb +36 -0
- data/app/controllers/concerns/serializer_controller_concern.rb +11 -0
- data/app/controllers/user_token_controller.rb +2 -0
- data/app/controllers/web_base_controller.rb +11 -0
- data/app/models/application_record.rb +5 -0
- data/app/models/board.rb +14 -0
- data/app/models/comment.rb +9 -0
- data/app/models/concerns/encryptable_model_concern.rb +96 -0
- data/app/models/post.rb +12 -0
- data/app/models/user.rb +6 -0
- data/app/models/user_board.rb +71 -0
- data/app/serializers/board_serializer.rb +5 -0
- data/app/serializers/comment_serializer.rb +10 -0
- data/app/serializers/post_serializer.rb +23 -0
- data/app/serializers/user_board_serializer.rb +10 -0
- data/app/serializers/user_serializer.rb +6 -0
- data/config/initializers/unsakini.rb +4 -0
- data/config/routes.rb +22 -0
- data/db/migrate/20161116114222_create_boards.rb +9 -0
- data/db/migrate/20161116200034_create_user_boards.rb +11 -0
- data/db/migrate/20161118031023_create_posts.rb +12 -0
- data/db/migrate/20161118100454_create_comments.rb +11 -0
- data/db/migrate/20161118221508_add_encrypted_password_to_user_board.rb +5 -0
- data/db/migrate/20161122211105_create_users.rb +12 -0
- data/lib/generators/unsakini/angular/USAGE +8 -0
- data/lib/generators/unsakini/angular/angular_generator.rb +7 -0
- data/lib/generators/unsakini/config/USAGE +8 -0
- data/lib/generators/unsakini/config/config_generator.rb +7 -0
- data/lib/generators/unsakini/config/templates/unsakini.rb +4 -0
- data/lib/tasks/unsakini_tasks.rake +33 -0
- data/lib/unsakini/engine.rb +30 -0
- data/lib/unsakini/version.rb +3 -0
- data/lib/unsakini.rb +5 -0
- data/spec/concerns/models/encryptable_concern.rb +40 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/angular/README.md +31 -0
- data/spec/dummy/angular/angular-cli.json +59 -0
- data/spec/dummy/angular/e2e/app.e2e-spec.ts +14 -0
- data/spec/dummy/angular/e2e/app.po.ts +11 -0
- data/spec/dummy/angular/e2e/signup.e2e-spec.ts +28 -0
- data/spec/dummy/angular/e2e/signup.po.ts +31 -0
- data/spec/dummy/angular/e2e/tsconfig.json +16 -0
- data/spec/dummy/angular/karma.conf.js +45 -0
- data/spec/dummy/angular/package.json +50 -0
- data/spec/dummy/angular/protractor.conf.js +32 -0
- data/spec/dummy/angular/src/app/app.component.css +0 -0
- data/spec/dummy/angular/src/app/app.component.html +4 -0
- data/spec/dummy/angular/src/app/app.component.spec.ts +47 -0
- data/spec/dummy/angular/src/app/app.component.ts +10 -0
- data/spec/dummy/angular/src/app/app.module.ts +29 -0
- data/spec/dummy/angular/src/app/app.routes.module.ts +29 -0
- data/spec/dummy/angular/src/app/index.ts +2 -0
- data/spec/dummy/angular/src/app/registration/registration.component.css +0 -0
- data/spec/dummy/angular/src/app/registration/registration.component.html +14 -0
- data/spec/dummy/angular/src/app/registration/registration.component.spec.ts +157 -0
- data/spec/dummy/angular/src/app/registration/registration.component.ts +42 -0
- data/spec/dummy/angular/src/environments/environment.prod.ts +3 -0
- data/spec/dummy/angular/src/environments/environment.ts +8 -0
- data/spec/dummy/angular/src/favicon.ico +0 -0
- data/spec/dummy/angular/src/index.html +14 -0
- data/spec/dummy/angular/src/main.ts +12 -0
- data/spec/dummy/angular/src/polyfills.ts +19 -0
- data/spec/dummy/angular/src/styles.css +1 -0
- data/spec/dummy/angular/src/test.ts +31 -0
- data/spec/dummy/angular/src/tsconfig.json +18 -0
- data/spec/dummy/angular/src/typings.d.ts +2 -0
- data/spec/dummy/angular/tslint.json +114 -0
- data/spec/dummy/angular/typings.json +4 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +34 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/config/application.rb +22 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +9 -0
- data/spec/dummy/config/crypto.yml +7 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +47 -0
- data/spec/dummy/config/environments/production.rb +78 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cors.rb +16 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/new_framework_defaults.rb +18 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/puma.rb +47 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +56 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/app/favicon.ico +0 -0
- data/spec/dummy/public/app/index.html +14 -0
- data/spec/dummy/public/app/inline.bundle.js +139 -0
- data/spec/dummy/public/app/inline.map +1 -0
- data/spec/dummy/public/app/main.bundle.js +64689 -0
- data/spec/dummy/public/app/main.map +1 -0
- data/spec/dummy/public/app/styles.bundle.js +364 -0
- data/spec/dummy/public/app/styles.map +1 -0
- data/spec/factories/boards.rb +5 -0
- data/spec/factories/comments.rb +7 -0
- data/spec/factories/posts.rb +8 -0
- data/spec/factories/user_boards.rb +9 -0
- data/spec/factories/users.rb +10 -0
- data/spec/models/board_spec.rb +19 -0
- data/spec/models/comment_spec.rb +26 -0
- data/spec/models/post_spec.rb +19 -0
- data/spec/models/user_board_spec.rb +193 -0
- data/spec/models/user_spec.rb +5 -0
- data/spec/rails_helper.rb +58 -0
- data/spec/requests/api/api_boards_spec.rb +238 -0
- data/spec/requests/api/api_share_board_spec.rb +167 -0
- data/spec/requests/api/api_users_spec.rb +52 -0
- data/spec/requests/api/board/api_board_posts_spec.rb +299 -0
- data/spec/requests/api/board/post/api_board_post_comments_spec.rb +370 -0
- data/spec/requests/render_app_index_spec.rb +19 -0
- data/spec/schema/board.json +39 -0
- data/spec/schema/comment.json +51 -0
- data/spec/schema/post.json +87 -0
- data/spec/schema/user.json +27 -0
- data/spec/spec_helper.rb +67 -0
- data/spec/support/auth_helper.rb +17 -0
- data/spec/support/scenario_helper.rb +134 -0
- data/spec/support/serialize_helper.rb +37 -0
- metadata +540 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Base controller for web pages
|
|
2
|
+
|
|
3
|
+
class WebBaseController < ActionController::Base
|
|
4
|
+
include ActionController::ImplicitRender
|
|
5
|
+
include ActionView::Layouts
|
|
6
|
+
|
|
7
|
+
# Renders the angular index view when request url is /app/* to enable html5 pushState capability of angularjs
|
|
8
|
+
def app
|
|
9
|
+
render file: "#{Rails.root}/public/app/index.html", layout: false
|
|
10
|
+
end
|
|
11
|
+
end
|
data/app/models/board.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#Board model
|
|
2
|
+
|
|
3
|
+
class Board < ApplicationRecord
|
|
4
|
+
include EncryptableModelConcern
|
|
5
|
+
encryptable_attributes :name
|
|
6
|
+
|
|
7
|
+
validates :name, presence: true
|
|
8
|
+
|
|
9
|
+
has_many :users, through: :user_boards
|
|
10
|
+
|
|
11
|
+
has_many :user_boards, :dependent => :delete_all
|
|
12
|
+
has_many :posts, :dependent => :destroy
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
require 'base64'
|
|
3
|
+
|
|
4
|
+
# Responsible for encryption and decryption of certain model attributes
|
|
5
|
+
|
|
6
|
+
module EncryptableModelConcern
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
included do
|
|
10
|
+
before_save :encrypt_encryptable_attributes
|
|
11
|
+
after_save :decrypt_encryptable_attributes
|
|
12
|
+
after_find :decrypt_encryptable_attributes
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module ClassMethods
|
|
16
|
+
# Sets the `encryptable_attributes` class instance variable in the model.
|
|
17
|
+
#
|
|
18
|
+
# Encryptable attributes are encrypted before saving using `before_save` hook and decrypted using `after_save` and `after_find` hooks.
|
|
19
|
+
#
|
|
20
|
+
# Example:
|
|
21
|
+
# ```
|
|
22
|
+
# class Board < BaseModel
|
|
23
|
+
# encryptable_attributes :name, :title, :content
|
|
24
|
+
# end
|
|
25
|
+
# ```
|
|
26
|
+
# @param attrs [Symbol] model attributes
|
|
27
|
+
#
|
|
28
|
+
def encryptable_attributes(*attrs)
|
|
29
|
+
@encryptable_attributes = attrs
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns the model's `encryptable_attributes` class instance variable.
|
|
35
|
+
#
|
|
36
|
+
def encryptable_attributes
|
|
37
|
+
self.class.instance_variable_get(:@encryptable_attributes) || []
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
# Encryptes the model's encryptable attributes before saving using Rails' `before_save` hook.
|
|
42
|
+
#
|
|
43
|
+
# **Note: Be careful in calling this method manually as it can corrupt the data.**
|
|
44
|
+
def encrypt_encryptable_attributes
|
|
45
|
+
encryptable_attributes.each do |k|
|
|
46
|
+
self[k] = encrypt(self[k])
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Decrypts the model's encryptable attributes using Rails' `after_save` and `after_find` hooks.
|
|
51
|
+
#
|
|
52
|
+
# **Note: Be careful in calling this method manually as it can corrupt the data.**
|
|
53
|
+
def decrypt_encryptable_attributes
|
|
54
|
+
encryptable_attributes.each do |k|
|
|
55
|
+
self[k] = decrypt(self[k])
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Determins if the value being encrypted/decryped is empty.
|
|
60
|
+
def is_empty_val(value)
|
|
61
|
+
!value or value.nil? or value == ""
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Returns the cipher algorithm used
|
|
65
|
+
def cipher
|
|
66
|
+
OpenSSL::Cipher::Cipher.new('aes-256-cbc')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Returns the encryption key from the `unsakini_crypto_key` config
|
|
70
|
+
def cipher_key
|
|
71
|
+
begin
|
|
72
|
+
Rails.configuration.unsakini_crypto_key
|
|
73
|
+
rescue Exception => e
|
|
74
|
+
raise 'Encryption key is not set! Please run `rails g unsakini:config` before you proceed.'
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Encrypts model attribute value
|
|
79
|
+
def encrypt(value)
|
|
80
|
+
return value if is_empty_val(value)
|
|
81
|
+
c = cipher.encrypt
|
|
82
|
+
c.key = Digest::SHA256.digest(cipher_key)
|
|
83
|
+
c.iv = iv = c.random_iv
|
|
84
|
+
Base64.encode64(iv) + Base64.encode64(c.update(value.to_s) + c.final)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Decrypts model attribute value
|
|
88
|
+
def decrypt(value)
|
|
89
|
+
return value if is_empty_val(value)
|
|
90
|
+
c = cipher.decrypt
|
|
91
|
+
c.key = Digest::SHA256.digest(cipher_key)
|
|
92
|
+
c.iv = Base64.decode64 value.slice!(0,25)
|
|
93
|
+
c.update(Base64.decode64(value.to_s)) + c.final
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
data/app/models/post.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#Post model
|
|
2
|
+
|
|
3
|
+
class Post < ApplicationRecord
|
|
4
|
+
include EncryptableModelConcern
|
|
5
|
+
encryptable_attributes :title, :content
|
|
6
|
+
validates :title, presence: true
|
|
7
|
+
validates :content, presence: true
|
|
8
|
+
|
|
9
|
+
belongs_to :user
|
|
10
|
+
belongs_to :board
|
|
11
|
+
has_many :comments, :dependent => :delete_all
|
|
12
|
+
end
|
data/app/models/user.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# UserBoard model, links the user and it's boards
|
|
2
|
+
|
|
3
|
+
class UserBoard < ApplicationRecord
|
|
4
|
+
include EncryptableModelConcern
|
|
5
|
+
encryptable_attributes :encrypted_password
|
|
6
|
+
|
|
7
|
+
validates :encrypted_password, :presence => true, if: :is_admin
|
|
8
|
+
|
|
9
|
+
before_validation :validate_before_create, on: :create
|
|
10
|
+
before_validation :validate_before_update, on: :update
|
|
11
|
+
|
|
12
|
+
belongs_to :user
|
|
13
|
+
belongs_to :board
|
|
14
|
+
|
|
15
|
+
def name=(str)
|
|
16
|
+
@name = str
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def name
|
|
20
|
+
if !@name.nil?
|
|
21
|
+
@name
|
|
22
|
+
else
|
|
23
|
+
self.board.name
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def share(user_ids, new_key)
|
|
28
|
+
ActiveRecord::Base.transaction do
|
|
29
|
+
user_ids.each do |usr_id|
|
|
30
|
+
UserBoard.new({
|
|
31
|
+
user_id: usr_id,
|
|
32
|
+
board_id: self.board_id,
|
|
33
|
+
encrypted_password: nil,
|
|
34
|
+
is_admin: false
|
|
35
|
+
})
|
|
36
|
+
.save!
|
|
37
|
+
end
|
|
38
|
+
self.encrypted_password = new_key
|
|
39
|
+
self.save!
|
|
40
|
+
end
|
|
41
|
+
true
|
|
42
|
+
|
|
43
|
+
rescue
|
|
44
|
+
self.errors[:base] << "Unable to share the this board"
|
|
45
|
+
false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def reset_user_boards_encrypted_password
|
|
51
|
+
UserBoard.where("board_id = ? AND user_id != ?", self.board_id, self.user_id).update_all(encrypted_password: nil)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def validate_before_create
|
|
55
|
+
if self.board.nil?
|
|
56
|
+
b = Board.new(name: @name)
|
|
57
|
+
if b.save
|
|
58
|
+
self.board_id = b.id
|
|
59
|
+
else
|
|
60
|
+
self.errors[:base] << "Board name is invalid"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def validate_before_update
|
|
66
|
+
self.board.name = @name if !@name.blank?
|
|
67
|
+
reset_user_boards_encrypted_password if self.encrypted_password_changed?
|
|
68
|
+
self.errors[:base] << "Board name is invalid" if !self.board.save
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Serializes the {Comment} model instance to json.
|
|
2
|
+
# Read more about active model serializers - https://github.com/rails-api/active_model_serializers
|
|
3
|
+
|
|
4
|
+
class CommentSerializer < ActiveModel::Serializer
|
|
5
|
+
|
|
6
|
+
attributes :id, :content, :created_at, :updated_at
|
|
7
|
+
|
|
8
|
+
belongs_to :user
|
|
9
|
+
|
|
10
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Serializes the `Post` model instance to json.
|
|
2
|
+
# Read more about active model serializers - https://github.com/rails-api/active_model_serializers
|
|
3
|
+
|
|
4
|
+
class PostSerializer < ActiveModel::Serializer
|
|
5
|
+
|
|
6
|
+
attributes :id, :title, :content, :created_at, :updated_at
|
|
7
|
+
|
|
8
|
+
belongs_to :user
|
|
9
|
+
|
|
10
|
+
belongs_to :board do |serializer|
|
|
11
|
+
user_board = object.board.user_boards.where(user_id: object.user_id).first
|
|
12
|
+
|
|
13
|
+
{
|
|
14
|
+
"id" => object.board.id,
|
|
15
|
+
"name" => object.board.name,
|
|
16
|
+
"is_admin" => user_board.is_admin,
|
|
17
|
+
"encrypted_password" => user_board.encrypted_password,
|
|
18
|
+
"created_at" => object.board.created_at,
|
|
19
|
+
"updated_at" => object.board.updated_at
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Serializes the `UserBoard` model instance to json.
|
|
2
|
+
# Read more about active model serializers - https://github.com/rails-api/active_model_serializers
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
class UserBoardSerializer < ActiveModel::Serializer
|
|
6
|
+
attributes :id, :is_admin, :encrypted_password, :created_at, :updated_at
|
|
7
|
+
belongs_to :board
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
end
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Rails.application.routes.draw do
|
|
2
|
+
|
|
3
|
+
post 'user_token' => 'user_token#create'
|
|
4
|
+
|
|
5
|
+
# ng2 html5 pushState routes
|
|
6
|
+
get 'app', to: 'web_base#app'
|
|
7
|
+
get 'app/*ngroute', to: 'web_base#app'
|
|
8
|
+
|
|
9
|
+
namespace :api do
|
|
10
|
+
resource :user
|
|
11
|
+
resources :boards do
|
|
12
|
+
resources :posts do
|
|
13
|
+
resources :comments, only: [:index, :create, :update, :destroy]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
post '/api/share/board/', to: 'share_board#index', as: 'share_board'
|
|
18
|
+
get '/api/users/search', to: 'users#search', as: 'user_search'
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
namespace :unsakini do
|
|
2
|
+
|
|
3
|
+
desc "Initializes the angular app in ./angular directory."
|
|
4
|
+
task :build do
|
|
5
|
+
|
|
6
|
+
ng_dir = 'angular'
|
|
7
|
+
lib_dir = "#{File.expand_path File.dirname(__FILE__)}"
|
|
8
|
+
lib_dir.slice!("/lib/tasks")
|
|
9
|
+
|
|
10
|
+
begin
|
|
11
|
+
Dir.chdir "#{Rails.root}/#{ng_dir}" do
|
|
12
|
+
|
|
13
|
+
cmd = ''
|
|
14
|
+
cmd += 'npm i;'
|
|
15
|
+
cmd += "#{Rails.root}/#{ng_dir}/node_modules/.bin/ng build"
|
|
16
|
+
cmd += " --prod" if Rails.env.production?
|
|
17
|
+
puts "Running #{cmd}"
|
|
18
|
+
system(cmd)
|
|
19
|
+
|
|
20
|
+
puts "Done installing angular assets."
|
|
21
|
+
end
|
|
22
|
+
rescue Exception => e
|
|
23
|
+
puts \
|
|
24
|
+
"
|
|
25
|
+
|
|
26
|
+
Please run `rails g unsakini:angular` before you proceed.
|
|
27
|
+
|
|
28
|
+
"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
module Unsakini
|
|
4
|
+
class Engine < ::Rails::Engine
|
|
5
|
+
|
|
6
|
+
config.generators.api_only = true
|
|
7
|
+
|
|
8
|
+
config.generators do |g|
|
|
9
|
+
g.test_framework :rspec, :fixture => false
|
|
10
|
+
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
|
11
|
+
g.assets false
|
|
12
|
+
g.helper false
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# config.middleware.insert_before 0, Rack::Cors do
|
|
16
|
+
# allow do
|
|
17
|
+
# origins '*'
|
|
18
|
+
# resource '*', :headers => :any, :methods => [:get, :post, :options]
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# http://stackoverflow.com/questions/4065699/rails-3-engine-provide-config-for-users
|
|
25
|
+
def self.setup(&block)
|
|
26
|
+
yield Engine.config if block
|
|
27
|
+
Engine.config
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
data/lib/unsakini.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
shared_examples_for "encryptable" do |attributes|
|
|
4
|
+
let(:model) { described_class } # the class that includes the concern
|
|
5
|
+
|
|
6
|
+
let(:model_instance) {
|
|
7
|
+
build(described_class.to_s.underscore.to_sym)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
it "has encryptable attributes" do
|
|
11
|
+
expect(model_instance.encryptable_attributes).not_to be_empty
|
|
12
|
+
expect(model_instance.encryptable_attributes).to eq(attributes)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "encrypts and decrypts encryptable attributes" do
|
|
16
|
+
model_hash = parse_json(model_instance.to_json)
|
|
17
|
+
model_instance.save
|
|
18
|
+
where_param = Hash.new
|
|
19
|
+
model_instance.encryptable_attributes.each do |variable|
|
|
20
|
+
where_param[variable] = model_hash[variable.to_s]
|
|
21
|
+
end
|
|
22
|
+
expect(model.where(where_param).count).to eq 0
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "encrypts data before saving and decrypts it after saving" do
|
|
26
|
+
expect(model_instance).to receive(:encrypt_encryptable_attributes)
|
|
27
|
+
expect(model_instance).to receive(:decrypt_encryptable_attributes)
|
|
28
|
+
model_instance.save validate: false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "decrypts data after find" do
|
|
32
|
+
model_hash = parse_json(model_instance.to_json)
|
|
33
|
+
model_instance.save validate: false
|
|
34
|
+
find_model_instance = model.find_by_id(model_instance.id)
|
|
35
|
+
find_model_instance.encryptable_attributes.each do |attribute|
|
|
36
|
+
expect(find_model_instance.send(attribute)).to eq(model_hash[attribute.to_s])
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
data/spec/dummy/Rakefile
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Angular
|
|
2
|
+
|
|
3
|
+
This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.20-4.
|
|
4
|
+
|
|
5
|
+
## Development server
|
|
6
|
+
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
|
|
7
|
+
|
|
8
|
+
## Code scaffolding
|
|
9
|
+
|
|
10
|
+
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class`.
|
|
11
|
+
|
|
12
|
+
## Build
|
|
13
|
+
|
|
14
|
+
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
|
|
15
|
+
|
|
16
|
+
## Running unit tests
|
|
17
|
+
|
|
18
|
+
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
19
|
+
|
|
20
|
+
## Running end-to-end tests
|
|
21
|
+
|
|
22
|
+
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
|
|
23
|
+
Before running the tests make sure you are serving the app via `ng serve`.
|
|
24
|
+
|
|
25
|
+
## Deploying to Github Pages
|
|
26
|
+
|
|
27
|
+
Run `ng github-pages:deploy` to deploy to Github Pages.
|
|
28
|
+
|
|
29
|
+
## Further help
|
|
30
|
+
|
|
31
|
+
To get more help on the `angular-cli` use `ng --help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"project": {
|
|
3
|
+
"version": "1.0.0-beta.20-4",
|
|
4
|
+
"name": "angular"
|
|
5
|
+
},
|
|
6
|
+
"apps": [
|
|
7
|
+
{
|
|
8
|
+
"root": "src",
|
|
9
|
+
"outDir": "../public/app",
|
|
10
|
+
"assets": [
|
|
11
|
+
"assets",
|
|
12
|
+
"favicon.ico"
|
|
13
|
+
],
|
|
14
|
+
"index": "index.html",
|
|
15
|
+
"main": "main.ts",
|
|
16
|
+
"test": "test.ts",
|
|
17
|
+
"tsconfig": "tsconfig.json",
|
|
18
|
+
"prefix": "app",
|
|
19
|
+
"mobile": false,
|
|
20
|
+
"styles": [
|
|
21
|
+
"styles.css"
|
|
22
|
+
],
|
|
23
|
+
"scripts": [],
|
|
24
|
+
"environments": {
|
|
25
|
+
"source": "environments/environment.ts",
|
|
26
|
+
"dev": "environments/environment.ts",
|
|
27
|
+
"prod": "environments/environment.prod.ts"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"addons": [],
|
|
32
|
+
"packages": [],
|
|
33
|
+
"e2e": {
|
|
34
|
+
"protractor": {
|
|
35
|
+
"config": "./protractor.conf.js"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"test": {
|
|
39
|
+
"karma": {
|
|
40
|
+
"config": "./karma.conf.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"defaults": {
|
|
44
|
+
"styleExt": "css",
|
|
45
|
+
"prefixInterfaces": false,
|
|
46
|
+
"inline": {
|
|
47
|
+
"style": false,
|
|
48
|
+
"template": false
|
|
49
|
+
},
|
|
50
|
+
"spec": {
|
|
51
|
+
"class": false,
|
|
52
|
+
"component": true,
|
|
53
|
+
"directive": true,
|
|
54
|
+
"module": false,
|
|
55
|
+
"pipe": true,
|
|
56
|
+
"service": true
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|