unsakini 0.0.4.pre.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -27
  3. data/angular/angular-cli.json +3 -5
  4. data/{public/unsakini/app → angular/dist}/favicon.ico +0 -0
  5. data/angular/dist/index.html +14 -0
  6. data/angular/dist/inline.bundle.js +139 -0
  7. data/angular/dist/inline.map +1 -0
  8. data/angular/dist/main.bundle.js +64689 -0
  9. data/angular/dist/main.map +1 -0
  10. data/angular/dist/styles.bundle.js +364 -0
  11. data/angular/dist/styles.map +1 -0
  12. data/angular/package.json +1 -4
  13. data/angular/src/app/app.component.html +4 -1
  14. data/angular/src/app/app.module.ts +7 -8
  15. data/angular/src/app/app.routes.module.ts +2 -12
  16. data/angular/src/app/index.ts +0 -2
  17. data/angular/src/app/registration/registration.component.html +12 -70
  18. data/angular/src/app/registration/registration.component.spec.ts +11 -8
  19. data/angular/src/app/registration/registration.component.ts +8 -10
  20. data/angular/src/environments/environment.prod.ts +1 -2
  21. data/angular/src/environments/environment.ts +1 -2
  22. data/angular/src/index.html +1 -1
  23. data/angular/src/styles.css +1 -0
  24. data/app/controllers/api/boards_controller.rb +73 -0
  25. data/app/controllers/api/comments_controller.rb +51 -0
  26. data/app/controllers/api/posts_controller.rb +58 -0
  27. data/app/controllers/api/share_board_controller.rb +118 -0
  28. data/app/controllers/api/users_controller.rb +40 -0
  29. data/app/controllers/application_controller.rb +2 -2
  30. data/app/controllers/concerns/board_owner_controller_concern.rb +38 -0
  31. data/app/controllers/concerns/comment_owner_controller_concern.rb +33 -0
  32. data/app/controllers/concerns/logged_in_controller_concern.rb +21 -0
  33. data/app/controllers/concerns/post_owner_controller_concern.rb +36 -0
  34. data/app/controllers/concerns/serializer_controller_concern.rb +11 -0
  35. data/app/controllers/user_token_controller.rb +2 -0
  36. data/app/controllers/web_base_controller.rb +23 -0
  37. data/app/models/application_record.rb +5 -0
  38. data/app/models/board.rb +14 -0
  39. data/app/models/comment.rb +9 -0
  40. data/app/models/concerns/encryptable_model_concern.rb +96 -0
  41. data/app/models/post.rb +12 -0
  42. data/app/models/user.rb +15 -0
  43. data/app/models/user_board.rb +82 -0
  44. data/app/serializers/board_serializer.rb +5 -0
  45. data/app/serializers/{unsakini/comment_serializer.rb → comment_serializer.rb} +3 -6
  46. data/app/serializers/post_serializer.rb +23 -0
  47. data/app/serializers/user_board_serializer.rb +11 -0
  48. data/app/serializers/{unsakini/user_serializer.rb → user_serializer.rb} +2 -5
  49. data/app/views/{unsakini/web → web_base}/index.html.erb +169 -65
  50. data/config/routes.rb +10 -10
  51. data/db/migrate/20161116114222_create_boards.rb +9 -0
  52. data/db/migrate/{20161116200034_create_unsakini_user_boards.rb → 20161116200034_create_user_boards.rb} +2 -3
  53. data/db/migrate/{20161118031023_create_unsakini_posts.rb → 20161118031023_create_posts.rb} +2 -2
  54. data/db/migrate/{20161118100454_create_unsakini_comments.rb → 20161118100454_create_comments.rb} +2 -2
  55. data/db/migrate/20161118221508_add_encrypted_password_to_user_board.rb +5 -0
  56. data/db/migrate/20161122211105_create_users.rb +12 -0
  57. data/db/migrate/20161124102633_add_is_shared_to_boards.rb +5 -0
  58. data/lib/generators/unsakini/angular/USAGE +8 -0
  59. data/lib/generators/unsakini/angular/angular_generator.rb +7 -0
  60. data/lib/generators/unsakini/config/config_generator.rb +1 -3
  61. data/lib/tasks/unsakini_tasks.rake +37 -6
  62. data/lib/unsakini/engine.rb +0 -2
  63. data/lib/unsakini/version.rb +1 -1
  64. data/public/css/custom.css +1 -5
  65. data/public/images/logo.svg +619 -0
  66. data/spec/concerns/models/encryptable_concern.rb +2 -3
  67. data/spec/controllers/{web_controller_spec.rb → web_base_controller_spec.rb} +3 -4
  68. data/spec/dummy/config/application.rb +1 -3
  69. data/spec/dummy/config/environments/development.rb +0 -2
  70. data/spec/dummy/config/initializers/assets.rb +11 -0
  71. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  72. data/spec/dummy/config/initializers/session_store.rb +3 -0
  73. data/spec/dummy/db/development.sqlite3 +0 -0
  74. data/spec/dummy/db/migrate/20161124210219_create_boards.unsakini_engine.rb +10 -0
  75. data/spec/dummy/db/migrate/20161124210220_create_user_boards.unsakini_engine.rb +12 -0
  76. data/spec/dummy/db/migrate/20161124210221_create_posts.unsakini_engine.rb +13 -0
  77. data/spec/dummy/db/migrate/20161124210222_create_comments.unsakini_engine.rb +12 -0
  78. data/spec/dummy/db/migrate/20161124210223_add_encrypted_password_to_user_board.unsakini_engine.rb +6 -0
  79. data/spec/dummy/db/migrate/20161124210224_create_users.unsakini_engine.rb +13 -0
  80. data/spec/dummy/db/migrate/20161124210225_add_is_shared_to_boards.unsakini_engine.rb +6 -0
  81. data/spec/dummy/db/schema.rb +14 -16
  82. data/spec/dummy/db/test.sqlite3 +0 -0
  83. data/spec/dummy/public/app/favicon.ico +0 -0
  84. data/spec/dummy/public/app/index.html +14 -0
  85. data/spec/dummy/public/app/inline.bundle.js +139 -0
  86. data/spec/dummy/public/app/inline.map +1 -0
  87. data/spec/dummy/public/app/main.bundle.js +64689 -0
  88. data/spec/dummy/public/app/main.map +1 -0
  89. data/spec/dummy/public/app/styles.bundle.js +364 -0
  90. data/spec/dummy/public/app/styles.map +1 -0
  91. data/spec/dummy/tmp/unsakini-ng2/LICENSE +21 -0
  92. data/spec/dummy/tmp/unsakini-ng2/README.md +1 -0
  93. data/spec/dummy/tmp/unsakini-ng2/angular-cli.json +59 -0
  94. data/spec/dummy/tmp/unsakini-ng2/e2e/app.e2e-spec.ts +14 -0
  95. data/spec/dummy/tmp/unsakini-ng2/e2e/app.po.ts +11 -0
  96. data/spec/dummy/tmp/unsakini-ng2/e2e/signup.e2e-spec.ts +28 -0
  97. data/spec/dummy/tmp/unsakini-ng2/e2e/signup.po.ts +31 -0
  98. data/spec/dummy/tmp/unsakini-ng2/e2e/tsconfig.json +16 -0
  99. data/spec/dummy/tmp/unsakini-ng2/karma.conf.js +45 -0
  100. data/spec/dummy/tmp/unsakini-ng2/package.json +49 -0
  101. data/spec/dummy/tmp/unsakini-ng2/protractor.conf.js +32 -0
  102. data/spec/dummy/tmp/unsakini-ng2/src/app/app.component.css +0 -0
  103. data/spec/dummy/tmp/unsakini-ng2/src/app/app.component.html +4 -0
  104. data/spec/dummy/tmp/unsakini-ng2/src/app/app.component.spec.ts +47 -0
  105. data/spec/dummy/tmp/unsakini-ng2/src/app/app.component.ts +10 -0
  106. data/spec/dummy/tmp/unsakini-ng2/src/app/app.module.ts +29 -0
  107. data/spec/dummy/tmp/unsakini-ng2/src/app/app.routes.module.ts +29 -0
  108. data/spec/dummy/tmp/unsakini-ng2/src/app/index.ts +2 -0
  109. data/spec/dummy/tmp/unsakini-ng2/src/app/registration/registration.component.css +0 -0
  110. data/spec/dummy/tmp/unsakini-ng2/src/app/registration/registration.component.html +14 -0
  111. data/spec/dummy/tmp/unsakini-ng2/src/app/registration/registration.component.spec.ts +157 -0
  112. data/spec/dummy/tmp/unsakini-ng2/src/app/registration/registration.component.ts +42 -0
  113. data/spec/dummy/tmp/unsakini-ng2/src/environments/environment.prod.ts +3 -0
  114. data/spec/dummy/tmp/unsakini-ng2/src/environments/environment.ts +8 -0
  115. data/spec/dummy/tmp/unsakini-ng2/src/favicon.ico +0 -0
  116. data/spec/dummy/tmp/unsakini-ng2/src/index.html +14 -0
  117. data/spec/dummy/tmp/unsakini-ng2/src/main.ts +12 -0
  118. data/spec/dummy/tmp/unsakini-ng2/src/polyfills.ts +19 -0
  119. data/spec/dummy/tmp/unsakini-ng2/src/styles.css +1 -0
  120. data/spec/dummy/tmp/unsakini-ng2/src/test.ts +31 -0
  121. data/spec/dummy/tmp/unsakini-ng2/src/tsconfig.json +18 -0
  122. data/spec/dummy/tmp/unsakini-ng2/src/typings.d.ts +2 -0
  123. data/spec/dummy/tmp/unsakini-ng2/tslint.json +114 -0
  124. data/spec/dummy/tmp/unsakini-ng2/typings.json +4 -0
  125. data/spec/factories/boards.rb +1 -1
  126. data/spec/factories/comments.rb +1 -1
  127. data/spec/factories/posts.rb +1 -1
  128. data/spec/factories/user_boards.rb +1 -1
  129. data/spec/factories/users.rb +1 -1
  130. data/spec/models/board_spec.rb +2 -2
  131. data/spec/models/comment_spec.rb +2 -2
  132. data/spec/models/post_spec.rb +2 -2
  133. data/spec/models/user_board_spec.rb +19 -19
  134. data/spec/models/user_spec.rb +1 -1
  135. data/spec/requests/{boards/boards_crud_spec.rb → api/boards/api_boards_crud_spec.rb} +26 -26
  136. data/spec/requests/{boards/boards_pagination_spec.rb → api/boards/api_boards_pagination_spec.rb} +7 -7
  137. data/spec/requests/{boards/private_board_spec.rb → api/boards/api_private_board_spec.rb} +26 -26
  138. data/spec/requests/{boards/shared_board_spec.rb → api/boards/api_shared_board_spec.rb} +9 -9
  139. data/spec/requests/{boards/sharing_board_spec.rb → api/boards/api_sharing_board_spec.rb} +13 -13
  140. data/spec/requests/{comments/comments_pagination_spec.rb → api/comments/api_comments_pagination_spec.rb} +3 -3
  141. data/spec/requests/{comments/comments_private_board_spec.rb → api/comments/api_comments_private_board_spec.rb} +20 -20
  142. data/spec/requests/{comments/comments_shared_board_spec.rb → api/comments/api_comments_shared_board_spec.rb} +17 -17
  143. data/spec/requests/{posts/posts_pagination_spec.rb → api/posts/api_posts_pagination_spec.rb} +3 -3
  144. data/spec/requests/{posts/posts_private_board_spec.rb → api/posts/api_posts_private_board_spec.rb} +22 -22
  145. data/spec/requests/{posts/posts_shared_board_spec.rb → api/posts/api_posts_shared_board_spec.rb} +24 -24
  146. data/spec/requests/{user/user_create_spec.rb → api/user/api_user_create_spec.rb} +23 -19
  147. data/spec/requests/{user/user_search_spec.rb → api/user/api_user_search_spec.rb} +9 -9
  148. data/spec/spec_helper.rb +0 -1
  149. data/spec/support/auth_helper.rb +2 -0
  150. metadata +202 -135
  151. data/angular/npm-debug.log +0 -54
  152. data/angular/src/app/confirm-account/confirm-account.component.ts +0 -27
  153. data/angular/src/app/confirm-account/confirm-account.html +0 -41
  154. data/angular/src/app/confirm-account/confirm-account.module.ts +0 -24
  155. data/angular/src/app/confirm-account/confirm-account.scss +0 -3
  156. data/angular/src/app/confirm-account/confirm-account.service.ts +0 -27
  157. data/angular/src/app/confirm-account/index.ts +0 -3
  158. data/angular/src/app/login/index.ts +0 -3
  159. data/angular/src/app/login/login.component.ts +0 -40
  160. data/angular/src/app/login/login.html +0 -43
  161. data/angular/src/app/login/login.module.ts +0 -27
  162. data/angular/src/app/login/login.service.ts +0 -48
  163. data/angular/src/app/registration/index.ts +0 -3
  164. data/angular/src/app/registration/registration.module.ts +0 -23
  165. data/angular/src/app/registration/registration.service.ts +0 -46
  166. data/angular/src/app/registration/registration.services.spec.ts +0 -71
  167. data/angular/src/app/services/auth-http/auth.http.service.ts +0 -35
  168. data/angular/src/app/services/auth-http/index.ts +0 -1
  169. data/angular/src/app/services/http/http.service.spec.ts +0 -205
  170. data/angular/src/app/services/http/http.service.ts +0 -40
  171. data/angular/src/app/services/http/index.ts +0 -1
  172. data/angular/src/app/services/index.ts +0 -3
  173. data/angular/src/app/services/services.module.ts +0 -33
  174. data/angular/src/assets/global.scss +0 -3
  175. data/angular/src/environments/custom.ts +0 -4
  176. data/app/controllers/concerns/unsakini/board_owner_controller_concern.rb +0 -42
  177. data/app/controllers/concerns/unsakini/comment_owner_controller_concern.rb +0 -36
  178. data/app/controllers/concerns/unsakini/logged_in_controller_concern.rb +0 -23
  179. data/app/controllers/concerns/unsakini/post_owner_controller_concern.rb +0 -38
  180. data/app/controllers/concerns/unsakini/serializer_controller_concern.rb +0 -13
  181. data/app/controllers/unsakini/base_controller.rb +0 -6
  182. data/app/controllers/unsakini/boards_controller.rb +0 -76
  183. data/app/controllers/unsakini/comments_controller.rb +0 -54
  184. data/app/controllers/unsakini/posts_controller.rb +0 -61
  185. data/app/controllers/unsakini/share_board_controller.rb +0 -122
  186. data/app/controllers/unsakini/user_token_controller.rb +0 -17
  187. data/app/controllers/unsakini/users_controller.rb +0 -69
  188. data/app/controllers/unsakini/web_controller.rb +0 -27
  189. data/app/mailers/unsakini/user_mailer.rb +0 -13
  190. data/app/models/concerns/unsakini/encryptable_model_concern.rb +0 -97
  191. data/app/models/unsakini/application_record.rb +0 -7
  192. data/app/models/unsakini/board.rb +0 -16
  193. data/app/models/unsakini/comment.rb +0 -12
  194. data/app/models/unsakini/post.rb +0 -15
  195. data/app/models/unsakini/user.rb +0 -43
  196. data/app/models/unsakini/user_board.rb +0 -84
  197. data/app/models/unsakini.rb +0 -5
  198. data/app/serializers/unsakini/board_serializer.rb +0 -7
  199. data/app/serializers/unsakini/post_serializer.rb +0 -26
  200. data/app/serializers/unsakini/user_board_serializer.rb +0 -14
  201. data/app/views/unsakini/user_mailer/confirm_account.html.erb +0 -3
  202. data/db/migrate/20161116114222_create_unsakini_boards.rb +0 -10
  203. data/db/migrate/20161126145352_create_unsakini_users.rb +0 -15
  204. data/lib/generators/unsakini/dependencies/USAGE +0 -5
  205. data/lib/generators/unsakini/dependencies/dependencies_generator.rb +0 -19
  206. data/public/images/unsakini.svg +0 -56
  207. data/public/unsakini/app/448c34a56d699c29117adc64c43affeb.woff2 +0 -0
  208. data/public/unsakini/app/89889688147bd7575d6327160d64e760.svg +0 -288
  209. data/public/unsakini/app/assets/global.scss +0 -3
  210. data/public/unsakini/app/e18bbf611f2a2e43afc071aa2f4e1512.ttf +0 -0
  211. data/public/unsakini/app/f4769f9bdb7466be65088239c12046d1.eot +0 -0
  212. data/public/unsakini/app/fa2772327f55d8198301fdb8bcfc8158.woff +0 -0
  213. data/public/unsakini/app/index.html +0 -14
  214. data/public/unsakini/app/inline.d41d8cd98f00b204e980.bundle.js +0 -2
  215. data/public/unsakini/app/inline.d41d8cd98f00b204e980.bundle.map +0 -1
  216. data/public/unsakini/app/main.54f49c65d3d20650a5d5.bundle.js +0 -2152
  217. data/public/unsakini/app/main.54f49c65d3d20650a5d5.bundle.js.gz +0 -0
  218. data/public/unsakini/app/main.54f49c65d3d20650a5d5.bundle.map +0 -1
  219. data/public/unsakini/app/styles.58e065928ed8ebd0b582.bundle.js +0 -2
  220. data/public/unsakini/app/styles.58e065928ed8ebd0b582.bundle.map +0 -1
  221. data/public/unsakini/app/styles.5dac0e986fce6f8738b300cb558b56a0.bundle.css +0 -8
  222. data/spec/dummy/config/initializers/knock.rb +0 -59
  223. data/spec/schema/jwt.json +0 -9
@@ -1,122 +0,0 @@
1
- module Unsakini
2
-
3
- class ShareBoardController < BaseController
4
-
5
- include LoggedInControllerConcern
6
- include BoardOwnerControllerConcern
7
- include PostOwnerControllerConcern
8
- include CommentOwnerControllerConcern
9
-
10
- before_action :validate_params
11
-
12
- # Shares a board to other users. Example payload param:
13
- #
14
- # `POST /api/share/board`
15
- #
16
- # ```
17
- # {
18
- # board: {
19
- # id: 1,
20
- # name: 'some encrypted text',
21
- # },
22
- # posts: [
23
- # {
24
- # board_id: 1,
25
- # title: 'some encrypted text',
26
- # content: 'some encrypted text',
27
- # comments: [
28
- # {
29
- # id: 1,
30
- # content: 'some encrypted text',
31
- # user_id: 1,
32
- # post_id: 1,
33
- # }
34
- # ]
35
- # }
36
- # ],
37
- # shared_user_ids: [1, 2, 3, 4],
38
- # encrypted_password: 'some encrypted password'
39
- # }
40
- # ```
41
- # The `encrypted_password` param will be used to decrypt contents of this board. The encryption happens in the client so
42
- # the server don't really know what is the original password. The board creator will have to share it privately to other users whom he/she shared it with so they can access the board.
43
- #
44
- # `posts` and `comments` fields can be empty.
45
- def index
46
- ActiveRecord::Base.transaction do
47
- if params[:posts]
48
- params[:posts].each do |post|
49
- p = Post.find(post[:id])
50
- p.title = post[:title]
51
- p.content = post[:content]
52
- p.save!
53
-
54
- if post[:comments] and p.valid?
55
- post[:comments].each do |comment|
56
- c = Comment.find(comment[:id])
57
- c.content = comment[:content]
58
- c.save!
59
- end
60
- end
61
- end
62
- end
63
- if @user_board.share(params[:shared_user_ids], params[:encrypted_password])
64
- render json: {}, status: :ok
65
- else
66
- raise "An error occured"
67
- end
68
- end
69
- rescue
70
- # clean up the created {UserBoard}s
71
- render json: ["Some of the data can't be saved."], status: 422
72
- end
73
-
74
- # Validates the contents of params against the database records.
75
- def validate_params
76
-
77
- if params[:encrypted_password].nil? or params[:shared_user_ids].nil? or params[:board].nil?
78
- render json: {}, status: 422
79
- return
80
- end
81
-
82
- result = has_board_access(params[:board][:id])
83
- if result[:status] != :ok
84
- render json: {}, status: result[:status]
85
- return
86
- else
87
- if !result[:user_board].is_admin
88
- render json: {}, status: :forbidden
89
- return
90
- end
91
- @board = result[:board]
92
- @user_board = result[:user_board]
93
- end
94
-
95
- if params[:posts]
96
-
97
- params[:posts].each do |post|
98
- s = has_post_access(params[:board][:id], post[:id])[:status]
99
- if s != :ok
100
- render json: {}, status: s
101
- return
102
- end
103
-
104
- if post[:comments]
105
- post[:comments].each do |comment|
106
- s = has_comment_access(post[:id], comment[:id])[:status]
107
- if s != :ok
108
- render json: {}, status: s
109
- return
110
- end
111
- end
112
- end
113
-
114
- end
115
-
116
- end
117
-
118
- end
119
-
120
- end
121
-
122
- end
@@ -1,17 +0,0 @@
1
- module Unsakini
2
- class UserTokenController < Knock::AuthTokenController
3
- def create
4
- if entity.confirmed_at?
5
- render json: auth_token, status: :created
6
- else
7
- res = {message: "Your account needs confirmation. Please follow the confirmation instructions sent to #{auth_params[:email]}"}
8
- render status: 401, json: res
9
- end
10
- end
11
-
12
- def entity_name
13
- self.class.name.split('TokenController').first
14
- end
15
-
16
- end
17
- end
@@ -1,69 +0,0 @@
1
- module Unsakini
2
-
3
- class UsersController < BaseController
4
-
5
- include LoggedInControllerConcern
6
- include ::ActionController::Serialization
7
-
8
- skip_before_action :ensure_logged_in, only: [:create, :confirm]
9
-
10
- #Creates a new user
11
- def create
12
- user = User.new(user_params)
13
-
14
- if user.save
15
- UserMailer.confirm_account(user).deliver_now
16
- render json: user, status: :created
17
- else
18
- render json: user.errors, status: 422
19
- end
20
- end
21
-
22
- # confirm user account
23
- def confirm
24
- token = params[:token].to_s
25
-
26
- user = User.find_by(confirmation_token: token)
27
-
28
- if user.present? && user.confirmation_token_valid?
29
- if user.mark_as_confirmed!
30
- render json: {status: 'User confirmed successfully'}, status: :ok
31
- else
32
- render json: user.errors, status: 422
33
- end
34
- else
35
- render json: ['Invalid token'], status: :not_found
36
- end
37
- end
38
-
39
- # Renders the current user as json
40
- #
41
- # `GET /api/user/:id`
42
- #
43
- def show
44
- render json: @user
45
- end
46
-
47
- # Returns the user with matching email
48
- #
49
- # `GET /api/users/search?email=xxx`
50
- #
51
- def search
52
- user = User.where("email = ? AND id != ?", params[:email], @user.id).first
53
- if user
54
- render json: user
55
- else
56
- render json: {}, status: :not_found
57
- end
58
- end
59
-
60
- private
61
-
62
- def user_params
63
- params.permit(:name, :email, :password, :password_confirmation)
64
- end
65
-
66
- end
67
-
68
-
69
- end
@@ -1,27 +0,0 @@
1
- # Base controller for web pages
2
-
3
- module Unsakini
4
- class WebController < ActionController::Base
5
- include ActionController::ImplicitRender
6
- include ActionView::Layouts
7
-
8
- # Renders welcome page
9
- def index
10
- @project = 'Unsakini'
11
- @description = 'Privacy. Confidentiality. Security.'
12
- @version = VERSION
13
- @author = 'Adones Pitogo'
14
- @repository = 'https://github.com/adonespitogo/unsakini'
15
- @title = "#{@project} | #{@description}"
16
- @tagline = "Created by and for online activists, information security enthusiasts and government surveillance evaders."
17
- @keywords = "unsakini, encrypted, bulletin board, BB, ruby, rails"
18
- end
19
-
20
- # Renders the angular index view when request url is /app/* to enable html5 pushState capability of angularjs
21
- def app
22
- gem_root = File.expand_path '../../../..', __FILE__
23
-
24
- render file: "#{gem_root}/public/unsakini/app/index.html", layout: false
25
- end
26
- end
27
- end
@@ -1,13 +0,0 @@
1
- module Unsakini
2
- class UserMailer < ::ActionMailer::Base
3
- default from: 'notifications@example.com'
4
-
5
- def confirm_account(user)
6
- @user = user
7
- @url = "#{root_url}app/account/confirm/#{@user.confirmation_token}"
8
- mail(to: @user.email, subject: 'Unsakini - Account Confirmation')
9
- end
10
-
11
- end
12
-
13
- end
@@ -1,97 +0,0 @@
1
- require 'openssl'
2
- require 'base64'
3
-
4
- # Responsible for encryption and decryption of certain model attributes
5
- module Unsakini
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
97
- end
@@ -1,7 +0,0 @@
1
- # Base application model
2
- require_dependency 'unsakini'
3
- module Unsakini
4
- class ApplicationRecord < ActiveRecord::Base
5
- self.abstract_class = true
6
- end
7
- end
@@ -1,16 +0,0 @@
1
- #Board model
2
- module Unsakini
3
- class Board < ApplicationRecord
4
-
5
- include EncryptableModelConcern
6
- encryptable_attributes :name
7
-
8
- validates :name, presence: true
9
-
10
- has_many :users, through: :user_boards
11
-
12
- has_many :user_boards, :dependent => :delete_all
13
- has_many :posts, :dependent => :destroy
14
-
15
- end
16
- end
@@ -1,12 +0,0 @@
1
- #Comment model
2
- module Unsakini
3
- class Comment < ApplicationRecord
4
- include EncryptableModelConcern
5
-
6
- encryptable_attributes :content
7
- validates :content, presence: true
8
-
9
- belongs_to :post
10
- belongs_to :user
11
- end
12
- end
@@ -1,15 +0,0 @@
1
- #Post model
2
-
3
- module Unsakini
4
- class Post < ApplicationRecord
5
- include EncryptableModelConcern
6
-
7
- encryptable_attributes :title, :content
8
- validates :title, presence: true
9
- validates :content, presence: true
10
-
11
- belongs_to :user
12
- belongs_to :board
13
- has_many :comments, :dependent => :delete_all
14
- end
15
- end
@@ -1,43 +0,0 @@
1
- # module Unsakini
2
- module Unsakini
3
- class User < ApplicationRecord
4
-
5
- has_secure_password
6
-
7
- validates_uniqueness_of :email, case_sensitive: false, on: [:create]
8
- validates_format_of :email, with: /@/
9
- validates :name, :email, presence: true
10
- validates :password, :presence => true,
11
- :confirmation => true,
12
- :length => { :minimum => 6 },
13
- :if => :password # only validate if password changed!
14
-
15
- has_many :user_boards
16
- has_many :boards, through: :user_boards
17
-
18
- before_save :downcase_email
19
- before_create :generate_confirmation_instructions
20
-
21
- def downcase_email
22
- self.email = self.email.delete(' ').downcase
23
- end
24
-
25
- def generate_confirmation_instructions
26
- self.confirmation_token = SecureRandom.hex(10)
27
- self.confirmation_sent_at = Time.now.utc
28
- end
29
-
30
- def confirmation_token_valid?
31
- (self.confirmation_sent_at + 30.days) > Time.now.utc
32
- end
33
-
34
- def mark_as_confirmed!
35
- self.confirmation_token = nil
36
- self.confirmed_at = Time.now.utc
37
- save
38
- end
39
-
40
- end
41
- end
42
-
43
- # end
@@ -1,84 +0,0 @@
1
- # UserBoard model, links the user and it's boards
2
- module Unsakini
3
- class UserBoard < ApplicationRecord
4
- include EncryptableModelConcern
5
-
6
- encryptable_attributes :encrypted_password
7
-
8
- validates :encrypted_password, :presence => true, if: :is_admin
9
-
10
- before_validation :validate_before_create, on: :create
11
- before_validation :validate_before_update, on: :update
12
-
13
- belongs_to :user
14
- belongs_to :board
15
-
16
- scope :admin, -> { where(is_admin: true) }
17
-
18
- def name=(str)
19
- @name = str
20
- end
21
-
22
- def name
23
- if !@name.nil?
24
- @name
25
- else
26
- self.board.name
27
- end
28
- end
29
-
30
- # Returns user_boards where {Board} is `is_shared`
31
- #
32
- # @param is_shared [Boolean] wether to return shared or not shared boards
33
- def self.shared(is_shared)
34
- joins("LEFT JOIN #{Board.table_name} ON #{self.table_name}.board_id = #{Board.table_name}.id")
35
- .where("#{Board.table_name}.is_shared = ?", is_shared)
36
- end
37
-
38
- def share(user_ids, new_key)
39
- ActiveRecord::Base.transaction do
40
- user_ids.each do |usr_id|
41
- UserBoard.new({
42
- user_id: usr_id,
43
- board_id: self.board_id,
44
- encrypted_password: nil,
45
- is_admin: false
46
- })
47
- .save!
48
- end
49
- self.board.is_shared = true
50
- self.encrypted_password = new_key
51
- self.save!
52
- end
53
- true
54
-
55
- rescue
56
- self.errors[:base] << "Unable to share the this board"
57
- false
58
- end
59
-
60
- private
61
-
62
- def reset_user_boards_encrypted_password
63
- UserBoard.where("board_id = ? AND user_id != ?", self.board_id, self.user_id).update_all(encrypted_password: nil)
64
- end
65
-
66
- def validate_before_create
67
- if self.board.nil?
68
- b = Board.new(name: @name)
69
- if b.save
70
- self.board_id = b.id
71
- else
72
- self.errors[:base] << "Board name is invalid"
73
- end
74
- end
75
- end
76
-
77
- def validate_before_update
78
- self.board.name = @name if !@name.blank?
79
- reset_user_boards_encrypted_password if self.encrypted_password_changed?
80
- self.errors[:base] << "Board name is invalid" if !self.board.save
81
- end
82
-
83
- end
84
- end
@@ -1,5 +0,0 @@
1
- module Unsakini
2
- def self.table_name_prefix
3
- 'unsakini_'
4
- end
5
- end
@@ -1,7 +0,0 @@
1
- module Unsakini
2
- class BoardSerializer < ActiveModel::Serializer
3
-
4
- attributes :id, :name, :created_at, :updated_at
5
-
6
- end
7
- end
@@ -1,26 +0,0 @@
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
- module Unsakini
5
- class PostSerializer < ActiveModel::Serializer
6
-
7
- attributes :id, :title, :content, :created_at, :updated_at
8
-
9
- belongs_to :user
10
-
11
- belongs_to :board do |serializer|
12
- user_board = object.board.user_boards.where(user_id: object.user_id).first
13
-
14
- {
15
- "id" => object.board.id,
16
- "name" => object.board.name,
17
- "is_admin" => user_board.is_admin,
18
- "encrypted_password" => user_board.encrypted_password,
19
- "created_at" => object.board.created_at,
20
- "updated_at" => object.board.updated_at
21
- }
22
- end
23
-
24
- end
25
-
26
- end
@@ -1,14 +0,0 @@
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
- module Unsakini
6
- class UserBoardSerializer < ActiveModel::Serializer
7
-
8
- attributes :id, :is_admin, :encrypted_password, :created_at, :updated_at
9
-
10
- belongs_to :board
11
-
12
- end
13
-
14
- end
@@ -1,3 +0,0 @@
1
- <h1>Confirm Your Account</h1>
2
- Click the link below: <br>
3
- <a href="<%= @url %>"><%= @url %></a>
@@ -1,10 +0,0 @@
1
- class CreateUnsakiniBoards < ActiveRecord::Migration[5.0]
2
- def change
3
- create_table :unsakini_boards do |t|
4
- t.text :name
5
- t.boolean :is_shared, default: false
6
-
7
- t.timestamps
8
- end
9
- end
10
- end
@@ -1,15 +0,0 @@
1
- class CreateUnsakiniUsers < ActiveRecord::Migration[5.0]
2
- def change
3
- create_table :unsakini_users do |t|
4
- t.string :name, null: false
5
- t.string :email, null: false
6
- t.string :password_digest, null: false
7
- t.string :confirmation_token
8
- t.datetime :confirmed_at
9
- t.datetime :confirmation_sent_at
10
-
11
- t.timestamps
12
- end
13
-
14
- end
15
- end
@@ -1,5 +0,0 @@
1
- Description:
2
- Add the needed dependencies to Gemfile. Review your Gemfile after running this command and before you do bundle install.
3
-
4
- Example:
5
- rails generate dependencies
@@ -1,19 +0,0 @@
1
- class Unsakini::DependenciesGenerator < Rails::Generators::Base
2
- source_root File.expand_path('../templates', __FILE__)
3
-
4
- def add_dependencies_to_host
5
-
6
- gem 'active_model_serializers'
7
- gem 'rack-cors'
8
- gem 'kaminari'
9
- gem 'api-pagination'
10
- gem 'knock', git: 'https://github.com/adonespitogo/knock'
11
-
12
- gem_group :development, :test do
13
- gem "rb-readline"
14
- gem "byebug"
15
- gem 'letter_opener'
16
- end
17
-
18
- end
19
- end